@parall/daemon 1.36.0 → 1.37.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 +11 -11
- package/bundle/parall-browser-pod.js +384 -32
- package/bundle/parall-claude-agent.js +426 -51
- package/bundle/parall-codex-agent.js +425 -49
- package/bundle/parall-daemon.js +33336 -31520
- package/dist/browser-pod.d.ts +7 -0
- package/dist/browser-pod.d.ts.map +1 -1
- package/dist/browser-pod.js +73 -3
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +2 -2
- package/dist/clip-runtime/browser-daemon-env.d.ts +29 -0
- package/dist/clip-runtime/browser-daemon-env.d.ts.map +1 -0
- package/dist/clip-runtime/browser-daemon-env.js +70 -0
- package/dist/clip-runtime/browser-profile-manager.d.ts +34 -5
- package/dist/clip-runtime/browser-profile-manager.d.ts.map +1 -1
- package/dist/clip-runtime/browser-profile-manager.js +166 -24
- package/dist/clip-runtime/browser-profile-pool.d.ts +250 -0
- package/dist/clip-runtime/browser-profile-pool.d.ts.map +1 -0
- package/dist/clip-runtime/browser-profile-pool.js +581 -0
- package/dist/clip-runtime/index.d.ts +2 -1
- package/dist/clip-runtime/index.d.ts.map +1 -1
- package/dist/clip-runtime/index.js +2 -1
- package/dist/clip-runtime/process-manager.d.ts +5 -3
- package/dist/clip-runtime/process-manager.d.ts.map +1 -1
- package/dist/clip-runtime/subprocess.d.ts +14 -0
- package/dist/clip-runtime/subprocess.d.ts.map +1 -1
- package/dist/clip-runtime/subprocess.js +49 -0
- package/dist/config.d.ts +14 -15
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +8 -26
- package/dist/daemon-main.d.ts +8 -0
- package/dist/daemon-main.d.ts.map +1 -0
- package/dist/daemon-main.js +165 -0
- package/dist/daemon-paths.d.ts +14 -0
- package/dist/daemon-paths.d.ts.map +1 -0
- package/dist/daemon-paths.js +26 -0
- package/dist/daemon-update-mode.d.ts +8 -0
- package/dist/daemon-update-mode.d.ts.map +1 -0
- package/dist/daemon-update-mode.js +18 -0
- package/dist/index.js +41 -167
- package/dist/runtime-bin-resolver.d.ts +4 -0
- package/dist/runtime-bin-resolver.d.ts.map +1 -1
- package/dist/runtime-bin-resolver.js +40 -7
- package/dist/runtime-detector.d.ts +30 -0
- package/dist/runtime-detector.d.ts.map +1 -0
- package/dist/runtime-detector.js +100 -0
- package/dist/supervisor.d.ts +64 -2
- package/dist/supervisor.d.ts.map +1 -1
- package/dist/supervisor.js +629 -67
- package/dist/update-health-gate.d.ts +66 -0
- package/dist/update-health-gate.d.ts.map +1 -0
- package/dist/update-health-gate.js +93 -0
- package/dist/updater-manifest.d.ts +2 -1
- package/dist/updater-manifest.d.ts.map +1 -1
- package/dist/updater-manifest.js +38 -7
- package/dist/updater.d.ts +13 -2
- package/dist/updater.d.ts.map +1 -1
- package/dist/updater.js +126 -17
- package/package.json +6 -6
package/dist/browser-pod.d.ts
CHANGED
|
@@ -46,6 +46,7 @@
|
|
|
46
46
|
*/
|
|
47
47
|
import * as http from 'node:http';
|
|
48
48
|
import { type GatewayLogger } from '@parall/agent-core';
|
|
49
|
+
import { type BrowserProxyConfig } from './clip-runtime/browser-profile-manager.js';
|
|
49
50
|
import { BrowserStateStore, type HydrateResult } from './clip-runtime/browser-state-store.js';
|
|
50
51
|
export interface BrowserPodConfig {
|
|
51
52
|
/** Controller-minted pba_ platform assignment token (ProviderStream bearer). */
|
|
@@ -64,6 +65,9 @@ export interface BrowserPodConfig {
|
|
|
64
65
|
stateDir: string;
|
|
65
66
|
/** bb-browser user-data dir (BB_BROWSER_HOME); where S3 state hydrates in a later PR. */
|
|
66
67
|
homeDir: string;
|
|
68
|
+
/** Per-profile outbound proxy (controller-injected via PRLL_BROWSER_PROXY_* env on a
|
|
69
|
+
* cold pod, or the /assign body on a warm one). null = direct egress. */
|
|
70
|
+
proxy: BrowserProxyConfig | null;
|
|
67
71
|
}
|
|
68
72
|
/**
|
|
69
73
|
* Resolve and validate the pod's runtime config from the environment. Throws on
|
|
@@ -109,6 +113,9 @@ export interface AssignRequest {
|
|
|
109
113
|
leaseId: string;
|
|
110
114
|
generation: number;
|
|
111
115
|
state?: AssignStateCreds;
|
|
116
|
+
/** Per-profile outbound proxy (warm-pod counterpart of the cold pod's
|
|
117
|
+
* PRLL_BROWSER_PROXY_* env). Absent = direct egress. */
|
|
118
|
+
proxy?: BrowserProxyConfig;
|
|
112
119
|
}
|
|
113
120
|
type AssignParseResult = {
|
|
114
121
|
ok: true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser-pod.d.ts","sourceRoot":"","sources":["../src/browser-pod.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AAIH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAIlC,OAAO,EAAgB,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"browser-pod.d.ts","sourceRoot":"","sources":["../src/browser-pod.ts"],"names":[],"mappings":"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"}
|
package/dist/browser-pod.js
CHANGED
|
@@ -51,7 +51,7 @@ import * as os from 'node:os';
|
|
|
51
51
|
import * as path from 'node:path';
|
|
52
52
|
import { pathToFileURL } from 'node:url';
|
|
53
53
|
import { createLogger } from '@parall/agent-core';
|
|
54
|
-
import { BrowserProfileManager } from './clip-runtime/browser-profile-manager.js';
|
|
54
|
+
import { BrowserProfileManager, } from './clip-runtime/browser-profile-manager.js';
|
|
55
55
|
import { BrowserStateStore } from './clip-runtime/browser-state-store.js';
|
|
56
56
|
import { ClipProvider } from './clip-runtime/clip-provider.js';
|
|
57
57
|
import { ClipProcessManager } from './clip-runtime/process-manager.js';
|
|
@@ -114,8 +114,37 @@ export function resolveBrowserPodConfig(env = process.env) {
|
|
|
114
114
|
healthPort: parsePort(env.PRLL_HEALTH_PORT, DEFAULT_HEALTH_PORT),
|
|
115
115
|
stateDir,
|
|
116
116
|
homeDir,
|
|
117
|
+
proxy: parseProxyEnv(env),
|
|
117
118
|
};
|
|
118
119
|
}
|
|
120
|
+
/** Parse the controller-injected PRLL_BROWSER_PROXY_* env into a proxy config, or
|
|
121
|
+
* null when no proxy is set (PRLL_BROWSER_PROXY_SERVER absent → direct egress).
|
|
122
|
+
* The cold pod gets these as env; the warm pod's /assign writes the same vars. */
|
|
123
|
+
function parseProxyEnv(env) {
|
|
124
|
+
const server = env.PRLL_BROWSER_PROXY_SERVER?.trim();
|
|
125
|
+
// username + password are credential-like passthrough — kept VERBATIM (never
|
|
126
|
+
// trimmed), because residential-proxy usernames carry session/geo selectors and
|
|
127
|
+
// a provider could legitimately use surrounding whitespace. Empty string → undefined.
|
|
128
|
+
const username = env.PRLL_BROWSER_PROXY_USERNAME || undefined;
|
|
129
|
+
const password = env.PRLL_BROWSER_PROXY_PASSWORD || undefined;
|
|
130
|
+
if (!server) {
|
|
131
|
+
// Orphan credentials with no server must FAIL CLOSED, not silently fall through
|
|
132
|
+
// to direct egress: a misconfigured pod spec that drops the server var while
|
|
133
|
+
// keeping creds should crash here, not leak traffic past the intended proxy.
|
|
134
|
+
if (username !== undefined || password !== undefined) {
|
|
135
|
+
throw new Error('browser-pod: PRLL_BROWSER_PROXY_USERNAME/PASSWORD set without PRLL_BROWSER_PROXY_SERVER');
|
|
136
|
+
}
|
|
137
|
+
return null; // no proxy at all → direct egress
|
|
138
|
+
}
|
|
139
|
+
// Reject half-auth at the pod boundary too (the server already enforces the
|
|
140
|
+
// user+pass pair). A version skew / bad pod spec should fail fast here, not
|
|
141
|
+
// forward incomplete creds to account_create where it becomes a confusing
|
|
142
|
+
// runtime auth failure.
|
|
143
|
+
if ((username === undefined) !== (password === undefined)) {
|
|
144
|
+
throw new Error('browser-pod: PRLL_BROWSER_PROXY_USERNAME and PRLL_BROWSER_PROXY_PASSWORD must be set together');
|
|
145
|
+
}
|
|
146
|
+
return { server, username, password };
|
|
147
|
+
}
|
|
119
148
|
/**
|
|
120
149
|
* Resolve a warm pod's identity-less config. Unlike resolveBrowserPodConfig this
|
|
121
150
|
* requires PRLL_POOL_TOKEN (not PRLL_ASSIGNMENT_TOKEN) and NO profile/org — those
|
|
@@ -196,7 +225,29 @@ export function parseAssignRequest(body) {
|
|
|
196
225
|
sessionToken,
|
|
197
226
|
};
|
|
198
227
|
}
|
|
199
|
-
|
|
228
|
+
let proxy;
|
|
229
|
+
if (b.proxy !== undefined && b.proxy !== null) {
|
|
230
|
+
if (typeof b.proxy !== 'object')
|
|
231
|
+
return { ok: false, error: 'proxy must be an object' };
|
|
232
|
+
const p = b.proxy;
|
|
233
|
+
const server = str(p.server);
|
|
234
|
+
if (!server)
|
|
235
|
+
return { ok: false, error: 'proxy requires server' };
|
|
236
|
+
// username + password are credentials — preserved VERBATIM (never trimmed);
|
|
237
|
+
// empty string → undefined. (server is a structured host:port, so it is trimmed.)
|
|
238
|
+
const username = (typeof p.username === 'string' ? p.username : '') || undefined;
|
|
239
|
+
const password = (typeof p.password === 'string' ? p.password : '') || undefined;
|
|
240
|
+
// Reject half-auth (same invariant the server enforces) before it reaches
|
|
241
|
+
// account_create as a confusing runtime auth failure.
|
|
242
|
+
if ((username === undefined) !== (password === undefined)) {
|
|
243
|
+
return { ok: false, error: 'proxy username and password must be provided together' };
|
|
244
|
+
}
|
|
245
|
+
proxy = { server, username, password };
|
|
246
|
+
}
|
|
247
|
+
return {
|
|
248
|
+
ok: true,
|
|
249
|
+
value: { assignmentToken, profileId, orgId, leaseId, generation, state, proxy },
|
|
250
|
+
};
|
|
200
251
|
}
|
|
201
252
|
/**
|
|
202
253
|
* Apply an /assign payload to `env` (process.env in prod) so the assigned path
|
|
@@ -220,6 +271,19 @@ export function applyAssignmentEnv(env, req) {
|
|
|
220
271
|
if (req.state.endpoint)
|
|
221
272
|
env.PRLL_BROWSER_STATE_ENDPOINT = req.state.endpoint;
|
|
222
273
|
}
|
|
274
|
+
// Clear any prior proxy env BEFORE applying this assignment's proxy, so a pod
|
|
275
|
+
// env reused across assignments never inherits a stale credential (a no-proxy
|
|
276
|
+
// or different-proxy reassignment must not keep the previous profile's creds).
|
|
277
|
+
delete env.PRLL_BROWSER_PROXY_SERVER;
|
|
278
|
+
delete env.PRLL_BROWSER_PROXY_USERNAME;
|
|
279
|
+
delete env.PRLL_BROWSER_PROXY_PASSWORD;
|
|
280
|
+
if (req.proxy) {
|
|
281
|
+
env.PRLL_BROWSER_PROXY_SERVER = req.proxy.server;
|
|
282
|
+
if (req.proxy.username)
|
|
283
|
+
env.PRLL_BROWSER_PROXY_USERNAME = req.proxy.username;
|
|
284
|
+
if (req.proxy.password)
|
|
285
|
+
env.PRLL_BROWSER_PROXY_PASSWORD = req.proxy.password;
|
|
286
|
+
}
|
|
223
287
|
}
|
|
224
288
|
/** Constant-time bearer comparison against the injected pool token. The pod cannot
|
|
225
289
|
* verify the JWT signature (no shared secret), so it string-compares the bearer to
|
|
@@ -562,7 +626,13 @@ function makeCheckpointer(store) {
|
|
|
562
626
|
export async function preparePodRuntime(config, env, log) {
|
|
563
627
|
// Real browser runtime — starts bb-browser + Chromium lazily on first invoke,
|
|
564
628
|
// ensures the single profile's account, persists under homeDir (BB_BROWSER_HOME).
|
|
565
|
-
|
|
629
|
+
// A hosted pod serves exactly one profile, so resolveProxy ignores the id and
|
|
630
|
+
// returns the controller-injected proxy (env on a cold pod, /assign on a warm one).
|
|
631
|
+
const browser = new BrowserProfileManager({
|
|
632
|
+
homeDir: config.homeDir,
|
|
633
|
+
log,
|
|
634
|
+
resolveProxy: () => config.proxy,
|
|
635
|
+
});
|
|
566
636
|
// The process manager hosts no installable clips in pod mode — its only job is
|
|
567
637
|
// to advertise the synthetic "browser" capability (getProviderClips appends it
|
|
568
638
|
// because a BrowserProfileManager is present) and route inbound browser invokes
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAkTA,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAuD9E"}
|
package/dist/cli.js
CHANGED
|
@@ -219,11 +219,11 @@ function cmdServiceUninstall() {
|
|
|
219
219
|
}
|
|
220
220
|
}
|
|
221
221
|
async function cmdUpdate(checkOnly) {
|
|
222
|
-
const { resolveClaudeDaemonConfig, resolveBundleDir } = await import('./config.js');
|
|
222
|
+
const { resolveClaudeDaemonConfig, resolveBundleDir, resolveUpdateSigningEnabled } = await import('./config.js');
|
|
223
223
|
const { DaemonUpdater } = await import('./updater.js');
|
|
224
224
|
const config = resolveClaudeDaemonConfig(process.env);
|
|
225
225
|
const bundleDir = resolveBundleDir(process.env);
|
|
226
|
-
const signingEnabled = process.env
|
|
226
|
+
const signingEnabled = resolveUpdateSigningEnabled(process.env);
|
|
227
227
|
const updater = new DaemonUpdater(bundleDir, config.updateCdnUrl, {
|
|
228
228
|
info: (msg) => console.log(msg),
|
|
229
229
|
warn: (msg) => console.warn(msg),
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build the env for a spawned bb-browser daemon: inherit the parent env (so the
|
|
3
|
+
* Chromium it launches keeps PATH / HOME / DISPLAY / XDG / locale / proxy — the
|
|
4
|
+
* hosted browser-docker pod runs Chrome under Xvfb and depends on these), set
|
|
5
|
+
* BB_BROWSER_HOME, and strip the **platform credentials the daemon/pod carries**
|
|
6
|
+
* before they reach the child — bb-browser uses none of them and the Chromium it
|
|
7
|
+
* launches runs untrusted web content, so credentials must never land in its env:
|
|
8
|
+
* - LLM/provider creds (`ANTHROPIC_*` / `OPENAI_*` / `PRLL_CLAUDE_ALLOW_API_KEY`,
|
|
9
|
+
* via the maintained `clearAllProviderCreds` SSOT);
|
|
10
|
+
* - the machine key (`PRLL_API_KEY=mck_`, BYOC control plane);
|
|
11
|
+
* - hosted-pod creds injected by the browser-profile-controller (browser-pod.ts):
|
|
12
|
+
* the platform assignment / pool tokens (`PRLL_ASSIGNMENT_TOKEN`,
|
|
13
|
+
* `PRLL_POOL_TOKEN`, `pba_`) and the S3 browser-state STS creds (`AWS_*`).
|
|
14
|
+
* It also drops the hosted browser-state config the controller injects alongside
|
|
15
|
+
* those creds (`AWS_REGION`, `PRLL_BROWSER_STATE_BUCKET`, `PRLL_STATE_GENERATION`,
|
|
16
|
+
* `PRLL_BROWSER_STATE_ENDPOINT`): bb-browser never reads it, so dropping it shrinks
|
|
17
|
+
* the env surface handed to a process running untrusted content. (Unrelated BYOC
|
|
18
|
+
* host env is out of scope.)
|
|
19
|
+
*
|
|
20
|
+
* ts/daemon/AGENTS.md requires the credential env to be overridden before spawning
|
|
21
|
+
* a child, and with one bb-browser per profile the exposure would otherwise be
|
|
22
|
+
* multiplied N×. Denylist rather than allowlist: the SAME spawn feeds the Xvfb
|
|
23
|
+
* Chromium in the hosted pod, whose full env surface can't be exercised locally, so
|
|
24
|
+
* a too-narrow allowlist would silently break it — a denylist cannot. The hosted
|
|
25
|
+
* keys below are a safe no-op on a BYOC host (its env never carries them). Exported
|
|
26
|
+
* for unit testing.
|
|
27
|
+
*/
|
|
28
|
+
export declare function buildBrowserDaemonEnv(baseEnv: NodeJS.ProcessEnv, homeDir: string): NodeJS.ProcessEnv;
|
|
29
|
+
//# sourceMappingURL=browser-daemon-env.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-daemon-env.d.ts","sourceRoot":"","sources":["../../src/clip-runtime/browser-daemon-env.ts"],"names":[],"mappings":"AAsCA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,MAAM,CAAC,UAAU,EAC1B,OAAO,EAAE,MAAM,GACd,MAAM,CAAC,UAAU,CAOnB"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { clearAllProviderCreds } from '@parall/agent-core';
|
|
2
|
+
// Env sanitization for the spawned bb-browser daemon child (and the Chromium it
|
|
3
|
+
// launches, which runs untrusted web content). Split out of browser-profile-manager
|
|
4
|
+
// to keep that file under the size threshold; this is a distinct concern (env
|
|
5
|
+
// scrubbing) from the daemon/account/tab lifecycle.
|
|
6
|
+
/** Env vars stripped from the bb-browser child — the platform credentials it must
|
|
7
|
+
* never carry, plus hosted browser-state config it doesn't use (in addition to the
|
|
8
|
+
* provider creds scrubbed by clearAllProviderCreds). See buildBrowserDaemonEnv. */
|
|
9
|
+
const BROWSER_DAEMON_STRIPPED_ENV = [
|
|
10
|
+
'PRLL_API_KEY', // machine key (mck_) — BYOC + agent control plane
|
|
11
|
+
'PRLL_PROVIDER_CONFIG', // JSON ProviderConfig blob — may carry BYO LLM api keys
|
|
12
|
+
'PRLL_ASSIGNMENT_TOKEN', // hosted pod platform assignment token (pba_)
|
|
13
|
+
'PRLL_POOL_TOKEN', // hosted warm-pool bootstrap token (pba_)
|
|
14
|
+
'AWS_ACCESS_KEY_ID', // hosted S3 browser-state STS creds (browser-pod.ts)
|
|
15
|
+
'AWS_SECRET_ACCESS_KEY',
|
|
16
|
+
'AWS_SESSION_TOKEN',
|
|
17
|
+
// AWS credential-RESOLUTION vars: the SDK derives creds from these too (IRSA
|
|
18
|
+
// web-identity, ECS/EKS container creds, named profile, on-disk cred/config
|
|
19
|
+
// files), so a child inheriting them could assume the pod's role even without
|
|
20
|
+
// the static keys above. bb-browser uses none of them.
|
|
21
|
+
'AWS_WEB_IDENTITY_TOKEN_FILE',
|
|
22
|
+
'AWS_ROLE_ARN',
|
|
23
|
+
'AWS_ROLE_SESSION_NAME',
|
|
24
|
+
'AWS_CONTAINER_CREDENTIALS_RELATIVE_URI',
|
|
25
|
+
'AWS_CONTAINER_CREDENTIALS_FULL_URI',
|
|
26
|
+
'AWS_CONTAINER_AUTHORIZATION_TOKEN',
|
|
27
|
+
'AWS_PROFILE',
|
|
28
|
+
'AWS_SHARED_CREDENTIALS_FILE',
|
|
29
|
+
'AWS_CONFIG_FILE',
|
|
30
|
+
'AWS_REGION', // hosted browser-state config — bb-browser does not use it
|
|
31
|
+
'PRLL_BROWSER_STATE_REGION', // browser-pod AWS_REGION fallback — same config family
|
|
32
|
+
'PRLL_BROWSER_STATE_BUCKET',
|
|
33
|
+
'PRLL_STATE_GENERATION',
|
|
34
|
+
'PRLL_BROWSER_STATE_ENDPOINT',
|
|
35
|
+
];
|
|
36
|
+
/**
|
|
37
|
+
* Build the env for a spawned bb-browser daemon: inherit the parent env (so the
|
|
38
|
+
* Chromium it launches keeps PATH / HOME / DISPLAY / XDG / locale / proxy — the
|
|
39
|
+
* hosted browser-docker pod runs Chrome under Xvfb and depends on these), set
|
|
40
|
+
* BB_BROWSER_HOME, and strip the **platform credentials the daemon/pod carries**
|
|
41
|
+
* before they reach the child — bb-browser uses none of them and the Chromium it
|
|
42
|
+
* launches runs untrusted web content, so credentials must never land in its env:
|
|
43
|
+
* - LLM/provider creds (`ANTHROPIC_*` / `OPENAI_*` / `PRLL_CLAUDE_ALLOW_API_KEY`,
|
|
44
|
+
* via the maintained `clearAllProviderCreds` SSOT);
|
|
45
|
+
* - the machine key (`PRLL_API_KEY=mck_`, BYOC control plane);
|
|
46
|
+
* - hosted-pod creds injected by the browser-profile-controller (browser-pod.ts):
|
|
47
|
+
* the platform assignment / pool tokens (`PRLL_ASSIGNMENT_TOKEN`,
|
|
48
|
+
* `PRLL_POOL_TOKEN`, `pba_`) and the S3 browser-state STS creds (`AWS_*`).
|
|
49
|
+
* It also drops the hosted browser-state config the controller injects alongside
|
|
50
|
+
* those creds (`AWS_REGION`, `PRLL_BROWSER_STATE_BUCKET`, `PRLL_STATE_GENERATION`,
|
|
51
|
+
* `PRLL_BROWSER_STATE_ENDPOINT`): bb-browser never reads it, so dropping it shrinks
|
|
52
|
+
* the env surface handed to a process running untrusted content. (Unrelated BYOC
|
|
53
|
+
* host env is out of scope.)
|
|
54
|
+
*
|
|
55
|
+
* ts/daemon/AGENTS.md requires the credential env to be overridden before spawning
|
|
56
|
+
* a child, and with one bb-browser per profile the exposure would otherwise be
|
|
57
|
+
* multiplied N×. Denylist rather than allowlist: the SAME spawn feeds the Xvfb
|
|
58
|
+
* Chromium in the hosted pod, whose full env surface can't be exercised locally, so
|
|
59
|
+
* a too-narrow allowlist would silently break it — a denylist cannot. The hosted
|
|
60
|
+
* keys below are a safe no-op on a BYOC host (its env never carries them). Exported
|
|
61
|
+
* for unit testing.
|
|
62
|
+
*/
|
|
63
|
+
export function buildBrowserDaemonEnv(baseEnv, homeDir) {
|
|
64
|
+
const env = { ...baseEnv, BB_BROWSER_HOME: homeDir };
|
|
65
|
+
clearAllProviderCreds(env); // strips ANTHROPIC_* / OPENAI_* / PRLL_CLAUDE_ALLOW_API_KEY
|
|
66
|
+
for (const key of BROWSER_DAEMON_STRIPPED_ENV) {
|
|
67
|
+
delete env[key];
|
|
68
|
+
}
|
|
69
|
+
return env;
|
|
70
|
+
}
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import { type ViewerTurnConfig } from './browser-viewer-streamer.js';
|
|
2
|
-
type BrowserProfileStatus = 'running' | 'stopped' | 'error';
|
|
3
|
-
|
|
2
|
+
export type BrowserProfileStatus = 'running' | 'stopped' | 'error';
|
|
3
|
+
/** Per-profile outbound proxy (BYO provider credentials) bound at bb-browser
|
|
4
|
+
* account_create. server is host:port (optional http/https/socks5 scheme);
|
|
5
|
+
* username/password authenticate (CDP Fetch.authRequired). Geo/session targeting
|
|
6
|
+
* lives inside the username (provider-specific). null/absent = direct egress. */
|
|
7
|
+
export interface BrowserProxyConfig {
|
|
8
|
+
server: string;
|
|
9
|
+
username?: string;
|
|
10
|
+
password?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface BrowserProfileManagerOptions {
|
|
4
13
|
homeDir: string;
|
|
5
14
|
log: {
|
|
6
15
|
info(msg: string): void;
|
|
@@ -8,25 +17,45 @@ interface BrowserProfileManagerOptions {
|
|
|
8
17
|
error(msg: string): void;
|
|
9
18
|
};
|
|
10
19
|
reportStatus?: (profileId: string, status: BrowserProfileStatus, errorMsg?: string) => void;
|
|
20
|
+
/** Resolve the profile's outbound proxy, called once per bb-browser account
|
|
21
|
+
* creation (the single choke point — invoke / open / ensureRuntime all funnel
|
|
22
|
+
* through ensureAccount). A proxy change therefore takes effect on the next
|
|
23
|
+
* account_create (after a reset). Returning null = direct egress. A thrown
|
|
24
|
+
* error fails the account creation closed (better than egressing from the real
|
|
25
|
+
* IP for a proxy-configured profile). */
|
|
26
|
+
resolveProxy?: (profileId: string) => Promise<BrowserProxyConfig | null> | BrowserProxyConfig | null;
|
|
11
27
|
}
|
|
12
|
-
interface BrowserInvokeRequest {
|
|
28
|
+
export interface BrowserInvokeRequest {
|
|
13
29
|
profileId: string;
|
|
14
30
|
account: string;
|
|
15
31
|
command: string;
|
|
16
32
|
input: unknown;
|
|
17
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* The host-side browser invoke surface ClipProcessManager depends on. Both
|
|
36
|
+
* BrowserProfileManager (one bb-browser, multi-account — used by the hosted
|
|
37
|
+
* browser pod) and BrowserProfilePool (one bb-browser per profile — used by the
|
|
38
|
+
* BYOC daemon supervisor for true per-profile isolation) satisfy it, so the
|
|
39
|
+
* synthetic "browser" capability routes through either without caring which.
|
|
40
|
+
*/
|
|
41
|
+
export interface BrowserInvoker {
|
|
42
|
+
invoke(request: BrowserInvokeRequest): Promise<unknown>;
|
|
43
|
+
}
|
|
18
44
|
export declare class BrowserProfileManager {
|
|
19
45
|
private readonly opts;
|
|
20
46
|
private daemon;
|
|
21
47
|
private starting;
|
|
22
48
|
private restarting;
|
|
49
|
+
private stopping;
|
|
23
50
|
private readonly ensuredAccounts;
|
|
24
51
|
private readonly ensuringAccounts;
|
|
25
52
|
private readonly reportedStatuses;
|
|
26
53
|
private readonly viewer;
|
|
27
54
|
constructor(opts: BrowserProfileManagerOptions);
|
|
28
55
|
invoke({ profileId, account, command, input }: BrowserInvokeRequest): Promise<unknown>;
|
|
29
|
-
ensureRuntime(profileId: string
|
|
56
|
+
ensureRuntime(profileId: string, opts?: {
|
|
57
|
+
forceStatusReport?: boolean;
|
|
58
|
+
}): Promise<void>;
|
|
30
59
|
openProfile(profileId: string, startUrl?: string): Promise<void>;
|
|
31
60
|
stopProfile(profileId: string): Promise<void>;
|
|
32
61
|
resetProfile(profileId: string): Promise<void>;
|
|
@@ -74,7 +103,7 @@ export declare class BrowserProfileManager {
|
|
|
74
103
|
private restartDaemon;
|
|
75
104
|
private restartDaemonOnce;
|
|
76
105
|
private startDaemon;
|
|
106
|
+
private startDaemonAttempt;
|
|
77
107
|
private post;
|
|
78
108
|
}
|
|
79
|
-
export {};
|
|
80
109
|
//# sourceMappingURL=browser-profile-manager.d.ts.map
|
|
@@ -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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"}
|