@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
|
@@ -8055,8 +8055,8 @@ var init_requestBuilder = __esm({
|
|
|
8055
8055
|
async build() {
|
|
8056
8056
|
const { hostname, protocol = "https", port, path: basePath } = await this.context.endpoint();
|
|
8057
8057
|
this.path = basePath;
|
|
8058
|
-
for (const
|
|
8059
|
-
|
|
8058
|
+
for (const resolvePath2 of this.resolvePathStack) {
|
|
8059
|
+
resolvePath2(this.path);
|
|
8060
8060
|
}
|
|
8061
8061
|
return new import_protocol_http5.HttpRequest({
|
|
8062
8062
|
protocol,
|
|
@@ -35113,6 +35113,7 @@ var ENDPOINTS = {
|
|
|
35113
35113
|
// Org-scoped
|
|
35114
35114
|
ORG: (orgId) => `${API_BASE}/orgs/${orgId}`,
|
|
35115
35115
|
ORG_MEMBERS: (orgId) => `${API_BASE}/orgs/${orgId}/members`,
|
|
35116
|
+
ORG_MEMBERS_FORMER: (orgId) => `${API_BASE}/orgs/${orgId}/members/former`,
|
|
35116
35117
|
TEAMS: (orgId) => `${API_BASE}/orgs/${orgId}/teams`,
|
|
35117
35118
|
ORG_MEMBERS_ONLINE: (orgId) => `${API_BASE}/orgs/${orgId}/members/online`,
|
|
35118
35119
|
ORG_MEMBER: (orgId, userId) => `${API_BASE}/orgs/${orgId}/members/${userId}`,
|
|
@@ -35262,6 +35263,19 @@ var ENDPOINTS = {
|
|
|
35262
35263
|
EXTERNAL_TRIGGER: (orgId, triggerId) => `${API_BASE}/orgs/${orgId}/external-triggers/${triggerId}`,
|
|
35263
35264
|
EXTERNAL_TRIGGER_RUNS: (orgId) => `${API_BASE}/orgs/${orgId}/external-trigger-runs`,
|
|
35264
35265
|
EXTERNAL_TRIGGER_RUN: (orgId, runId) => `${API_BASE}/orgs/${orgId}/external-trigger-runs/${runId}`,
|
|
35266
|
+
// External IM channel (org-scoped, platform-mediated Feishu/Slack)
|
|
35267
|
+
CHANNEL_CONNECTIONS: (orgId) => `${API_BASE}/orgs/${orgId}/channel-connections`,
|
|
35268
|
+
CHANNEL_CONNECTION: (orgId, connectionId) => `${API_BASE}/orgs/${orgId}/channel-connections/${connectionId}`,
|
|
35269
|
+
CHANNEL_CONNECTION_CREDENTIALS: (orgId, connectionId) => `${API_BASE}/orgs/${orgId}/channel-connections/${connectionId}/credentials`,
|
|
35270
|
+
CHANNEL_CONNECTION_INGRESS_TOKEN_REGENERATE: (orgId, connectionId) => `${API_BASE}/orgs/${orgId}/channel-connections/${connectionId}/ingress-token/regenerate`,
|
|
35271
|
+
CHANNEL_CONNECTION_CONVERSATIONS: (orgId, connectionId) => `${API_BASE}/orgs/${orgId}/channel-connections/${connectionId}/conversations`,
|
|
35272
|
+
CHANNEL_CONVERSATION: (orgId, conversationId) => `${API_BASE}/orgs/${orgId}/channel-conversations/${conversationId}`,
|
|
35273
|
+
CHANNEL_CONVERSATION_MESSAGES: (orgId, conversationId) => `${API_BASE}/orgs/${orgId}/channel-conversations/${conversationId}/messages`,
|
|
35274
|
+
CHANNEL_CONVERSATION_SESSION: (orgId, conversationId) => `${API_BASE}/orgs/${orgId}/channel-conversations/${conversationId}/session`,
|
|
35275
|
+
CHANNEL_MESSAGE: (orgId, messageId) => `${API_BASE}/orgs/${orgId}/channel-messages/${messageId}`,
|
|
35276
|
+
CHANNEL_PROVISIONING: (orgId) => `${API_BASE}/orgs/${orgId}/channel-provisioning`,
|
|
35277
|
+
CHANNEL_PROVISIONING_SESSION: (orgId, sessionId) => `${API_BASE}/orgs/${orgId}/channel-provisioning/${sessionId}`,
|
|
35278
|
+
CHANNEL_PROVISIONING_CANCEL: (orgId, sessionId) => `${API_BASE}/orgs/${orgId}/channel-provisioning/${sessionId}/cancel`,
|
|
35265
35279
|
// Invitations (org-scoped, admin)
|
|
35266
35280
|
ORG_INVITATIONS: (orgId) => `${API_BASE}/orgs/${orgId}/invitations`,
|
|
35267
35281
|
ORG_INVITATION: (orgId, invId) => `${API_BASE}/orgs/${orgId}/invitations/${invId}`,
|
|
@@ -35279,9 +35293,16 @@ var ENDPOINTS = {
|
|
|
35279
35293
|
INVITE_LINK_JOIN: `${API_BASE}/invite-link/join`,
|
|
35280
35294
|
// Wikis (org-scoped, served by wiki-service)
|
|
35281
35295
|
WIKIS: (orgId) => `${WIKI_BASE}/orgs/${orgId}/wikis`,
|
|
35296
|
+
// Recycle bin — soft-deleted wikis (owner only). Must precede WIKI in the
|
|
35297
|
+
// backend router so `deleted` isn't captured as a {wikiId}; the SDK builder
|
|
35298
|
+
// is just a string.
|
|
35299
|
+
WIKIS_DELETED: (orgId) => `${WIKI_BASE}/orgs/${orgId}/wikis/deleted`,
|
|
35300
|
+
// Detail URL — also reused for DELETE (soft-delete) and `${WIKI}/restore`.
|
|
35282
35301
|
WIKI: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}`,
|
|
35302
|
+
WIKI_RESTORE: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/restore`,
|
|
35283
35303
|
WIKI_TREE: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/tree`,
|
|
35284
35304
|
WIKI_BLOB: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/blob`,
|
|
35305
|
+
WIKI_COPY: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/copy`,
|
|
35285
35306
|
WIKI_NODE_SECTIONS: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/node-sections`,
|
|
35286
35307
|
WIKI_SEARCH: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/search`,
|
|
35287
35308
|
WIKI_PAGE_INDEX: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/page-index`,
|
|
@@ -35343,6 +35364,7 @@ var ENDPOINTS = {
|
|
|
35343
35364
|
// References (org-scoped)
|
|
35344
35365
|
REFS_RESOLVE: (orgId) => `${API_BASE}/orgs/${orgId}/refs/resolve`,
|
|
35345
35366
|
REFS_BACKLINKS: (orgId) => `${API_BASE}/orgs/${orgId}/refs/backlinks`,
|
|
35367
|
+
REFS_GRAPH: (orgId) => `${API_BASE}/orgs/${orgId}/refs/graph`,
|
|
35346
35368
|
REFS_CHECK: (orgId) => `${API_BASE}/orgs/${orgId}/refs/check`,
|
|
35347
35369
|
// Platform config (agent-scoped, not org-scoped)
|
|
35348
35370
|
PLATFORM_CONFIG: `${API_BASE}/agents/platform-config`,
|
|
@@ -35363,6 +35385,14 @@ var ENDPOINTS = {
|
|
|
35363
35385
|
BILLING_AUTO_RELOAD: (orgId) => `${API_BASE}/orgs/${orgId}/billing/auto-reload`,
|
|
35364
35386
|
BILLING_SETUP_INTENT: (orgId) => `${API_BASE}/orgs/${orgId}/billing/setup-intent`,
|
|
35365
35387
|
COMPUTE_PRICING: () => `${API_BASE}/billing/compute-pricing`,
|
|
35388
|
+
// Runtime capability table (public, no auth) — SSOT for the create/settings
|
|
35389
|
+
// interlock: per-runtime compute modes, native model family, cross-family
|
|
35390
|
+
// availability, and recommended model.
|
|
35391
|
+
RUNTIMES: () => `${API_BASE}/runtimes`,
|
|
35392
|
+
// Model catalog (public, no auth) — served from the server's DB-backed
|
|
35393
|
+
// snapshot. Optional include_model keeps an agent's pinned hidden legacy
|
|
35394
|
+
// model representable in settings pickers.
|
|
35395
|
+
MODELS: (includeModel) => includeModel ? `${API_BASE}/models?include_model=${encodeURIComponent(includeModel)}` : `${API_BASE}/models`,
|
|
35366
35396
|
// ADMIN_GRANTS intentionally NOT exported here — it sits under the
|
|
35367
35397
|
// unauthenticated `/internal/admin/*` surface and must not bleed into the
|
|
35368
35398
|
// public SDK. Admin dashboard hits the URL directly from its own client.
|
|
@@ -35375,6 +35405,7 @@ var ENDPOINTS = {
|
|
|
35375
35405
|
AGENT_CLIP: (orgId, agentId, clipId) => `${CLIP_BASE}/orgs/${orgId}/agents/${agentId}/clips/${clipId}`,
|
|
35376
35406
|
CLIP_INVOKE: (orgId) => `${CLIP_BASE}/orgs/${orgId}/invoke`,
|
|
35377
35407
|
CLIP_ONLINE: (orgId) => `${CLIP_BASE}/orgs/${orgId}/online`,
|
|
35408
|
+
BROWSER_RUNTIME_STATUS: (orgId) => `${CLIP_BASE}/orgs/${orgId}/browser-runtime/status`,
|
|
35378
35409
|
BROWSER_PROFILES: (orgId) => `${CLIP_BASE}/orgs/${orgId}/browser-profiles`,
|
|
35379
35410
|
BROWSER_PROFILE: (orgId, profileId) => `${CLIP_BASE}/orgs/${orgId}/browser-profiles/${profileId}`,
|
|
35380
35411
|
BROWSER_PROFILE_OPEN: (orgId, profileId) => `${CLIP_BASE}/orgs/${orgId}/browser-profiles/${profileId}/open`,
|
|
@@ -35719,6 +35750,13 @@ var ParallClient = class _ParallClient {
|
|
|
35719
35750
|
const res = await this.request("GET", ENDPOINTS.ORG_MEMBERS(orgId));
|
|
35720
35751
|
return res.data;
|
|
35721
35752
|
}
|
|
35753
|
+
/** User IDs of soft-removed (former) org members — for marking their avatar /
|
|
35754
|
+
* name as "left" where dormant relations still surface them (DMs, task
|
|
35755
|
+
* assignees, message history). */
|
|
35756
|
+
async getFormerMemberIds(orgId) {
|
|
35757
|
+
const res = await this.request("GET", ENDPOINTS.ORG_MEMBERS_FORMER(orgId));
|
|
35758
|
+
return res.user_ids ?? [];
|
|
35759
|
+
}
|
|
35722
35760
|
async getTeams(orgId) {
|
|
35723
35761
|
const res = await this.request("GET", ENDPOINTS.TEAMS(orgId));
|
|
35724
35762
|
return res.data;
|
|
@@ -36200,26 +36238,32 @@ var ParallClient = class _ParallClient {
|
|
|
36200
36238
|
const res = await this.request("GET", ENDPOINTS.MACHINES_ME_CLIPS);
|
|
36201
36239
|
return res.data;
|
|
36202
36240
|
}
|
|
36203
|
-
/** `GET /machines/me/browser-profiles` — browser profiles hosted by this machine.
|
|
36241
|
+
/** `GET /machines/me/browser-profiles` — browser profiles hosted by this machine.
|
|
36242
|
+
* Returns the daemon DTO (carries proxy_password for bb-browser replay). */
|
|
36204
36243
|
async listMachineBrowserProfiles() {
|
|
36205
36244
|
const res = await this.request("GET", ENDPOINTS.MACHINES_ME_BROWSER_PROFILES);
|
|
36206
36245
|
return res.data;
|
|
36207
36246
|
}
|
|
36208
36247
|
/** `POST /machines/me/browser-profiles/{profileId}/status` — report runtime status. */
|
|
36209
|
-
async reportBrowserProfileStatus(profileId, status, errorMsg) {
|
|
36248
|
+
async reportBrowserProfileStatus(profileId, status, errorMsg, generation) {
|
|
36210
36249
|
await this.request("POST", ENDPOINTS.MACHINES_ME_BROWSER_PROFILE_STATUS(profileId), {
|
|
36211
36250
|
status,
|
|
36212
|
-
...errorMsg ? { error_msg: errorMsg } : {}
|
|
36251
|
+
...errorMsg ? { error_msg: errorMsg } : {},
|
|
36252
|
+
...generation !== void 0 ? { generation } : {}
|
|
36213
36253
|
});
|
|
36214
36254
|
}
|
|
36215
36255
|
/**
|
|
36216
36256
|
* `POST /machines/me/health` — bump the Machine's `updated_at` to now and
|
|
36217
|
-
* report daemon state. The daemon
|
|
36218
|
-
*
|
|
36257
|
+
* report daemon state. The daemon calls this on startup and again whenever
|
|
36258
|
+
* periodic runtime re-detection produces a CHANGED result (there is no
|
|
36259
|
+
* fixed-cadence keepalive loop today — steady state posts nothing). All
|
|
36219
36260
|
* fields are optional and only persisted when changed:
|
|
36220
36261
|
* - `daemonVersion` — the running bundle/launcher version.
|
|
36221
36262
|
* - `selfUpdateCapable` — whether the daemon can act on a machine.update
|
|
36222
36263
|
* signal (true under a service manager, false for bare `npx` foreground).
|
|
36264
|
+
* - `detectedRuntimes` — runtime CLIs found on the host. Omitted = no
|
|
36265
|
+
* report this beat (server keeps the stored value); [] = detection ran
|
|
36266
|
+
* and found nothing (server clears to empty).
|
|
36223
36267
|
*/
|
|
36224
36268
|
async postMachineHeartbeat(opts) {
|
|
36225
36269
|
const body = {};
|
|
@@ -36227,6 +36271,8 @@ var ParallClient = class _ParallClient {
|
|
|
36227
36271
|
body.daemon_version = opts.daemonVersion;
|
|
36228
36272
|
if (opts?.selfUpdateCapable !== void 0)
|
|
36229
36273
|
body.self_update_capable = opts.selfUpdateCapable;
|
|
36274
|
+
if (opts?.detectedRuntimes !== void 0)
|
|
36275
|
+
body.detected_runtimes = opts.detectedRuntimes;
|
|
36230
36276
|
return this.request("POST", ENDPOINTS.MACHINES_ME_HEALTH, Object.keys(body).length > 0 ? body : void 0);
|
|
36231
36277
|
}
|
|
36232
36278
|
async reportAgentWorkspaceState(agentId, state2) {
|
|
@@ -36545,6 +36591,59 @@ var ParallClient = class _ParallClient {
|
|
|
36545
36591
|
async deleteExternalConnection(orgId, connectionId) {
|
|
36546
36592
|
return this.request("DELETE", ENDPOINTS.EXTERNAL_CONNECTION(orgId, connectionId));
|
|
36547
36593
|
}
|
|
36594
|
+
// ---- External IM channel (org-scoped) ----
|
|
36595
|
+
async createChannelConnection(orgId, input) {
|
|
36596
|
+
return this.request("POST", ENDPOINTS.CHANNEL_CONNECTIONS(orgId), input);
|
|
36597
|
+
}
|
|
36598
|
+
async listChannelConnections(orgId) {
|
|
36599
|
+
return this.request("GET", ENDPOINTS.CHANNEL_CONNECTIONS(orgId));
|
|
36600
|
+
}
|
|
36601
|
+
async getChannelConnection(orgId, connectionId) {
|
|
36602
|
+
return this.request("GET", ENDPOINTS.CHANNEL_CONNECTION(orgId, connectionId));
|
|
36603
|
+
}
|
|
36604
|
+
async updateChannelConnection(orgId, connectionId, patch) {
|
|
36605
|
+
return this.request("PATCH", ENDPOINTS.CHANNEL_CONNECTION(orgId, connectionId), patch);
|
|
36606
|
+
}
|
|
36607
|
+
async archiveChannelConnection(orgId, connectionId) {
|
|
36608
|
+
return this.request("DELETE", ENDPOINTS.CHANNEL_CONNECTION(orgId, connectionId));
|
|
36609
|
+
}
|
|
36610
|
+
async deliverChannelCredentials(orgId, connectionId, credentials) {
|
|
36611
|
+
return this.request("POST", ENDPOINTS.CHANNEL_CONNECTION_CREDENTIALS(orgId, connectionId), credentials);
|
|
36612
|
+
}
|
|
36613
|
+
async regenerateChannelIngressToken(orgId, connectionId) {
|
|
36614
|
+
return this.request("POST", ENDPOINTS.CHANNEL_CONNECTION_INGRESS_TOKEN_REGENERATE(orgId, connectionId));
|
|
36615
|
+
}
|
|
36616
|
+
/** Start a Feishu one-click provisioning session (device flow QR). */
|
|
36617
|
+
async initiateChannelProvisioning(orgId, input) {
|
|
36618
|
+
return this.request("POST", ENDPOINTS.CHANNEL_PROVISIONING(orgId), input);
|
|
36619
|
+
}
|
|
36620
|
+
/**
|
|
36621
|
+
* Lazy status poll — server-side this may forward one provider poll, so
|
|
36622
|
+
* call it at the session's `poll_interval_seconds` cadence, not faster.
|
|
36623
|
+
*/
|
|
36624
|
+
async getChannelProvisioningSession(orgId, sessionId) {
|
|
36625
|
+
return this.request("GET", ENDPOINTS.CHANNEL_PROVISIONING_SESSION(orgId, sessionId));
|
|
36626
|
+
}
|
|
36627
|
+
async cancelChannelProvisioning(orgId, sessionId) {
|
|
36628
|
+
return this.request("POST", ENDPOINTS.CHANNEL_PROVISIONING_CANCEL(orgId, sessionId));
|
|
36629
|
+
}
|
|
36630
|
+
async listChannelConversations(orgId, connectionId) {
|
|
36631
|
+
return this.request("GET", ENDPOINTS.CHANNEL_CONNECTION_CONVERSATIONS(orgId, connectionId));
|
|
36632
|
+
}
|
|
36633
|
+
async getChannelConversation(orgId, conversationId) {
|
|
36634
|
+
return this.request("GET", ENDPOINTS.CHANNEL_CONVERSATION(orgId, conversationId));
|
|
36635
|
+
}
|
|
36636
|
+
async listChannelConversationMessages(orgId, conversationId, limit) {
|
|
36637
|
+
return this.request("GET", ENDPOINTS.CHANNEL_CONVERSATION_MESSAGES(orgId, conversationId), void 0, { limit });
|
|
36638
|
+
}
|
|
36639
|
+
async setChannelConversationSession(orgId, conversationId, agentSessionId) {
|
|
36640
|
+
return this.request("PATCH", ENDPOINTS.CHANNEL_CONVERSATION_SESSION(orgId, conversationId), {
|
|
36641
|
+
agent_session_id: agentSessionId
|
|
36642
|
+
});
|
|
36643
|
+
}
|
|
36644
|
+
async getChannelMessage(orgId, messageId) {
|
|
36645
|
+
return this.request("GET", ENDPOINTS.CHANNEL_MESSAGE(orgId, messageId));
|
|
36646
|
+
}
|
|
36548
36647
|
async getExternalTriggerSchema(orgId, connectionId) {
|
|
36549
36648
|
return this.request("GET", ENDPOINTS.EXTERNAL_TRIGGER_SCHEMA(orgId, connectionId));
|
|
36550
36649
|
}
|
|
@@ -36586,6 +36685,23 @@ var ParallClient = class _ParallClient {
|
|
|
36586
36685
|
async getWiki(orgId, wikiId) {
|
|
36587
36686
|
return this.request("GET", ENDPOINTS.WIKI(orgId, wikiId));
|
|
36588
36687
|
}
|
|
36688
|
+
/** Soft-delete an entire wiki (org owner only; the default wiki is
|
|
36689
|
+
* protected → 403 WIKI_PROTECTED). Returns the deleted wiki. Recoverable
|
|
36690
|
+
* via restoreWiki within the retention window. */
|
|
36691
|
+
async deleteWiki(orgId, wikiId) {
|
|
36692
|
+
return this.request("DELETE", ENDPOINTS.WIKI(orgId, wikiId));
|
|
36693
|
+
}
|
|
36694
|
+
/** Restore a soft-deleted wiki (org owner only). 409 WIKI_PURGE_STARTED once
|
|
36695
|
+
* purge has been claimed (no longer restorable), or 404 once the row is gone.
|
|
36696
|
+
* Returns the restored wiki. */
|
|
36697
|
+
async restoreWiki(orgId, wikiId) {
|
|
36698
|
+
return this.request("POST", ENDPOINTS.WIKI_RESTORE(orgId, wikiId));
|
|
36699
|
+
}
|
|
36700
|
+
/** Recycle bin — list soft-deleted wikis for the org (owner only). */
|
|
36701
|
+
async getDeletedWikis(orgId) {
|
|
36702
|
+
const res = await this.request("GET", ENDPOINTS.WIKIS_DELETED(orgId));
|
|
36703
|
+
return res.data;
|
|
36704
|
+
}
|
|
36589
36705
|
async getWikiTree(orgId, wikiId, params) {
|
|
36590
36706
|
return this.request("GET", ENDPOINTS.WIKI_TREE(orgId, wikiId), void 0, params);
|
|
36591
36707
|
}
|
|
@@ -36619,6 +36735,15 @@ var ParallClient = class _ParallClient {
|
|
|
36619
36735
|
blob.signed_url = this.absoluteMediaUrl(blob.signed_url);
|
|
36620
36736
|
return blob;
|
|
36621
36737
|
}
|
|
36738
|
+
/**
|
|
36739
|
+
* Copy one wiki file to another path as an independent snapshot (no sync).
|
|
36740
|
+
* Used to "share a private file out": copy a file from the caller's personal
|
|
36741
|
+
* namespace (`users/{userId}/…`) into the public wiki, leaving the original
|
|
36742
|
+
* untouched. 409 `FILE_EXISTS` if `dest_path` already exists.
|
|
36743
|
+
*/
|
|
36744
|
+
async copyWikiFile(orgId, wikiId, req) {
|
|
36745
|
+
return this.request("POST", ENDPOINTS.WIKI_COPY(orgId, wikiId), req);
|
|
36746
|
+
}
|
|
36622
36747
|
async getWikiNodeSections(orgId, wikiId, params) {
|
|
36623
36748
|
return this.request("GET", ENDPOINTS.WIKI_NODE_SECTIONS(orgId, wikiId), void 0, params);
|
|
36624
36749
|
}
|
|
@@ -36787,6 +36912,16 @@ var ParallClient = class _ParallClient {
|
|
|
36787
36912
|
async getBacklinks(orgId, params) {
|
|
36788
36913
|
return this.request("GET", ENDPOINTS.REFS_BACKLINKS(orgId), void 0, params);
|
|
36789
36914
|
}
|
|
36915
|
+
/**
|
|
36916
|
+
* Bounded multi-hop walk of the prll:// reference graph around `uri`. `uri`
|
|
36917
|
+
* must be an entity-level prll:// URI — a refined URI (path/query/fragment) is
|
|
36918
|
+
* rejected with 400 UNSUPPORTED_REFINED_URI. `depth` is clamped server-side to
|
|
36919
|
+
* [1, 4]; breadth (node/edge counts) is capped server-side and surfaced via
|
|
36920
|
+
* `truncated`. ACL is applied per hop (chat membership + wiki path scope).
|
|
36921
|
+
*/
|
|
36922
|
+
async getRefsGraph(orgId, params) {
|
|
36923
|
+
return this.request("GET", ENDPOINTS.REFS_GRAPH(orgId), void 0, params);
|
|
36924
|
+
}
|
|
36790
36925
|
async checkBrokenRefs(orgId) {
|
|
36791
36926
|
return this.request("GET", ENDPOINTS.REFS_CHECK(orgId));
|
|
36792
36927
|
}
|
|
@@ -36882,6 +37017,19 @@ var ParallClient = class _ParallClient {
|
|
|
36882
37017
|
const resp = await this.request("GET", ENDPOINTS.COMPUTE_PRICING());
|
|
36883
37018
|
return resp.data;
|
|
36884
37019
|
}
|
|
37020
|
+
/** Runtime capability table (public) — SSOT for the create/settings interlock. */
|
|
37021
|
+
async getRuntimes() {
|
|
37022
|
+
const resp = await this.request("GET", ENDPOINTS.RUNTIMES());
|
|
37023
|
+
return resp.data;
|
|
37024
|
+
}
|
|
37025
|
+
/**
|
|
37026
|
+
* Platform model catalog (public) — DB-backed, replaces the compile-time
|
|
37027
|
+
* PLATFORM_MODELS constant. Pass includeModel to keep an agent's pinned
|
|
37028
|
+
* hidden legacy model representable (settings picker).
|
|
37029
|
+
*/
|
|
37030
|
+
async getModels(includeModel) {
|
|
37031
|
+
return this.request("GET", ENDPOINTS.MODELS(includeModel));
|
|
37032
|
+
}
|
|
36885
37033
|
// ---- Clips ----
|
|
36886
37034
|
async listClips(orgId) {
|
|
36887
37035
|
const resp = await this.request("GET", ENDPOINTS.CLIPS(orgId));
|
|
@@ -36926,6 +37074,11 @@ var ParallClient = class _ParallClient {
|
|
|
36926
37074
|
const resp = await this.request("GET", ENDPOINTS.CLIP_ONLINE(orgId));
|
|
36927
37075
|
return resp.data;
|
|
36928
37076
|
}
|
|
37077
|
+
/** Deployment-wide hosted browser runtime availability — drives whether the
|
|
37078
|
+
* create UI offers the platform-hosted placement. Fail-closed server-side. */
|
|
37079
|
+
async getBrowserRuntimeStatus(orgId) {
|
|
37080
|
+
return this.request("GET", ENDPOINTS.BROWSER_RUNTIME_STATUS(orgId));
|
|
37081
|
+
}
|
|
36929
37082
|
/** Org-wide browser-profile discovery list. Returns the sanitized
|
|
36930
37083
|
* {@link BrowserProfileListItem} shape (not the full domain model), each row
|
|
36931
37084
|
* carrying a per-viewer `can_open` control hint. */
|
|
@@ -37034,6 +37187,50 @@ import { createRequire } from "node:module";
|
|
|
37034
37187
|
import * as path from "node:path";
|
|
37035
37188
|
import { fileURLToPath } from "node:url";
|
|
37036
37189
|
|
|
37190
|
+
// ts/daemon/dist/clip-runtime/browser-daemon-env.js
|
|
37191
|
+
var BROWSER_DAEMON_STRIPPED_ENV = [
|
|
37192
|
+
"PRLL_API_KEY",
|
|
37193
|
+
// machine key (mck_) — BYOC + agent control plane
|
|
37194
|
+
"PRLL_PROVIDER_CONFIG",
|
|
37195
|
+
// JSON ProviderConfig blob — may carry BYO LLM api keys
|
|
37196
|
+
"PRLL_ASSIGNMENT_TOKEN",
|
|
37197
|
+
// hosted pod platform assignment token (pba_)
|
|
37198
|
+
"PRLL_POOL_TOKEN",
|
|
37199
|
+
// hosted warm-pool bootstrap token (pba_)
|
|
37200
|
+
"AWS_ACCESS_KEY_ID",
|
|
37201
|
+
// hosted S3 browser-state STS creds (browser-pod.ts)
|
|
37202
|
+
"AWS_SECRET_ACCESS_KEY",
|
|
37203
|
+
"AWS_SESSION_TOKEN",
|
|
37204
|
+
// AWS credential-RESOLUTION vars: the SDK derives creds from these too (IRSA
|
|
37205
|
+
// web-identity, ECS/EKS container creds, named profile, on-disk cred/config
|
|
37206
|
+
// files), so a child inheriting them could assume the pod's role even without
|
|
37207
|
+
// the static keys above. bb-browser uses none of them.
|
|
37208
|
+
"AWS_WEB_IDENTITY_TOKEN_FILE",
|
|
37209
|
+
"AWS_ROLE_ARN",
|
|
37210
|
+
"AWS_ROLE_SESSION_NAME",
|
|
37211
|
+
"AWS_CONTAINER_CREDENTIALS_RELATIVE_URI",
|
|
37212
|
+
"AWS_CONTAINER_CREDENTIALS_FULL_URI",
|
|
37213
|
+
"AWS_CONTAINER_AUTHORIZATION_TOKEN",
|
|
37214
|
+
"AWS_PROFILE",
|
|
37215
|
+
"AWS_SHARED_CREDENTIALS_FILE",
|
|
37216
|
+
"AWS_CONFIG_FILE",
|
|
37217
|
+
"AWS_REGION",
|
|
37218
|
+
// hosted browser-state config — bb-browser does not use it
|
|
37219
|
+
"PRLL_BROWSER_STATE_REGION",
|
|
37220
|
+
// browser-pod AWS_REGION fallback — same config family
|
|
37221
|
+
"PRLL_BROWSER_STATE_BUCKET",
|
|
37222
|
+
"PRLL_STATE_GENERATION",
|
|
37223
|
+
"PRLL_BROWSER_STATE_ENDPOINT"
|
|
37224
|
+
];
|
|
37225
|
+
function buildBrowserDaemonEnv(baseEnv, homeDir) {
|
|
37226
|
+
const env = { ...baseEnv, BB_BROWSER_HOME: homeDir };
|
|
37227
|
+
clearAllProviderCreds(env);
|
|
37228
|
+
for (const key of BROWSER_DAEMON_STRIPPED_ENV) {
|
|
37229
|
+
delete env[key];
|
|
37230
|
+
}
|
|
37231
|
+
return env;
|
|
37232
|
+
}
|
|
37233
|
+
|
|
37037
37234
|
// ts/daemon/dist/clip-runtime/browser-viewer-streamer.js
|
|
37038
37235
|
import { spawn } from "node:child_process";
|
|
37039
37236
|
|
|
@@ -37063,6 +37260,41 @@ async function findFreePort() {
|
|
|
37063
37260
|
function sleep(ms) {
|
|
37064
37261
|
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
37065
37262
|
}
|
|
37263
|
+
function waitForChildExit(child, log, graceMs = 5e3, hardCapMs = 15e3) {
|
|
37264
|
+
if (child.exitCode !== null || child.signalCode !== null)
|
|
37265
|
+
return Promise.resolve();
|
|
37266
|
+
return new Promise((resolve2) => {
|
|
37267
|
+
let killTimer;
|
|
37268
|
+
let capTimer;
|
|
37269
|
+
const finish = () => {
|
|
37270
|
+
child.removeListener("exit", finish);
|
|
37271
|
+
if (killTimer)
|
|
37272
|
+
clearTimeout(killTimer);
|
|
37273
|
+
if (capTimer)
|
|
37274
|
+
clearTimeout(capTimer);
|
|
37275
|
+
resolve2();
|
|
37276
|
+
};
|
|
37277
|
+
child.once("exit", finish);
|
|
37278
|
+
try {
|
|
37279
|
+
child.kill("SIGTERM");
|
|
37280
|
+
} catch {
|
|
37281
|
+
}
|
|
37282
|
+
killTimer = setTimeout(() => {
|
|
37283
|
+
if (child.exitCode === null && child.signalCode === null) {
|
|
37284
|
+
try {
|
|
37285
|
+
child.kill("SIGKILL");
|
|
37286
|
+
} catch {
|
|
37287
|
+
}
|
|
37288
|
+
}
|
|
37289
|
+
}, graceMs);
|
|
37290
|
+
capTimer = setTimeout(() => {
|
|
37291
|
+
log?.warn(`child did not exit within ${hardCapMs}ms after SIGKILL; proceeding`);
|
|
37292
|
+
finish();
|
|
37293
|
+
}, hardCapMs);
|
|
37294
|
+
killTimer.unref?.();
|
|
37295
|
+
capTimer.unref?.();
|
|
37296
|
+
});
|
|
37297
|
+
}
|
|
37066
37298
|
|
|
37067
37299
|
// ts/daemon/dist/clip-runtime/browser-viewer-streamer.js
|
|
37068
37300
|
var BB_VIEWER_HEALTH_TIMEOUT_MS = 1e4;
|
|
@@ -37641,6 +37873,7 @@ function filterTabListToAccount(result, account) {
|
|
|
37641
37873
|
|
|
37642
37874
|
// ts/daemon/dist/clip-runtime/browser-profile-manager.js
|
|
37643
37875
|
var BB_BROWSER_DAEMON_START_TIMEOUT_MS = 15e3;
|
|
37876
|
+
var BB_BROWSER_DAEMON_START_ATTEMPTS = 3;
|
|
37644
37877
|
var BrowserCommandError = class extends Error {
|
|
37645
37878
|
method;
|
|
37646
37879
|
account;
|
|
@@ -37656,6 +37889,11 @@ var BrowserProfileManager = class {
|
|
|
37656
37889
|
daemon = null;
|
|
37657
37890
|
starting = null;
|
|
37658
37891
|
restarting = null;
|
|
37892
|
+
// Set by stop() and never reset (stop() is terminal — the pool disposes the
|
|
37893
|
+
// manager and the hosted pod exits). Makes a startDaemon() that resolves after
|
|
37894
|
+
// stop() began un-adoptable, so a late child can't be reassigned to this.daemon
|
|
37895
|
+
// and escape teardown.
|
|
37896
|
+
stopping = false;
|
|
37659
37897
|
ensuredAccounts = /* @__PURE__ */ new Set();
|
|
37660
37898
|
ensuringAccounts = /* @__PURE__ */ new Map();
|
|
37661
37899
|
reportedStatuses = /* @__PURE__ */ new Map();
|
|
@@ -37706,9 +37944,12 @@ var BrowserProfileManager = class {
|
|
|
37706
37944
|
throw err;
|
|
37707
37945
|
}
|
|
37708
37946
|
}
|
|
37709
|
-
async ensureRuntime(profileId) {
|
|
37947
|
+
async ensureRuntime(profileId, opts = {}) {
|
|
37710
37948
|
if (!profileId)
|
|
37711
37949
|
throw new Error("browser profile id is required");
|
|
37950
|
+
if (opts.forceStatusReport) {
|
|
37951
|
+
this.reportedStatuses.delete(profileId);
|
|
37952
|
+
}
|
|
37712
37953
|
try {
|
|
37713
37954
|
await this.withDaemonRecovery(() => this.ensureAccount(profileId), `ensure runtime for ${profileId}`);
|
|
37714
37955
|
this.reportStatus(profileId, "running");
|
|
@@ -37757,22 +37998,36 @@ var BrowserProfileManager = class {
|
|
|
37757
37998
|
}
|
|
37758
37999
|
}
|
|
37759
38000
|
async stop() {
|
|
38001
|
+
this.stopping = true;
|
|
37760
38002
|
this.viewer.shutdown();
|
|
38003
|
+
const inflight = this.starting;
|
|
38004
|
+
const restarting = this.restarting;
|
|
37761
38005
|
const daemon = this.daemon;
|
|
37762
38006
|
this.daemon = null;
|
|
37763
38007
|
this.starting = null;
|
|
37764
38008
|
this.ensuredAccounts.clear();
|
|
37765
38009
|
this.ensuringAccounts.clear();
|
|
37766
38010
|
this.reportedStatuses.clear();
|
|
37767
|
-
if (
|
|
37768
|
-
|
|
37769
|
-
|
|
37770
|
-
|
|
37771
|
-
|
|
38011
|
+
if (restarting) {
|
|
38012
|
+
try {
|
|
38013
|
+
await restarting;
|
|
38014
|
+
} catch {
|
|
38015
|
+
}
|
|
37772
38016
|
}
|
|
37773
|
-
|
|
37774
|
-
|
|
38017
|
+
let started = null;
|
|
38018
|
+
if (inflight) {
|
|
38019
|
+
try {
|
|
38020
|
+
started = await inflight;
|
|
38021
|
+
} catch {
|
|
38022
|
+
}
|
|
37775
38023
|
}
|
|
38024
|
+
await Promise.all([daemon, started].filter((d5) => d5 !== null).map(async (d5) => {
|
|
38025
|
+
try {
|
|
38026
|
+
await this.post("/shutdown", d5, void 0, 3e3);
|
|
38027
|
+
} catch {
|
|
38028
|
+
}
|
|
38029
|
+
await waitForChildExit(d5.child, this.opts.log);
|
|
38030
|
+
}));
|
|
37776
38031
|
}
|
|
37777
38032
|
/**
|
|
37778
38033
|
* Viewer control command entrypoint — delegates to BrowserViewerStreamer
|
|
@@ -37922,10 +38177,12 @@ var BrowserProfileManager = class {
|
|
|
37922
38177
|
if (!isBrowserAccountInfoUnauthenticatedError(err)) {
|
|
37923
38178
|
if (!isBrowserAccountNotFoundError(err))
|
|
37924
38179
|
throw err;
|
|
38180
|
+
const proxy = this.opts.resolveProxy ? await this.opts.resolveProxy(account) : null;
|
|
37925
38181
|
await this.sendCommand({
|
|
37926
38182
|
method: "account_create",
|
|
37927
38183
|
account,
|
|
37928
|
-
...accountUrl ? { accountUrl } : {}
|
|
38184
|
+
...accountUrl ? { accountUrl } : {},
|
|
38185
|
+
...proxyCreateFields(proxy)
|
|
37929
38186
|
});
|
|
37930
38187
|
accountCreated = true;
|
|
37931
38188
|
}
|
|
@@ -37996,17 +38253,28 @@ var BrowserProfileManager = class {
|
|
|
37996
38253
|
async ensureDaemon() {
|
|
37997
38254
|
if (this.restarting)
|
|
37998
38255
|
await this.restarting;
|
|
38256
|
+
if (this.stopping)
|
|
38257
|
+
throw new Error("browser profile manager is stopping");
|
|
37999
38258
|
if (this.daemon && this.daemon.child.exitCode === null && this.daemon.child.signalCode === null) {
|
|
38000
38259
|
return this.daemon;
|
|
38001
38260
|
}
|
|
38002
|
-
if (this.starting)
|
|
38003
|
-
|
|
38261
|
+
if (this.starting) {
|
|
38262
|
+
const started = await this.starting;
|
|
38263
|
+
if (this.stopping)
|
|
38264
|
+
throw new Error("browser profile manager is stopping");
|
|
38265
|
+
return started;
|
|
38266
|
+
}
|
|
38004
38267
|
this.starting = this.startDaemon();
|
|
38268
|
+
const startPromise = this.starting;
|
|
38005
38269
|
try {
|
|
38006
|
-
|
|
38270
|
+
const started = await startPromise;
|
|
38271
|
+
if (this.stopping)
|
|
38272
|
+
throw new Error("browser profile manager is stopping");
|
|
38273
|
+
this.daemon = started;
|
|
38007
38274
|
return this.daemon;
|
|
38008
38275
|
} finally {
|
|
38009
|
-
this.starting
|
|
38276
|
+
if (this.starting === startPromise)
|
|
38277
|
+
this.starting = null;
|
|
38010
38278
|
}
|
|
38011
38279
|
}
|
|
38012
38280
|
async withDaemonRecovery(operation2, label) {
|
|
@@ -38042,20 +38310,46 @@ var BrowserProfileManager = class {
|
|
|
38042
38310
|
await this.post("/shutdown", daemon, void 0, 3e3);
|
|
38043
38311
|
} catch {
|
|
38044
38312
|
}
|
|
38045
|
-
|
|
38046
|
-
daemon.child.kill("SIGTERM");
|
|
38047
|
-
}
|
|
38313
|
+
await waitForChildExit(daemon.child, this.opts.log);
|
|
38048
38314
|
}
|
|
38049
38315
|
async startDaemon() {
|
|
38316
|
+
let lastErr;
|
|
38317
|
+
for (let attempt = 1; attempt <= BB_BROWSER_DAEMON_START_ATTEMPTS; attempt++) {
|
|
38318
|
+
try {
|
|
38319
|
+
return await this.startDaemonAttempt();
|
|
38320
|
+
} catch (err) {
|
|
38321
|
+
lastErr = err;
|
|
38322
|
+
if (attempt < BB_BROWSER_DAEMON_START_ATTEMPTS) {
|
|
38323
|
+
this.opts.log.warn(`[bb-browser] daemon start attempt ${attempt} failed; retrying with fresh ports: ${String(err)}`);
|
|
38324
|
+
}
|
|
38325
|
+
}
|
|
38326
|
+
}
|
|
38327
|
+
throw lastErr instanceof Error ? lastErr : new Error(String(lastErr));
|
|
38328
|
+
}
|
|
38329
|
+
async startDaemonAttempt() {
|
|
38050
38330
|
const host = "127.0.0.1";
|
|
38051
38331
|
const port = await findFreePort();
|
|
38332
|
+
let cdpPort = await findFreePort();
|
|
38333
|
+
for (let i5 = 0; cdpPort === port && i5 < 5; i5++) {
|
|
38334
|
+
cdpPort = await findFreePort();
|
|
38335
|
+
}
|
|
38336
|
+
if (cdpPort === port) {
|
|
38337
|
+
throw new Error("bb-browser: could not allocate distinct HTTP and CDP ports");
|
|
38338
|
+
}
|
|
38052
38339
|
const token = randomToken();
|
|
38053
38340
|
const daemonPath = resolveBbBrowserDaemonPath();
|
|
38054
|
-
const child = spawn2(process.execPath, [
|
|
38055
|
-
|
|
38056
|
-
|
|
38057
|
-
|
|
38058
|
-
|
|
38341
|
+
const child = spawn2(process.execPath, [
|
|
38342
|
+
daemonPath,
|
|
38343
|
+
"--host",
|
|
38344
|
+
host,
|
|
38345
|
+
"--port",
|
|
38346
|
+
String(port),
|
|
38347
|
+
"--token",
|
|
38348
|
+
token,
|
|
38349
|
+
"--cdp-port",
|
|
38350
|
+
String(cdpPort)
|
|
38351
|
+
], {
|
|
38352
|
+
env: buildBrowserDaemonEnv(process.env, this.opts.homeDir),
|
|
38059
38353
|
stdio: ["ignore", "ignore", "pipe"]
|
|
38060
38354
|
});
|
|
38061
38355
|
let childError = null;
|
|
@@ -38084,7 +38378,7 @@ var BrowserProfileManager = class {
|
|
|
38084
38378
|
await sleep(200);
|
|
38085
38379
|
}
|
|
38086
38380
|
}
|
|
38087
|
-
child.
|
|
38381
|
+
await waitForChildExit(child, this.opts.log);
|
|
38088
38382
|
throw new Error("bb-browser-daemon did not start in time");
|
|
38089
38383
|
}
|
|
38090
38384
|
async post(pathName, daemon, body, timeoutMs = 1e4) {
|
|
@@ -38182,6 +38476,16 @@ function resolveBbBrowserDaemonPath() {
|
|
|
38182
38476
|
function randomToken() {
|
|
38183
38477
|
return randomBytes(16).toString("hex");
|
|
38184
38478
|
}
|
|
38479
|
+
function proxyCreateFields(proxy) {
|
|
38480
|
+
if (!proxy?.server)
|
|
38481
|
+
return {};
|
|
38482
|
+
const fields = { proxyServer: proxy.server };
|
|
38483
|
+
if (proxy.username)
|
|
38484
|
+
fields.proxyUsername = proxy.username;
|
|
38485
|
+
if (proxy.password)
|
|
38486
|
+
fields.proxyPassword = proxy.password;
|
|
38487
|
+
return fields;
|
|
38488
|
+
}
|
|
38185
38489
|
|
|
38186
38490
|
// ts/daemon/dist/clip-runtime/browser-state-store.js
|
|
38187
38491
|
var import_client_s3 = __toESM(require_dist_cjs73(), 1);
|
|
@@ -40165,9 +40469,25 @@ function resolveBrowserPodConfig(env = process.env) {
|
|
|
40165
40469
|
orgId,
|
|
40166
40470
|
healthPort: parsePort(env.PRLL_HEALTH_PORT, DEFAULT_HEALTH_PORT),
|
|
40167
40471
|
stateDir,
|
|
40168
|
-
homeDir
|
|
40472
|
+
homeDir,
|
|
40473
|
+
proxy: parseProxyEnv(env)
|
|
40169
40474
|
};
|
|
40170
40475
|
}
|
|
40476
|
+
function parseProxyEnv(env) {
|
|
40477
|
+
const server = env.PRLL_BROWSER_PROXY_SERVER?.trim();
|
|
40478
|
+
const username = env.PRLL_BROWSER_PROXY_USERNAME || void 0;
|
|
40479
|
+
const password = env.PRLL_BROWSER_PROXY_PASSWORD || void 0;
|
|
40480
|
+
if (!server) {
|
|
40481
|
+
if (username !== void 0 || password !== void 0) {
|
|
40482
|
+
throw new Error("browser-pod: PRLL_BROWSER_PROXY_USERNAME/PASSWORD set without PRLL_BROWSER_PROXY_SERVER");
|
|
40483
|
+
}
|
|
40484
|
+
return null;
|
|
40485
|
+
}
|
|
40486
|
+
if (username === void 0 !== (password === void 0)) {
|
|
40487
|
+
throw new Error("browser-pod: PRLL_BROWSER_PROXY_USERNAME and PRLL_BROWSER_PROXY_PASSWORD must be set together");
|
|
40488
|
+
}
|
|
40489
|
+
return { server, username, password };
|
|
40490
|
+
}
|
|
40171
40491
|
function resolvePoolPodConfig(env = process.env) {
|
|
40172
40492
|
const poolToken = env.PRLL_POOL_TOKEN?.trim() || "";
|
|
40173
40493
|
const podId = env.PRLL_POD_ID?.trim() || "";
|
|
@@ -40236,7 +40556,25 @@ function parseAssignRequest(body) {
|
|
|
40236
40556
|
sessionToken
|
|
40237
40557
|
};
|
|
40238
40558
|
}
|
|
40239
|
-
|
|
40559
|
+
let proxy;
|
|
40560
|
+
if (b5.proxy !== void 0 && b5.proxy !== null) {
|
|
40561
|
+
if (typeof b5.proxy !== "object")
|
|
40562
|
+
return { ok: false, error: "proxy must be an object" };
|
|
40563
|
+
const p2 = b5.proxy;
|
|
40564
|
+
const server = str(p2.server);
|
|
40565
|
+
if (!server)
|
|
40566
|
+
return { ok: false, error: "proxy requires server" };
|
|
40567
|
+
const username = (typeof p2.username === "string" ? p2.username : "") || void 0;
|
|
40568
|
+
const password = (typeof p2.password === "string" ? p2.password : "") || void 0;
|
|
40569
|
+
if (username === void 0 !== (password === void 0)) {
|
|
40570
|
+
return { ok: false, error: "proxy username and password must be provided together" };
|
|
40571
|
+
}
|
|
40572
|
+
proxy = { server, username, password };
|
|
40573
|
+
}
|
|
40574
|
+
return {
|
|
40575
|
+
ok: true,
|
|
40576
|
+
value: { assignmentToken, profileId, orgId, leaseId, generation, state: state2, proxy }
|
|
40577
|
+
};
|
|
40240
40578
|
}
|
|
40241
40579
|
function applyAssignmentEnv(env, req) {
|
|
40242
40580
|
env.PRLL_ASSIGNMENT_TOKEN = req.assignmentToken;
|
|
@@ -40254,6 +40592,16 @@ function applyAssignmentEnv(env, req) {
|
|
|
40254
40592
|
if (req.state.endpoint)
|
|
40255
40593
|
env.PRLL_BROWSER_STATE_ENDPOINT = req.state.endpoint;
|
|
40256
40594
|
}
|
|
40595
|
+
delete env.PRLL_BROWSER_PROXY_SERVER;
|
|
40596
|
+
delete env.PRLL_BROWSER_PROXY_USERNAME;
|
|
40597
|
+
delete env.PRLL_BROWSER_PROXY_PASSWORD;
|
|
40598
|
+
if (req.proxy) {
|
|
40599
|
+
env.PRLL_BROWSER_PROXY_SERVER = req.proxy.server;
|
|
40600
|
+
if (req.proxy.username)
|
|
40601
|
+
env.PRLL_BROWSER_PROXY_USERNAME = req.proxy.username;
|
|
40602
|
+
if (req.proxy.password)
|
|
40603
|
+
env.PRLL_BROWSER_PROXY_PASSWORD = req.proxy.password;
|
|
40604
|
+
}
|
|
40257
40605
|
}
|
|
40258
40606
|
function poolTokenMatches(bearer, expected) {
|
|
40259
40607
|
if (!bearer)
|
|
@@ -40507,7 +40855,11 @@ function makeCheckpointer(store) {
|
|
|
40507
40855
|
};
|
|
40508
40856
|
}
|
|
40509
40857
|
async function preparePodRuntime(config, env, log) {
|
|
40510
|
-
const browser = new BrowserProfileManager({
|
|
40858
|
+
const browser = new BrowserProfileManager({
|
|
40859
|
+
homeDir: config.homeDir,
|
|
40860
|
+
log,
|
|
40861
|
+
resolveProxy: () => config.proxy
|
|
40862
|
+
});
|
|
40511
40863
|
const clipManager = new ClipProcessManager({
|
|
40512
40864
|
clipsDir: path5.join(config.stateDir, "clips"),
|
|
40513
40865
|
dataDir: path5.join(config.stateDir, "clip-data"),
|