@parall/daemon 1.46.0 → 1.48.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 +161 -7
- package/bundle/parall-claude-agent.js +188 -7
- package/bundle/parall-codex-agent.js +188 -7
- package/bundle/parall-daemon.js +693 -232
- package/dist/local-control.d.ts +59 -0
- package/dist/local-control.d.ts.map +1 -0
- package/dist/local-control.js +230 -0
- package/dist/local-profile-control.d.ts +77 -0
- package/dist/local-profile-control.d.ts.map +1 -0
- package/dist/local-profile-control.js +108 -0
- package/dist/supervisor.d.ts +13 -0
- package/dist/supervisor.d.ts.map +1 -1
- package/dist/supervisor.js +42 -0
- package/package.json +6 -6
package/bundle/parall-daemon.js
CHANGED
|
@@ -324,10 +324,17 @@ var init_constants = __esm({
|
|
|
324
324
|
CHANNEL_CONVERSATION_SESSION: (orgId, conversationId) => `${API_BASE}/orgs/${orgId}/channel-conversations/${conversationId}/session`,
|
|
325
325
|
CHANNEL_MESSAGE: (orgId, messageId) => `${API_BASE}/orgs/${orgId}/channel-messages/${messageId}`,
|
|
326
326
|
CHANNEL_PROVISIONING: (orgId) => `${API_BASE}/orgs/${orgId}/channel-provisioning`,
|
|
327
|
+
CHANNEL_SLACK_MANIFEST_LINK: (orgId) => `${API_BASE}/orgs/${orgId}/channel-provisioning/slack/manifest-link`,
|
|
327
328
|
CHANNEL_PROVISIONING_SESSION: (orgId, sessionId) => `${API_BASE}/orgs/${orgId}/channel-provisioning/${sessionId}`,
|
|
328
329
|
CHANNEL_PROVISIONING_CANCEL: (orgId, sessionId) => `${API_BASE}/orgs/${orgId}/channel-provisioning/${sessionId}/cancel`,
|
|
329
330
|
// Tier-B platform verb (agent-only): send one message as the bound bot.
|
|
330
331
|
CHANNEL_SEND: (orgId) => `${API_BASE}/orgs/${orgId}/agents/me/channel-send`,
|
|
332
|
+
// Tier-B read verbs (agent-only): workspace visibility as the bot sees it.
|
|
333
|
+
SLACK_CHANNELS: (orgId) => `${API_BASE}/orgs/${orgId}/agents/me/slack/channels`,
|
|
334
|
+
SLACK_USERS: (orgId) => `${API_BASE}/orgs/${orgId}/agents/me/slack/users`,
|
|
335
|
+
SLACK_HISTORY: (orgId) => `${API_BASE}/orgs/${orgId}/agents/me/slack/history`,
|
|
336
|
+
SLACK_MEMBERS: (orgId) => `${API_BASE}/orgs/${orgId}/agents/me/slack/members`,
|
|
337
|
+
SLACK_STATUS: (orgId) => `${API_BASE}/orgs/${orgId}/agents/me/slack/status`,
|
|
331
338
|
// Invitations (org-scoped, admin)
|
|
332
339
|
ORG_INVITATIONS: (orgId) => `${API_BASE}/orgs/${orgId}/invitations`,
|
|
333
340
|
ORG_INVITATION: (orgId, invId) => `${API_BASE}/orgs/${orgId}/invitations/${invId}`,
|
|
@@ -422,6 +429,7 @@ var init_constants = __esm({
|
|
|
422
429
|
ORG_UNREAD: (orgId) => `${API_BASE}/orgs/${orgId}/unread`,
|
|
423
430
|
CHAT_READ: (orgId, chatId) => `${API_BASE}/orgs/${orgId}/chats/${chatId}/read`,
|
|
424
431
|
THREAD_UNREAD: (orgId, chatId, threadRootId) => `${API_BASE}/orgs/${orgId}/chats/${chatId}/threads/${threadRootId}/unread`,
|
|
432
|
+
THREAD_READ: (orgId, chatId, threadRootId) => `${API_BASE}/orgs/${orgId}/chats/${chatId}/threads/${threadRootId}/read`,
|
|
425
433
|
// References (org-scoped)
|
|
426
434
|
REFS_RESOLVE: (orgId) => `${API_BASE}/orgs/${orgId}/refs/resolve`,
|
|
427
435
|
REFS_BACKLINKS: (orgId) => `${API_BASE}/orgs/${orgId}/refs/backlinks`,
|
|
@@ -483,10 +491,17 @@ var init_constants = __esm({
|
|
|
483
491
|
ORG_EDGE: (orgId) => `/api/v1/orgs/${orgId}/edge`,
|
|
484
492
|
ORG_EDGE_DEVICES: (orgId) => `/api/v1/orgs/${orgId}/edge/devices`,
|
|
485
493
|
ORG_EDGE_DEVICE: (orgId, edgeId) => `/api/v1/orgs/${orgId}/edge/${edgeId}`,
|
|
494
|
+
ORG_EDGE_DEVICE_UNREGISTER: (orgId, edgeId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/unregister`,
|
|
486
495
|
ORG_EDGE_ONBOARDING: (orgId) => `/api/v1/orgs/${orgId}/edge/onboarding`,
|
|
487
496
|
ORG_EDGE_PROFILES: (orgId, edgeId) => `/api/v1/orgs/${orgId}/edge/${edgeId}/profiles`,
|
|
497
|
+
ORG_EDGE_EXEC: (orgId) => `/api/v1/orgs/${orgId}/edge/exec`,
|
|
488
498
|
CLIP_CONNECTIONS: (orgId, clipId) => `/api/v1/orgs/${orgId}/clip-registry/${clipId}/connections`,
|
|
489
|
-
CLIP_CONNECTION: (orgId, connId) => `/api/v1/orgs/${orgId}/clip-connections/${connId}
|
|
499
|
+
CLIP_CONNECTION: (orgId, connId) => `/api/v1/orgs/${orgId}/clip-connections/${connId}`,
|
|
500
|
+
// Clip registry (v3, org-scoped, served by api-server — `crg_` entries; the
|
|
501
|
+
// Pinix Hub catalog proxy above is a different, id-less surface)
|
|
502
|
+
ORG_CLIP_REGISTRY: (orgId) => `/api/v1/orgs/${orgId}/clip-registry`,
|
|
503
|
+
ORG_CLIP_INSTALL: (orgId) => `/api/v1/orgs/${orgId}/clips/install`,
|
|
504
|
+
ORG_CLIPS_INSTALLED: (orgId) => `/api/v1/orgs/${orgId}/clips/installed`
|
|
490
505
|
};
|
|
491
506
|
WS_EVENTS = {
|
|
492
507
|
// Client -> Server
|
|
@@ -656,7 +671,7 @@ var init_client = __esm({
|
|
|
656
671
|
return apiError;
|
|
657
672
|
}
|
|
658
673
|
/** Build headers common to all requests (auth, swimlane). */
|
|
659
|
-
buildHeaders(
|
|
674
|
+
buildHeaders(path23, extra) {
|
|
660
675
|
const headers = {
|
|
661
676
|
"Content-Type": "application/json",
|
|
662
677
|
...extra
|
|
@@ -667,7 +682,7 @@ var init_client = __esm({
|
|
|
667
682
|
if (this.swimlaneName) {
|
|
668
683
|
headers["X-Prll-Swimlane"] = this.swimlaneName;
|
|
669
684
|
}
|
|
670
|
-
if (
|
|
685
|
+
if (path23.startsWith(API_BASE)) {
|
|
671
686
|
const overrides = this.getFeatureFlagOverrides?.();
|
|
672
687
|
if (overrides)
|
|
673
688
|
headers["X-Prll-FF-Override"] = overrides;
|
|
@@ -690,8 +705,8 @@ var init_client = __esm({
|
|
|
690
705
|
* is authoritative, so wiki vs api routing can't drift from how a caller
|
|
691
706
|
* happens to invoke the client.
|
|
692
707
|
*/
|
|
693
|
-
baseUrlFor(
|
|
694
|
-
return
|
|
708
|
+
baseUrlFor(path23) {
|
|
709
|
+
return path23.startsWith(WIKI_BASE) ? this.wikiBaseUrl : this.baseUrl;
|
|
695
710
|
}
|
|
696
711
|
setToken(token) {
|
|
697
712
|
this.token = token;
|
|
@@ -718,10 +733,10 @@ var init_client = __esm({
|
|
|
718
733
|
* REFRESH_THRESHOLD_S, refresh it **before** sending the request.
|
|
719
734
|
* No-op when the token is still fresh, missing, or un-parseable.
|
|
720
735
|
*/
|
|
721
|
-
async ensureFreshToken(
|
|
736
|
+
async ensureFreshToken(path23) {
|
|
722
737
|
if (!this.token || !this.getRefreshToken)
|
|
723
738
|
return;
|
|
724
|
-
const pathSuffix =
|
|
739
|
+
const pathSuffix = path23.replace(/^\/api\/v1/, "");
|
|
725
740
|
if (_ParallClient.AUTH_PATHS.has(pathSuffix))
|
|
726
741
|
return;
|
|
727
742
|
const exp = _ParallClient.decodeJwtExp(this.token);
|
|
@@ -753,11 +768,11 @@ var init_client = __esm({
|
|
|
753
768
|
this.refreshPromise = null;
|
|
754
769
|
}
|
|
755
770
|
}
|
|
756
|
-
async request(method,
|
|
771
|
+
async request(method, path23, body, query, retried = false, opts) {
|
|
757
772
|
if (!retried) {
|
|
758
|
-
await this.ensureFreshToken(
|
|
773
|
+
await this.ensureFreshToken(path23);
|
|
759
774
|
}
|
|
760
|
-
let url = `${this.baseUrlFor(
|
|
775
|
+
let url = `${this.baseUrlFor(path23)}${path23}`;
|
|
761
776
|
if (query) {
|
|
762
777
|
const params = new URLSearchParams();
|
|
763
778
|
for (const [key, value] of Object.entries(query)) {
|
|
@@ -769,7 +784,7 @@ var init_client = __esm({
|
|
|
769
784
|
if (qs)
|
|
770
785
|
url += `?${qs}`;
|
|
771
786
|
}
|
|
772
|
-
const headers = this.buildHeaders(
|
|
787
|
+
const headers = this.buildHeaders(path23);
|
|
773
788
|
const timeoutSignal = AbortSignal.timeout(opts?.timeoutMs ?? 15e3);
|
|
774
789
|
const signal = opts?.signal ? AbortSignal.any([opts.signal, timeoutSignal]) : timeoutSignal;
|
|
775
790
|
let res;
|
|
@@ -787,12 +802,12 @@ var init_client = __esm({
|
|
|
787
802
|
throw _ParallClient.normalizeFetchError(err);
|
|
788
803
|
}
|
|
789
804
|
if (res.status === 401) {
|
|
790
|
-
const pathSuffix =
|
|
805
|
+
const pathSuffix = path23.replace(/^\/api\/v1/, "");
|
|
791
806
|
const isAuthPath = _ParallClient.AUTH_PATHS.has(pathSuffix);
|
|
792
807
|
if (!retried && !isAuthPath && this.getRefreshToken) {
|
|
793
808
|
const refreshed = await this.tryRefresh();
|
|
794
809
|
if (refreshed) {
|
|
795
|
-
return this.request(method,
|
|
810
|
+
return this.request(method, path23, body, query, true, opts);
|
|
796
811
|
}
|
|
797
812
|
}
|
|
798
813
|
if (this.onTokenExpired && !isAuthPath) {
|
|
@@ -822,15 +837,15 @@ var init_client = __esm({
|
|
|
822
837
|
* hit the 100 MiB cap, so a longer 5-minute timeout is used so a
|
|
823
838
|
* 50 MiB blob on a slow connection doesn't get chopped at 15 s.
|
|
824
839
|
*/
|
|
825
|
-
async multipartRequest(method,
|
|
840
|
+
async multipartRequest(method, path23, body, retried = false) {
|
|
826
841
|
if (!retried) {
|
|
827
|
-
await this.ensureFreshToken(
|
|
842
|
+
await this.ensureFreshToken(path23);
|
|
828
843
|
}
|
|
829
|
-
const { "Content-Type": _drop, ...headers } = this.buildHeaders(
|
|
844
|
+
const { "Content-Type": _drop, ...headers } = this.buildHeaders(path23);
|
|
830
845
|
void _drop;
|
|
831
846
|
let res;
|
|
832
847
|
try {
|
|
833
|
-
res = await fetch(`${this.baseUrlFor(
|
|
848
|
+
res = await fetch(`${this.baseUrlFor(path23)}${path23}`, {
|
|
834
849
|
method,
|
|
835
850
|
headers,
|
|
836
851
|
body,
|
|
@@ -840,12 +855,12 @@ var init_client = __esm({
|
|
|
840
855
|
throw _ParallClient.normalizeFetchError(err);
|
|
841
856
|
}
|
|
842
857
|
if (res.status === 401) {
|
|
843
|
-
const pathSuffix =
|
|
858
|
+
const pathSuffix = path23.replace(/^\/api\/v1/, "");
|
|
844
859
|
const isAuthPath = _ParallClient.AUTH_PATHS.has(pathSuffix);
|
|
845
860
|
if (!retried && !isAuthPath && this.getRefreshToken) {
|
|
846
861
|
const refreshed = await this.tryRefresh();
|
|
847
862
|
if (refreshed) {
|
|
848
|
-
return this.multipartRequest(method,
|
|
863
|
+
return this.multipartRequest(method, path23, body, true);
|
|
849
864
|
}
|
|
850
865
|
}
|
|
851
866
|
if (this.onTokenExpired && !isAuthPath) {
|
|
@@ -1553,12 +1568,18 @@ var init_client = __esm({
|
|
|
1553
1568
|
async resizeMachine(orgId, machineId, spec) {
|
|
1554
1569
|
return this.request("PATCH", ENDPOINTS.MACHINE_SPEC(orgId, machineId), spec);
|
|
1555
1570
|
}
|
|
1556
|
-
/**
|
|
1571
|
+
/** @deprecated Retired server-side (daemon-control-authorization §4.2):
|
|
1572
|
+
* daemons update autonomously (CDN poll + platform release signal). The
|
|
1573
|
+
* endpoint now answers 409 LOCAL_UPDATE_NOT_SUPPORTED unconditionally. */
|
|
1557
1574
|
async requestMachineUpdate(orgId, machineId, mandatory = false) {
|
|
1558
1575
|
await this.request("POST", ENDPOINTS.MACHINE_REQUEST_UPDATE(orgId, machineId), { mandatory });
|
|
1559
1576
|
}
|
|
1560
|
-
|
|
1561
|
-
|
|
1577
|
+
/** @deprecated Retired server-side (daemon-control-authorization §4.2):
|
|
1578
|
+
* remote filesystem browse of a member's machine was remote device access.
|
|
1579
|
+
* The endpoint now answers 409 LOCAL_BROWSE_NOT_SUPPORTED unconditionally;
|
|
1580
|
+
* workspace paths are typed in (or picked on the machine's own Desktop). */
|
|
1581
|
+
async browseMachineFilesystem(orgId, machineId, path23) {
|
|
1582
|
+
return this.request("POST", ENDPOINTS.MACHINE_BROWSE(orgId, machineId), { path: path23 }, void 0, false, { timeoutMs: 15e3 });
|
|
1562
1583
|
}
|
|
1563
1584
|
/** Create a new machine key. Returns the raw key string (shown once) + metadata. */
|
|
1564
1585
|
async createMachineKey(orgId, machineId, name) {
|
|
@@ -1581,6 +1602,14 @@ var init_client = __esm({
|
|
|
1581
1602
|
async getThreadUnread(orgId, chatId, threadRootId) {
|
|
1582
1603
|
return this.request("GET", ENDPOINTS.THREAD_UNREAD(orgId, chatId, threadRootId));
|
|
1583
1604
|
}
|
|
1605
|
+
/** Advance the per-thread read cursor (forward-only). The server auto-clears
|
|
1606
|
+
* thread-scoped inbox items (thread_reply + in-thread mentions) the cursor
|
|
1607
|
+
* now covers. */
|
|
1608
|
+
async markThreadRead(orgId, chatId, threadRootId, messageId) {
|
|
1609
|
+
return this.request("POST", ENDPOINTS.THREAD_READ(orgId, chatId, threadRootId), {
|
|
1610
|
+
message_id: messageId
|
|
1611
|
+
});
|
|
1612
|
+
}
|
|
1584
1613
|
// ---- Inbox ----
|
|
1585
1614
|
async getInbox(orgId, params) {
|
|
1586
1615
|
return this.request("GET", ENDPOINTS.INBOX(orgId), void 0, params);
|
|
@@ -1604,9 +1633,12 @@ var init_client = __esm({
|
|
|
1604
1633
|
async archiveAllInbox(orgId) {
|
|
1605
1634
|
return this.request("POST", ENDPOINTS.INBOX_ARCHIVE_ALL(orgId));
|
|
1606
1635
|
}
|
|
1607
|
-
/** Mark
|
|
1608
|
-
|
|
1609
|
-
|
|
1636
|
+
/** Mark inbox items as read by their source (source_type + source_id) or by
|
|
1637
|
+
* group_key, rather than by inbox item ID. The group_key form clears a whole
|
|
1638
|
+
* group at once (e.g. `task:{taskId}` — task_assign/task_update/task_comment
|
|
1639
|
+
* share it), used by the task detail view's auto-ack on open. */
|
|
1640
|
+
async ackInbox(orgId, target) {
|
|
1641
|
+
return this.request("POST", ENDPOINTS.INBOX_ACK(orgId), target);
|
|
1610
1642
|
}
|
|
1611
1643
|
async deleteInboxItem(orgId, id) {
|
|
1612
1644
|
return this.request("DELETE", ENDPOINTS.INBOX_ITEM(orgId, id));
|
|
@@ -1888,6 +1920,15 @@ var init_client = __esm({
|
|
|
1888
1920
|
async initiateChannelProvisioning(orgId, input) {
|
|
1889
1921
|
return this.request("POST", ENDPOINTS.CHANNEL_PROVISIONING(orgId), input);
|
|
1890
1922
|
}
|
|
1923
|
+
/**
|
|
1924
|
+
* Mint a pending slack connection + api.slack.com manifest-prefill link
|
|
1925
|
+
* (guided manual path). Activate the returned connection_id with
|
|
1926
|
+
* deliverChannelCredentials once the user brings back the bot token +
|
|
1927
|
+
* signing secret.
|
|
1928
|
+
*/
|
|
1929
|
+
async createSlackManifestLink(orgId, input) {
|
|
1930
|
+
return this.request("POST", ENDPOINTS.CHANNEL_SLACK_MANIFEST_LINK(orgId), input);
|
|
1931
|
+
}
|
|
1891
1932
|
/**
|
|
1892
1933
|
* Lazy status poll — server-side this may forward one provider poll, so
|
|
1893
1934
|
* call it at the session's `poll_interval_seconds` cadence, not faster.
|
|
@@ -1906,6 +1947,38 @@ var init_client = __esm({
|
|
|
1906
1947
|
async sendChannelMessage(orgId, input) {
|
|
1907
1948
|
return this.request("POST", ENDPOINTS.CHANNEL_SEND(orgId), input);
|
|
1908
1949
|
}
|
|
1950
|
+
slackReadQuery(base, query, extra) {
|
|
1951
|
+
const params = new URLSearchParams();
|
|
1952
|
+
if (query?.cursor)
|
|
1953
|
+
params.set("cursor", query.cursor);
|
|
1954
|
+
if (query?.limit)
|
|
1955
|
+
params.set("limit", String(query.limit));
|
|
1956
|
+
for (const [k, v] of Object.entries(extra ?? {}))
|
|
1957
|
+
params.set(k, v);
|
|
1958
|
+
const qs = params.toString();
|
|
1959
|
+
return qs ? `${base}?${qs}` : base;
|
|
1960
|
+
}
|
|
1961
|
+
/**
|
|
1962
|
+
* Tier-B read verbs (agent-only): workspace visibility as the bot sees
|
|
1963
|
+
* it. Same live gate as the send verb; authorization beyond it is the
|
|
1964
|
+
* bot's own Slack permissions.
|
|
1965
|
+
*/
|
|
1966
|
+
async listSlackChannels(orgId, query) {
|
|
1967
|
+
return this.request("GET", this.slackReadQuery(ENDPOINTS.SLACK_CHANNELS(orgId), query));
|
|
1968
|
+
}
|
|
1969
|
+
async listSlackUsers(orgId, query) {
|
|
1970
|
+
return this.request("GET", this.slackReadQuery(ENDPOINTS.SLACK_USERS(orgId), query));
|
|
1971
|
+
}
|
|
1972
|
+
async slackHistory(orgId, conversationId, query) {
|
|
1973
|
+
return this.request("GET", this.slackReadQuery(ENDPOINTS.SLACK_HISTORY(orgId), query, { conversation: conversationId }));
|
|
1974
|
+
}
|
|
1975
|
+
async slackMembers(orgId, conversationId, query) {
|
|
1976
|
+
return this.request("GET", this.slackReadQuery(ENDPOINTS.SLACK_MEMBERS(orgId), query, { conversation: conversationId }));
|
|
1977
|
+
}
|
|
1978
|
+
/** Set/clear the Agents-pane "typing…" indicator (best-effort cosmetic). */
|
|
1979
|
+
async setSlackStatus(orgId, input) {
|
|
1980
|
+
await this.request("POST", ENDPOINTS.SLACK_STATUS(orgId), input);
|
|
1981
|
+
}
|
|
1909
1982
|
async listChannelConversations(orgId, connectionId) {
|
|
1910
1983
|
return this.request("GET", ENDPOINTS.CHANNEL_CONNECTION_CONVERSATIONS(orgId, connectionId));
|
|
1911
1984
|
}
|
|
@@ -2141,8 +2214,8 @@ var init_client = __esm({
|
|
|
2141
2214
|
async deleteWikiRestriction(orgId, wikiId, restrictionId) {
|
|
2142
2215
|
await this.request("DELETE", ENDPOINTS.WIKI_RESTRICTION(orgId, wikiId, restrictionId));
|
|
2143
2216
|
}
|
|
2144
|
-
async getWikiAccessStatus(orgId, wikiId,
|
|
2145
|
-
return this.request("GET", ENDPOINTS.WIKI_ACCESS_STATUS(orgId, wikiId), void 0,
|
|
2217
|
+
async getWikiAccessStatus(orgId, wikiId, path23) {
|
|
2218
|
+
return this.request("GET", ENDPOINTS.WIKI_ACCESS_STATUS(orgId, wikiId), void 0, path23 ? { path: path23 } : void 0);
|
|
2146
2219
|
}
|
|
2147
2220
|
async createWikiAccessRequest(orgId, wikiId, data) {
|
|
2148
2221
|
await this.request("POST", ENDPOINTS.WIKI_ACCESS_REQUESTS(orgId, wikiId), data);
|
|
@@ -2151,14 +2224,14 @@ var init_client = __esm({
|
|
|
2151
2224
|
async getWikiCommits(orgId, wikiId, params) {
|
|
2152
2225
|
return this.request("GET", ENDPOINTS.WIKI_COMMITS(orgId, wikiId), void 0, params);
|
|
2153
2226
|
}
|
|
2154
|
-
async getWikiFileCommits(orgId, wikiId,
|
|
2227
|
+
async getWikiFileCommits(orgId, wikiId, path23, params) {
|
|
2155
2228
|
return this.request("GET", ENDPOINTS.WIKI_FILE_COMMITS(orgId, wikiId), void 0, {
|
|
2156
|
-
path:
|
|
2229
|
+
path: path23,
|
|
2157
2230
|
...params
|
|
2158
2231
|
});
|
|
2159
2232
|
}
|
|
2160
|
-
async getWikiBlame(orgId, wikiId,
|
|
2161
|
-
return this.request("GET", ENDPOINTS.WIKI_BLAME(orgId, wikiId), void 0, { path:
|
|
2233
|
+
async getWikiBlame(orgId, wikiId, path23, ref) {
|
|
2234
|
+
return this.request("GET", ENDPOINTS.WIKI_BLAME(orgId, wikiId), void 0, { path: path23, ref });
|
|
2162
2235
|
}
|
|
2163
2236
|
// ---- Wiki Operations (audit log) ----
|
|
2164
2237
|
async getWikiOperations(orgId, wikiId, params) {
|
|
@@ -2410,6 +2483,31 @@ var init_client = __esm({
|
|
|
2410
2483
|
const resp = await this.request("GET", url);
|
|
2411
2484
|
return resp.data;
|
|
2412
2485
|
}
|
|
2486
|
+
// ---- Clip registry (v3, api-server org registry — `crg_` entries) ----
|
|
2487
|
+
/**
|
|
2488
|
+
* List registry clips visible to the org: its own plus public+approved
|
|
2489
|
+
* cross-org entries. This is the surface `installRegistryClip` and clip
|
|
2490
|
+
* connections operate on — NOT the Pinix catalog proxy
|
|
2491
|
+
* ({@link listRegistryClips}), whose entries carry no `crg_` id.
|
|
2492
|
+
*/
|
|
2493
|
+
async listOrgRegistryClips(orgId) {
|
|
2494
|
+
const resp = await this.request("GET", `${ENDPOINTS.ORG_CLIP_REGISTRY(orgId)}?limit=100`);
|
|
2495
|
+
return resp ?? [];
|
|
2496
|
+
}
|
|
2497
|
+
/**
|
|
2498
|
+
* Install a registry clip into the org (a reference in `clip_installs`, not a
|
|
2499
|
+
* copy). Idempotent: installing an already-installed clip returns the same
|
|
2500
|
+
* `200 {ok:true}`. Fails closed with `403 CLIP_NOT_APPROVED` when the clip is
|
|
2501
|
+
* not eligible (cross-org requires public + approved).
|
|
2502
|
+
*/
|
|
2503
|
+
async installRegistryClip(orgId, clipId) {
|
|
2504
|
+
return this.request("POST", ENDPOINTS.ORG_CLIP_INSTALL(orgId), { clip_id: clipId });
|
|
2505
|
+
}
|
|
2506
|
+
/** List the org's installed registry clips (full entries). */
|
|
2507
|
+
async listInstalledRegistryClips(orgId) {
|
|
2508
|
+
const resp = await this.request("GET", ENDPOINTS.ORG_CLIPS_INSTALLED(orgId));
|
|
2509
|
+
return resp ?? [];
|
|
2510
|
+
}
|
|
2413
2511
|
// ---- Edge devices ----
|
|
2414
2512
|
async listEdgeDevices(orgId) {
|
|
2415
2513
|
return this.request("GET", ENDPOINTS.ORG_EDGE_DEVICES(orgId));
|
|
@@ -2427,8 +2525,8 @@ var init_client = __esm({
|
|
|
2427
2525
|
return this.request("POST", ENDPOINTS.ORG_EDGE(orgId), input);
|
|
2428
2526
|
}
|
|
2429
2527
|
/**
|
|
2430
|
-
* Delete a hosted Cloud Profile. Hosted only —
|
|
2431
|
-
*
|
|
2528
|
+
* Delete a hosted Cloud Profile. Hosted only — use {@link unregisterEdgeDevice}
|
|
2529
|
+
* for an offline BYOC registration (`400 EDGE_PLACEMENT_UNSUPPORTED` here).
|
|
2432
2530
|
*
|
|
2433
2531
|
* Idempotent and ASYNC: returns `202` with `hosted_state: 'deleting'` on the first
|
|
2434
2532
|
* call and on every repeat. The device stops being usable immediately (no exec, no
|
|
@@ -2438,12 +2536,68 @@ var init_client = __esm({
|
|
|
2438
2536
|
async deleteEdgeDevice(orgId, edgeId) {
|
|
2439
2537
|
return this.request("DELETE", ENDPOINTS.ORG_EDGE_DEVICE(orgId, edgeId));
|
|
2440
2538
|
}
|
|
2539
|
+
/**
|
|
2540
|
+
* Remove the interactive human caller's own offline BYOC registration.
|
|
2541
|
+
*
|
|
2542
|
+
* Synchronous and idempotent: a committed removal and a repeat after removal
|
|
2543
|
+
* both resolve with no response body. A live connection returns `EDGE_ONLINE`;
|
|
2544
|
+
* callers must not clear local device identity until this method resolves.
|
|
2545
|
+
*/
|
|
2546
|
+
async unregisterEdgeDevice(orgId, edgeId) {
|
|
2547
|
+
await this.request("DELETE", ENDPOINTS.ORG_EDGE_DEVICE_UNREGISTER(orgId, edgeId));
|
|
2548
|
+
}
|
|
2441
2549
|
async getEdgeOnboarding(orgId) {
|
|
2442
2550
|
return this.request("GET", ENDPOINTS.ORG_EDGE_ONBOARDING(orgId));
|
|
2443
2551
|
}
|
|
2444
2552
|
async listEdgeProfiles(orgId, edgeId) {
|
|
2445
2553
|
return this.request("GET", ENDPOINTS.ORG_EDGE_PROFILES(orgId, edgeId));
|
|
2446
2554
|
}
|
|
2555
|
+
/**
|
|
2556
|
+
* Execute a registry clip command on an Edge device.
|
|
2557
|
+
*
|
|
2558
|
+
* A hosted (Cloud Profile) device is reachable ONLY through an explicit
|
|
2559
|
+
* `connection` (id `ccn_…` or alias) — there is no implicit route to an
|
|
2560
|
+
* org-shared browser login. BYOC keeps its legacy selectors (`edge_id`, or
|
|
2561
|
+
* nothing for the caller's own online device).
|
|
2562
|
+
*
|
|
2563
|
+
* Returns the result envelope on completion (`success` may be false when the
|
|
2564
|
+
* command RAN and failed — `error`/`error_code` describe why). Everything
|
|
2565
|
+
* else throws a typed {@link ApiError}; match on `err.code`:
|
|
2566
|
+
*
|
|
2567
|
+
* Safe to retry (guaranteed nothing was dispatched):
|
|
2568
|
+
* - `EDGE_ACTIVATING` 503 + `Retry-After` — cold cloud profile is starting.
|
|
2569
|
+
* Bounded backoff, same `correlation_id` across the loop.
|
|
2570
|
+
* - `EDGE_BUSY` 409 — the device is executing another request.
|
|
2571
|
+
* - `EDGE_CONCURRENCY_LIMIT` 429 — org at its concurrent-session limit.
|
|
2572
|
+
* - `EDGE_UNAVAILABLE` 503 — session torn down / replaced mid-dispatch.
|
|
2573
|
+
*
|
|
2574
|
+
* NOT retryable:
|
|
2575
|
+
* - `OUTCOME_UNKNOWN` 504 — dispatched, but no result arrived. The command
|
|
2576
|
+
* MAY HAVE EXECUTED (posted, ordered, deleted…). Never retry
|
|
2577
|
+
* automatically: verify the effect first, then decide. The message carries
|
|
2578
|
+
* the request id for audit.
|
|
2579
|
+
* - `EDGE_DEADLINE_EXCEEDED` 504 — arrived late, provably NOT executed.
|
|
2580
|
+
* - `EDGE_HOSTED_DISABLED_FOR_ORG` 403, `EDGE_REPAIR` 503 (operator-held),
|
|
2581
|
+
* `EDGE_RUNTIME_UNAVAILABLE` 503 (deployment has no hosted runtime).
|
|
2582
|
+
* - Routing errors: `HOSTED_CONNECTION_REQUIRED`, `CONNECTION_NOT_FOUND`,
|
|
2583
|
+
* `CONNECTION_CLIP_MISMATCH`, `CONNECTION_TARGET_GONE`,
|
|
2584
|
+
* `CONNECTION_PROFILE_MISMATCH`, `EDGE_DELETING`, `DEVICE_OFFLINE`.
|
|
2585
|
+
*/
|
|
2586
|
+
async execEdgeClip(orgId, req) {
|
|
2587
|
+
const t = req.timeout;
|
|
2588
|
+
const serverTimeout = t !== void 0 && t > 0 && t <= 12e4 ? t : 3e4;
|
|
2589
|
+
const timeoutMs = serverTimeout + 1e4;
|
|
2590
|
+
try {
|
|
2591
|
+
return await this.request("POST", ENDPOINTS.ORG_EDGE_EXEC(orgId), req, void 0, false, {
|
|
2592
|
+
timeoutMs
|
|
2593
|
+
});
|
|
2594
|
+
} catch (err) {
|
|
2595
|
+
if (err instanceof ApiError && err.status === 422 && !err.code && typeof err.extras?.error_code === "string") {
|
|
2596
|
+
err.code = err.extras.error_code;
|
|
2597
|
+
}
|
|
2598
|
+
throw err;
|
|
2599
|
+
}
|
|
2600
|
+
}
|
|
2447
2601
|
// ---- Clip connections ----
|
|
2448
2602
|
async listClipConnections(orgId, clipId) {
|
|
2449
2603
|
return this.request("GET", ENDPOINTS.CLIP_CONNECTIONS(orgId, clipId));
|
|
@@ -20619,9 +20773,9 @@ var require_getMachineId_linux = __commonJS({
|
|
|
20619
20773
|
var api_1 = (init_esm(), __toCommonJS(esm_exports));
|
|
20620
20774
|
async function getMachineId() {
|
|
20621
20775
|
const paths = ["/etc/machine-id", "/var/lib/dbus/machine-id"];
|
|
20622
|
-
for (const
|
|
20776
|
+
for (const path23 of paths) {
|
|
20623
20777
|
try {
|
|
20624
|
-
const result = await fs_1.promises.readFile(
|
|
20778
|
+
const result = await fs_1.promises.readFile(path23, { encoding: "utf8" });
|
|
20625
20779
|
return result.trim();
|
|
20626
20780
|
} catch (e) {
|
|
20627
20781
|
api_1.diag.debug(`error reading machine id: ${e}`);
|
|
@@ -24024,7 +24178,7 @@ function appendRootPathToUrlIfNeeded(url) {
|
|
|
24024
24178
|
return void 0;
|
|
24025
24179
|
}
|
|
24026
24180
|
}
|
|
24027
|
-
function appendResourcePathToUrl(url,
|
|
24181
|
+
function appendResourcePathToUrl(url, path23) {
|
|
24028
24182
|
try {
|
|
24029
24183
|
new URL(url);
|
|
24030
24184
|
} catch (_a) {
|
|
@@ -24034,11 +24188,11 @@ function appendResourcePathToUrl(url, path22) {
|
|
|
24034
24188
|
if (!url.endsWith("/")) {
|
|
24035
24189
|
url = url + "/";
|
|
24036
24190
|
}
|
|
24037
|
-
url +=
|
|
24191
|
+
url += path23;
|
|
24038
24192
|
try {
|
|
24039
24193
|
new URL(url);
|
|
24040
24194
|
} catch (_b) {
|
|
24041
|
-
diag2.warn("Configuration: Provided URL appended with '" +
|
|
24195
|
+
diag2.warn("Configuration: Provided URL appended with '" + path23 + "' is not a valid URL, using 'undefined' instead of '" + url + "'");
|
|
24042
24196
|
return void 0;
|
|
24043
24197
|
}
|
|
24044
24198
|
return url;
|
|
@@ -30492,7 +30646,7 @@ var require_util2 = __commonJS({
|
|
|
30492
30646
|
var { kDestroyed, kBodyUsed, kListeners, kBody } = require_symbols();
|
|
30493
30647
|
var { IncomingMessage } = __require("node:http");
|
|
30494
30648
|
var stream = __require("node:stream");
|
|
30495
|
-
var
|
|
30649
|
+
var net3 = __require("node:net");
|
|
30496
30650
|
var { stringify } = __require("node:querystring");
|
|
30497
30651
|
var { EventEmitter: EE } = __require("node:events");
|
|
30498
30652
|
var timers = require_timers();
|
|
@@ -30604,14 +30758,14 @@ var require_util2 = __commonJS({
|
|
|
30604
30758
|
}
|
|
30605
30759
|
const port = url.port != null ? url.port : url.protocol === "https:" ? 443 : 80;
|
|
30606
30760
|
let origin = url.origin != null ? url.origin : `${url.protocol || ""}//${url.hostname || ""}:${port}`;
|
|
30607
|
-
let
|
|
30761
|
+
let path23 = url.path != null ? url.path : `${url.pathname || ""}${url.search || ""}`;
|
|
30608
30762
|
if (origin[origin.length - 1] === "/") {
|
|
30609
30763
|
origin = origin.slice(0, origin.length - 1);
|
|
30610
30764
|
}
|
|
30611
|
-
if (
|
|
30612
|
-
|
|
30765
|
+
if (path23 && path23[0] !== "/") {
|
|
30766
|
+
path23 = `/${path23}`;
|
|
30613
30767
|
}
|
|
30614
|
-
return new URL(`${origin}${
|
|
30768
|
+
return new URL(`${origin}${path23}`);
|
|
30615
30769
|
}
|
|
30616
30770
|
if (!isHttpOrHttpsPrefixed(url.origin || url.protocol)) {
|
|
30617
30771
|
throw new InvalidArgumentError("Invalid URL protocol: the URL must start with `http:` or `https:`.");
|
|
@@ -30641,7 +30795,7 @@ var require_util2 = __commonJS({
|
|
|
30641
30795
|
}
|
|
30642
30796
|
assert(typeof host === "string");
|
|
30643
30797
|
const servername = getHostname(host);
|
|
30644
|
-
if (
|
|
30798
|
+
if (net3.isIP(servername)) {
|
|
30645
30799
|
return "";
|
|
30646
30800
|
}
|
|
30647
30801
|
return servername;
|
|
@@ -31432,9 +31586,9 @@ var require_diagnostics = __commonJS({
|
|
|
31432
31586
|
"undici:client:sendHeaders",
|
|
31433
31587
|
(evt) => {
|
|
31434
31588
|
const {
|
|
31435
|
-
request: { method, path:
|
|
31589
|
+
request: { method, path: path23, origin }
|
|
31436
31590
|
} = evt;
|
|
31437
|
-
debugLog("sending request to %s %s%s", method, origin,
|
|
31591
|
+
debugLog("sending request to %s %s%s", method, origin, path23);
|
|
31438
31592
|
}
|
|
31439
31593
|
);
|
|
31440
31594
|
}
|
|
@@ -31452,14 +31606,14 @@ var require_diagnostics = __commonJS({
|
|
|
31452
31606
|
"undici:request:headers",
|
|
31453
31607
|
(evt) => {
|
|
31454
31608
|
const {
|
|
31455
|
-
request: { method, path:
|
|
31609
|
+
request: { method, path: path23, origin },
|
|
31456
31610
|
response: { statusCode }
|
|
31457
31611
|
} = evt;
|
|
31458
31612
|
debugLog(
|
|
31459
31613
|
"received response to %s %s%s - HTTP %d",
|
|
31460
31614
|
method,
|
|
31461
31615
|
origin,
|
|
31462
|
-
|
|
31616
|
+
path23,
|
|
31463
31617
|
statusCode
|
|
31464
31618
|
);
|
|
31465
31619
|
}
|
|
@@ -31468,23 +31622,23 @@ var require_diagnostics = __commonJS({
|
|
|
31468
31622
|
"undici:request:trailers",
|
|
31469
31623
|
(evt) => {
|
|
31470
31624
|
const {
|
|
31471
|
-
request: { method, path:
|
|
31625
|
+
request: { method, path: path23, origin }
|
|
31472
31626
|
} = evt;
|
|
31473
|
-
debugLog("trailers received from %s %s%s", method, origin,
|
|
31627
|
+
debugLog("trailers received from %s %s%s", method, origin, path23);
|
|
31474
31628
|
}
|
|
31475
31629
|
);
|
|
31476
31630
|
diagnosticsChannel.subscribe(
|
|
31477
31631
|
"undici:request:error",
|
|
31478
31632
|
(evt) => {
|
|
31479
31633
|
const {
|
|
31480
|
-
request: { method, path:
|
|
31634
|
+
request: { method, path: path23, origin },
|
|
31481
31635
|
error
|
|
31482
31636
|
} = evt;
|
|
31483
31637
|
debugLog(
|
|
31484
31638
|
"request to %s %s%s errored - %s",
|
|
31485
31639
|
method,
|
|
31486
31640
|
origin,
|
|
31487
|
-
|
|
31641
|
+
path23,
|
|
31488
31642
|
error.message
|
|
31489
31643
|
);
|
|
31490
31644
|
}
|
|
@@ -31587,7 +31741,7 @@ var require_request = __commonJS({
|
|
|
31587
31741
|
var kHandler = Symbol("handler");
|
|
31588
31742
|
var Request = class {
|
|
31589
31743
|
constructor(origin, {
|
|
31590
|
-
path:
|
|
31744
|
+
path: path23,
|
|
31591
31745
|
method,
|
|
31592
31746
|
body,
|
|
31593
31747
|
headers,
|
|
@@ -31604,11 +31758,11 @@ var require_request = __commonJS({
|
|
|
31604
31758
|
maxRedirections,
|
|
31605
31759
|
typeOfService
|
|
31606
31760
|
}, handler) {
|
|
31607
|
-
if (typeof
|
|
31761
|
+
if (typeof path23 !== "string") {
|
|
31608
31762
|
throw new InvalidArgumentError("path must be a string");
|
|
31609
|
-
} else if (
|
|
31763
|
+
} else if (path23[0] !== "/" && !(path23.startsWith("http://") || path23.startsWith("https://")) && method !== "CONNECT") {
|
|
31610
31764
|
throw new InvalidArgumentError("path must be an absolute URL or start with a slash");
|
|
31611
|
-
} else if (invalidPathRegex.test(
|
|
31765
|
+
} else if (invalidPathRegex.test(path23)) {
|
|
31612
31766
|
throw new InvalidArgumentError("invalid request path");
|
|
31613
31767
|
}
|
|
31614
31768
|
if (typeof method !== "string") {
|
|
@@ -31683,7 +31837,7 @@ var require_request = __commonJS({
|
|
|
31683
31837
|
this.completed = false;
|
|
31684
31838
|
this.aborted = false;
|
|
31685
31839
|
this.upgrade = upgrade || null;
|
|
31686
|
-
this.path = query ? serializePathWithQuery(
|
|
31840
|
+
this.path = query ? serializePathWithQuery(path23, query) : path23;
|
|
31687
31841
|
this.origin = origin;
|
|
31688
31842
|
this.protocol = getProtocolFromUrlString(origin);
|
|
31689
31843
|
this.idempotent = idempotent == null ? method === "HEAD" || method === "GET" : idempotent;
|
|
@@ -32262,7 +32416,7 @@ var require_dispatcher_base = __commonJS({
|
|
|
32262
32416
|
var require_connect = __commonJS({
|
|
32263
32417
|
"ts/node_modules/.pnpm/undici@7.24.8/node_modules/undici/lib/core/connect.js"(exports2, module2) {
|
|
32264
32418
|
"use strict";
|
|
32265
|
-
var
|
|
32419
|
+
var net3 = __require("node:net");
|
|
32266
32420
|
var assert = __require("node:assert");
|
|
32267
32421
|
var util = require_util2();
|
|
32268
32422
|
var { InvalidArgumentError } = require_errors();
|
|
@@ -32301,7 +32455,7 @@ var require_connect = __commonJS({
|
|
|
32301
32455
|
const sessionCache = new SessionCache(maxCachedSessions == null ? 100 : maxCachedSessions);
|
|
32302
32456
|
timeout = timeout == null ? 1e4 : timeout;
|
|
32303
32457
|
allowH2 = allowH2 != null ? allowH2 : false;
|
|
32304
|
-
return function
|
|
32458
|
+
return function connect4({ hostname, host, protocol, port, servername, localAddress, httpSocket }, callback) {
|
|
32305
32459
|
let socket;
|
|
32306
32460
|
if (protocol === "https:") {
|
|
32307
32461
|
if (!tls) {
|
|
@@ -32331,7 +32485,7 @@ var require_connect = __commonJS({
|
|
|
32331
32485
|
} else {
|
|
32332
32486
|
assert(!httpSocket, "httpSocket can only be sent on TLS update");
|
|
32333
32487
|
port = port || 80;
|
|
32334
|
-
socket =
|
|
32488
|
+
socket = net3.connect({
|
|
32335
32489
|
highWaterMark: 64 * 1024,
|
|
32336
32490
|
// Same as nodejs fs streams.
|
|
32337
32491
|
...options,
|
|
@@ -36722,7 +36876,7 @@ var require_client_h1 = __commonJS({
|
|
|
36722
36876
|
return method !== "GET" && method !== "HEAD" && method !== "OPTIONS" && method !== "TRACE" && method !== "CONNECT";
|
|
36723
36877
|
}
|
|
36724
36878
|
function writeH1(client, request3) {
|
|
36725
|
-
const { method, path:
|
|
36879
|
+
const { method, path: path23, host, upgrade, blocking, reset } = request3;
|
|
36726
36880
|
let { body, headers, contentLength } = request3;
|
|
36727
36881
|
const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH" || method === "QUERY" || method === "PROPFIND" || method === "PROPPATCH";
|
|
36728
36882
|
if (util.isFormDataLike(body)) {
|
|
@@ -36791,7 +36945,7 @@ var require_client_h1 = __commonJS({
|
|
|
36791
36945
|
if (socket.setTypeOfService) {
|
|
36792
36946
|
socket.setTypeOfService(request3.typeOfService);
|
|
36793
36947
|
}
|
|
36794
|
-
let header = `${method} ${
|
|
36948
|
+
let header = `${method} ${path23} HTTP/1.1\r
|
|
36795
36949
|
`;
|
|
36796
36950
|
if (typeof host === "string") {
|
|
36797
36951
|
header += `host: ${host}\r
|
|
@@ -37444,7 +37598,7 @@ var require_client_h2 = __commonJS({
|
|
|
37444
37598
|
function writeH2(client, request3) {
|
|
37445
37599
|
const requestTimeout = request3.bodyTimeout ?? client[kBodyTimeout];
|
|
37446
37600
|
const session = client[kHTTP2Session];
|
|
37447
|
-
const { method, path:
|
|
37601
|
+
const { method, path: path23, host, upgrade, expectContinue, signal, protocol, headers: reqHeaders } = request3;
|
|
37448
37602
|
let { body } = request3;
|
|
37449
37603
|
if (upgrade != null && upgrade !== "websocket") {
|
|
37450
37604
|
util.errorRequest(client, request3, new InvalidArgumentError(`Custom upgrade "${upgrade}" not supported over HTTP/2`));
|
|
@@ -37512,7 +37666,7 @@ var require_client_h2 = __commonJS({
|
|
|
37512
37666
|
}
|
|
37513
37667
|
headers[HTTP2_HEADER_METHOD] = "CONNECT";
|
|
37514
37668
|
headers[HTTP2_HEADER_PROTOCOL] = "websocket";
|
|
37515
|
-
headers[HTTP2_HEADER_PATH] =
|
|
37669
|
+
headers[HTTP2_HEADER_PATH] = path23;
|
|
37516
37670
|
if (protocol === "ws:" || protocol === "wss:") {
|
|
37517
37671
|
headers[HTTP2_HEADER_SCHEME] = protocol === "ws:" ? "http" : "https";
|
|
37518
37672
|
} else {
|
|
@@ -37553,7 +37707,7 @@ var require_client_h2 = __commonJS({
|
|
|
37553
37707
|
stream.setTimeout(requestTimeout);
|
|
37554
37708
|
return true;
|
|
37555
37709
|
}
|
|
37556
|
-
headers[HTTP2_HEADER_PATH] =
|
|
37710
|
+
headers[HTTP2_HEADER_PATH] = path23;
|
|
37557
37711
|
headers[HTTP2_HEADER_SCHEME] = protocol === "http:" ? "http" : "https";
|
|
37558
37712
|
const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH";
|
|
37559
37713
|
if (body && typeof body.read === "function") {
|
|
@@ -37869,7 +38023,7 @@ var require_client = __commonJS({
|
|
|
37869
38023
|
"ts/node_modules/.pnpm/undici@7.24.8/node_modules/undici/lib/dispatcher/client.js"(exports2, module2) {
|
|
37870
38024
|
"use strict";
|
|
37871
38025
|
var assert = __require("node:assert");
|
|
37872
|
-
var
|
|
38026
|
+
var net3 = __require("node:net");
|
|
37873
38027
|
var http3 = __require("node:http");
|
|
37874
38028
|
var util = require_util2();
|
|
37875
38029
|
var { ClientStats } = require_stats();
|
|
@@ -37960,7 +38114,7 @@ var require_client = __commonJS({
|
|
|
37960
38114
|
tls,
|
|
37961
38115
|
strictContentLength,
|
|
37962
38116
|
maxCachedSessions,
|
|
37963
|
-
connect:
|
|
38117
|
+
connect: connect5,
|
|
37964
38118
|
maxRequestsPerClient,
|
|
37965
38119
|
localAddress,
|
|
37966
38120
|
maxResponseSize,
|
|
@@ -38017,13 +38171,13 @@ var require_client = __commonJS({
|
|
|
38017
38171
|
if (bodyTimeout != null && (!Number.isInteger(bodyTimeout) || bodyTimeout < 0)) {
|
|
38018
38172
|
throw new InvalidArgumentError("bodyTimeout must be a positive integer or zero");
|
|
38019
38173
|
}
|
|
38020
|
-
if (
|
|
38174
|
+
if (connect5 != null && typeof connect5 !== "function" && typeof connect5 !== "object") {
|
|
38021
38175
|
throw new InvalidArgumentError("connect must be a function or an object");
|
|
38022
38176
|
}
|
|
38023
38177
|
if (maxRequestsPerClient != null && (!Number.isInteger(maxRequestsPerClient) || maxRequestsPerClient < 0)) {
|
|
38024
38178
|
throw new InvalidArgumentError("maxRequestsPerClient must be a positive number");
|
|
38025
38179
|
}
|
|
38026
|
-
if (localAddress != null && (typeof localAddress !== "string" ||
|
|
38180
|
+
if (localAddress != null && (typeof localAddress !== "string" || net3.isIP(localAddress) === 0)) {
|
|
38027
38181
|
throw new InvalidArgumentError("localAddress must be valid string IP address");
|
|
38028
38182
|
}
|
|
38029
38183
|
if (maxResponseSize != null && (!Number.isInteger(maxResponseSize) || maxResponseSize < -1)) {
|
|
@@ -38051,8 +38205,8 @@ var require_client = __commonJS({
|
|
|
38051
38205
|
throw new InvalidArgumentError("pingInterval must be a positive integer, greater or equal to 0");
|
|
38052
38206
|
}
|
|
38053
38207
|
super();
|
|
38054
|
-
if (typeof
|
|
38055
|
-
|
|
38208
|
+
if (typeof connect5 !== "function") {
|
|
38209
|
+
connect5 = buildConnector({
|
|
38056
38210
|
...tls,
|
|
38057
38211
|
maxCachedSessions,
|
|
38058
38212
|
allowH2,
|
|
@@ -38060,14 +38214,14 @@ var require_client = __commonJS({
|
|
|
38060
38214
|
socketPath,
|
|
38061
38215
|
timeout: connectTimeout,
|
|
38062
38216
|
...typeof autoSelectFamily === "boolean" ? { autoSelectFamily, autoSelectFamilyAttemptTimeout } : void 0,
|
|
38063
|
-
...
|
|
38217
|
+
...connect5
|
|
38064
38218
|
});
|
|
38065
38219
|
} else if (socketPath != null) {
|
|
38066
|
-
const customConnect =
|
|
38067
|
-
|
|
38220
|
+
const customConnect = connect5;
|
|
38221
|
+
connect5 = (opts, callback) => customConnect({ ...opts, socketPath }, callback);
|
|
38068
38222
|
}
|
|
38069
38223
|
this[kUrl] = util.parseOrigin(url);
|
|
38070
|
-
this[kConnector] =
|
|
38224
|
+
this[kConnector] = connect5;
|
|
38071
38225
|
this[kPipelining] = pipelining != null ? pipelining : 1;
|
|
38072
38226
|
this[kMaxHeadersSize] = maxHeaderSize;
|
|
38073
38227
|
this[kKeepAliveDefaultTimeout] = keepAliveTimeout == null ? 4e3 : keepAliveTimeout;
|
|
@@ -38125,7 +38279,7 @@ var require_client = __commonJS({
|
|
|
38125
38279
|
);
|
|
38126
38280
|
}
|
|
38127
38281
|
[kConnect](cb) {
|
|
38128
|
-
|
|
38282
|
+
connect4(this);
|
|
38129
38283
|
this.once("connect", cb);
|
|
38130
38284
|
}
|
|
38131
38285
|
[kDispatch](opts, handler) {
|
|
@@ -38187,7 +38341,7 @@ var require_client = __commonJS({
|
|
|
38187
38341
|
assert(client[kSize] === 0);
|
|
38188
38342
|
}
|
|
38189
38343
|
}
|
|
38190
|
-
function
|
|
38344
|
+
function connect4(client) {
|
|
38191
38345
|
assert(!client[kConnecting]);
|
|
38192
38346
|
assert(!client[kHTTPContext]);
|
|
38193
38347
|
let { host, hostname, protocol, port } = client[kUrl];
|
|
@@ -38195,7 +38349,7 @@ var require_client = __commonJS({
|
|
|
38195
38349
|
const idx = hostname.indexOf("]");
|
|
38196
38350
|
assert(idx !== -1);
|
|
38197
38351
|
const ip = hostname.substring(1, idx);
|
|
38198
|
-
assert(
|
|
38352
|
+
assert(net3.isIPv6(ip));
|
|
38199
38353
|
hostname = ip;
|
|
38200
38354
|
}
|
|
38201
38355
|
client[kConnecting] = true;
|
|
@@ -38366,7 +38520,7 @@ var require_client = __commonJS({
|
|
|
38366
38520
|
return;
|
|
38367
38521
|
}
|
|
38368
38522
|
if (!client[kHTTPContext]) {
|
|
38369
|
-
|
|
38523
|
+
connect4(client);
|
|
38370
38524
|
return;
|
|
38371
38525
|
}
|
|
38372
38526
|
if (client[kHTTPContext].destroyed) {
|
|
@@ -38662,7 +38816,7 @@ var require_pool2 = __commonJS({
|
|
|
38662
38816
|
constructor(origin, {
|
|
38663
38817
|
connections,
|
|
38664
38818
|
factory = defaultFactory,
|
|
38665
|
-
connect:
|
|
38819
|
+
connect: connect4,
|
|
38666
38820
|
connectTimeout,
|
|
38667
38821
|
tls,
|
|
38668
38822
|
maxCachedSessions,
|
|
@@ -38679,24 +38833,24 @@ var require_pool2 = __commonJS({
|
|
|
38679
38833
|
if (typeof factory !== "function") {
|
|
38680
38834
|
throw new InvalidArgumentError("factory must be a function.");
|
|
38681
38835
|
}
|
|
38682
|
-
if (
|
|
38836
|
+
if (connect4 != null && typeof connect4 !== "function" && typeof connect4 !== "object") {
|
|
38683
38837
|
throw new InvalidArgumentError("connect must be a function or an object");
|
|
38684
38838
|
}
|
|
38685
|
-
if (typeof
|
|
38686
|
-
|
|
38839
|
+
if (typeof connect4 !== "function") {
|
|
38840
|
+
connect4 = buildConnector({
|
|
38687
38841
|
...tls,
|
|
38688
38842
|
maxCachedSessions,
|
|
38689
38843
|
allowH2,
|
|
38690
38844
|
socketPath,
|
|
38691
38845
|
timeout: connectTimeout,
|
|
38692
38846
|
...typeof autoSelectFamily === "boolean" ? { autoSelectFamily, autoSelectFamilyAttemptTimeout } : void 0,
|
|
38693
|
-
...
|
|
38847
|
+
...connect4
|
|
38694
38848
|
});
|
|
38695
38849
|
}
|
|
38696
38850
|
super();
|
|
38697
38851
|
this[kConnections] = connections || null;
|
|
38698
38852
|
this[kUrl] = util.parseOrigin(origin);
|
|
38699
|
-
this[kOptions] = { ...util.deepClone(options), connect:
|
|
38853
|
+
this[kOptions] = { ...util.deepClone(options), connect: connect4, allowH2, clientTtl, socketPath };
|
|
38700
38854
|
this[kOptions].interceptors = options.interceptors ? { ...options.interceptors } : void 0;
|
|
38701
38855
|
this[kFactory] = factory;
|
|
38702
38856
|
this.on("connect", (origin2, targets) => {
|
|
@@ -38913,7 +39067,7 @@ var require_round_robin_pool = __commonJS({
|
|
|
38913
39067
|
constructor(origin, {
|
|
38914
39068
|
connections,
|
|
38915
39069
|
factory = defaultFactory,
|
|
38916
|
-
connect:
|
|
39070
|
+
connect: connect4,
|
|
38917
39071
|
connectTimeout,
|
|
38918
39072
|
tls,
|
|
38919
39073
|
maxCachedSessions,
|
|
@@ -38930,24 +39084,24 @@ var require_round_robin_pool = __commonJS({
|
|
|
38930
39084
|
if (typeof factory !== "function") {
|
|
38931
39085
|
throw new InvalidArgumentError("factory must be a function.");
|
|
38932
39086
|
}
|
|
38933
|
-
if (
|
|
39087
|
+
if (connect4 != null && typeof connect4 !== "function" && typeof connect4 !== "object") {
|
|
38934
39088
|
throw new InvalidArgumentError("connect must be a function or an object");
|
|
38935
39089
|
}
|
|
38936
|
-
if (typeof
|
|
38937
|
-
|
|
39090
|
+
if (typeof connect4 !== "function") {
|
|
39091
|
+
connect4 = buildConnector({
|
|
38938
39092
|
...tls,
|
|
38939
39093
|
maxCachedSessions,
|
|
38940
39094
|
allowH2,
|
|
38941
39095
|
socketPath,
|
|
38942
39096
|
timeout: connectTimeout,
|
|
38943
39097
|
...typeof autoSelectFamily === "boolean" ? { autoSelectFamily, autoSelectFamilyAttemptTimeout } : void 0,
|
|
38944
|
-
...
|
|
39098
|
+
...connect4
|
|
38945
39099
|
});
|
|
38946
39100
|
}
|
|
38947
39101
|
super();
|
|
38948
39102
|
this[kConnections] = connections || null;
|
|
38949
39103
|
this[kUrl] = util.parseOrigin(origin);
|
|
38950
|
-
this[kOptions] = { ...util.deepClone(options), connect:
|
|
39104
|
+
this[kOptions] = { ...util.deepClone(options), connect: connect4, allowH2, clientTtl, socketPath };
|
|
38951
39105
|
this[kOptions].interceptors = options.interceptors ? { ...options.interceptors } : void 0;
|
|
38952
39106
|
this[kFactory] = factory;
|
|
38953
39107
|
this[kIndex] = -1;
|
|
@@ -39021,21 +39175,21 @@ var require_agent = __commonJS({
|
|
|
39021
39175
|
return opts && opts.connections === 1 ? new Client(origin, opts) : new Pool(origin, opts);
|
|
39022
39176
|
}
|
|
39023
39177
|
var Agent4 = class extends DispatcherBase {
|
|
39024
|
-
constructor({ factory = defaultFactory, maxOrigins = Infinity, connect:
|
|
39178
|
+
constructor({ factory = defaultFactory, maxOrigins = Infinity, connect: connect4, ...options } = {}) {
|
|
39025
39179
|
if (typeof factory !== "function") {
|
|
39026
39180
|
throw new InvalidArgumentError("factory must be a function.");
|
|
39027
39181
|
}
|
|
39028
|
-
if (
|
|
39182
|
+
if (connect4 != null && typeof connect4 !== "function" && typeof connect4 !== "object") {
|
|
39029
39183
|
throw new InvalidArgumentError("connect must be a function or an object");
|
|
39030
39184
|
}
|
|
39031
39185
|
if (typeof maxOrigins !== "number" || Number.isNaN(maxOrigins) || maxOrigins <= 0) {
|
|
39032
39186
|
throw new InvalidArgumentError("maxOrigins must be a number greater than 0");
|
|
39033
39187
|
}
|
|
39034
39188
|
super();
|
|
39035
|
-
if (
|
|
39036
|
-
|
|
39189
|
+
if (connect4 && typeof connect4 !== "function") {
|
|
39190
|
+
connect4 = { ...connect4 };
|
|
39037
39191
|
}
|
|
39038
|
-
this[kOptions] = { ...util.deepClone(options), maxOrigins, connect:
|
|
39192
|
+
this[kOptions] = { ...util.deepClone(options), maxOrigins, connect: connect4 };
|
|
39039
39193
|
this[kFactory] = factory;
|
|
39040
39194
|
this[kClients] = /* @__PURE__ */ new Map();
|
|
39041
39195
|
this[kOrigins] = /* @__PURE__ */ new Set();
|
|
@@ -39138,10 +39292,10 @@ var require_socks5_utils = __commonJS({
|
|
|
39138
39292
|
"ts/node_modules/.pnpm/undici@7.24.8/node_modules/undici/lib/core/socks5-utils.js"(exports2, module2) {
|
|
39139
39293
|
"use strict";
|
|
39140
39294
|
var { Buffer: Buffer2 } = __require("node:buffer");
|
|
39141
|
-
var
|
|
39295
|
+
var net3 = __require("node:net");
|
|
39142
39296
|
var { InvalidArgumentError } = require_errors();
|
|
39143
39297
|
function parseAddress(address) {
|
|
39144
|
-
if (
|
|
39298
|
+
if (net3.isIPv4(address)) {
|
|
39145
39299
|
const parts = address.split(".").map(Number);
|
|
39146
39300
|
return {
|
|
39147
39301
|
type: 1,
|
|
@@ -39149,7 +39303,7 @@ var require_socks5_utils = __commonJS({
|
|
|
39149
39303
|
buffer: Buffer2.from(parts)
|
|
39150
39304
|
};
|
|
39151
39305
|
}
|
|
39152
|
-
if (
|
|
39306
|
+
if (net3.isIPv6(address)) {
|
|
39153
39307
|
return {
|
|
39154
39308
|
type: 4,
|
|
39155
39309
|
// IPv6
|
|
@@ -39609,7 +39763,7 @@ var require_socks5_client = __commonJS({
|
|
|
39609
39763
|
var require_socks5_proxy_agent = __commonJS({
|
|
39610
39764
|
"ts/node_modules/.pnpm/undici@7.24.8/node_modules/undici/lib/dispatcher/socks5-proxy-agent.js"(exports2, module2) {
|
|
39611
39765
|
"use strict";
|
|
39612
|
-
var
|
|
39766
|
+
var net3 = __require("node:net");
|
|
39613
39767
|
var { URL: URL2 } = __require("node:url");
|
|
39614
39768
|
var tls;
|
|
39615
39769
|
var DispatcherBase = require_dispatcher_base();
|
|
@@ -39671,7 +39825,7 @@ var require_socks5_proxy_agent = __commonJS({
|
|
|
39671
39825
|
socket2.removeListener("connect", onConnect);
|
|
39672
39826
|
reject(err);
|
|
39673
39827
|
};
|
|
39674
|
-
const socket2 =
|
|
39828
|
+
const socket2 = net3.connect({
|
|
39675
39829
|
host: proxyHost,
|
|
39676
39830
|
port: proxyPort
|
|
39677
39831
|
});
|
|
@@ -39830,16 +39984,16 @@ var require_proxy_agent = __commonJS({
|
|
|
39830
39984
|
}
|
|
39831
39985
|
var Http1ProxyWrapper = class extends DispatcherBase {
|
|
39832
39986
|
#client;
|
|
39833
|
-
constructor(proxyUrl, { headers = {}, connect:
|
|
39987
|
+
constructor(proxyUrl, { headers = {}, connect: connect4, factory }) {
|
|
39834
39988
|
if (!proxyUrl) {
|
|
39835
39989
|
throw new InvalidArgumentError("Proxy URL is mandatory");
|
|
39836
39990
|
}
|
|
39837
39991
|
super();
|
|
39838
39992
|
this[kProxyHeaders] = headers;
|
|
39839
39993
|
if (factory) {
|
|
39840
|
-
this.#client = factory(proxyUrl, { connect:
|
|
39994
|
+
this.#client = factory(proxyUrl, { connect: connect4 });
|
|
39841
39995
|
} else {
|
|
39842
|
-
this.#client = new Client(proxyUrl, { connect:
|
|
39996
|
+
this.#client = new Client(proxyUrl, { connect: connect4 });
|
|
39843
39997
|
}
|
|
39844
39998
|
}
|
|
39845
39999
|
[kDispatch](opts, handler) {
|
|
@@ -39855,10 +40009,10 @@ var require_proxy_agent = __commonJS({
|
|
|
39855
40009
|
};
|
|
39856
40010
|
const {
|
|
39857
40011
|
origin,
|
|
39858
|
-
path:
|
|
40012
|
+
path: path23 = "/",
|
|
39859
40013
|
headers = {}
|
|
39860
40014
|
} = opts;
|
|
39861
|
-
opts.path = origin +
|
|
40015
|
+
opts.path = origin + path23;
|
|
39862
40016
|
if (!("host" in headers) && !("Host" in headers)) {
|
|
39863
40017
|
const { host } = new URL(origin);
|
|
39864
40018
|
headers.host = host;
|
|
@@ -39900,7 +40054,7 @@ var require_proxy_agent = __commonJS({
|
|
|
39900
40054
|
} else if (username && password) {
|
|
39901
40055
|
this[kProxyHeaders]["proxy-authorization"] = `Basic ${Buffer.from(`${decodeURIComponent(username)}:${decodeURIComponent(password)}`).toString("base64")}`;
|
|
39902
40056
|
}
|
|
39903
|
-
const
|
|
40057
|
+
const connect4 = buildConnector({ ...opts.proxyTls });
|
|
39904
40058
|
this[kConnectEndpoint] = buildConnector({ ...opts.requestTls });
|
|
39905
40059
|
const agentFactory = opts.factory || defaultAgentFactory;
|
|
39906
40060
|
const factory = (origin2, options) => {
|
|
@@ -39908,7 +40062,7 @@ var require_proxy_agent = __commonJS({
|
|
|
39908
40062
|
if (this[kProxy].protocol === "socks5:" || this[kProxy].protocol === "socks:") {
|
|
39909
40063
|
return new Socks5ProxyAgent(this[kProxy].uri, {
|
|
39910
40064
|
headers: this[kProxyHeaders],
|
|
39911
|
-
connect:
|
|
40065
|
+
connect: connect4,
|
|
39912
40066
|
factory: agentFactory,
|
|
39913
40067
|
username: opts.username || username,
|
|
39914
40068
|
password: opts.password || password,
|
|
@@ -39918,7 +40072,7 @@ var require_proxy_agent = __commonJS({
|
|
|
39918
40072
|
if (!this[kTunnelProxy] && protocol2 === "http:" && this[kProxy].protocol === "http:") {
|
|
39919
40073
|
return new Http1ProxyWrapper(this[kProxy].uri, {
|
|
39920
40074
|
headers: this[kProxyHeaders],
|
|
39921
|
-
connect:
|
|
40075
|
+
connect: connect4,
|
|
39922
40076
|
factory: agentFactory
|
|
39923
40077
|
});
|
|
39924
40078
|
}
|
|
@@ -39927,7 +40081,7 @@ var require_proxy_agent = __commonJS({
|
|
|
39927
40081
|
if (protocol === "socks5:" || protocol === "socks:") {
|
|
39928
40082
|
this[kClient] = null;
|
|
39929
40083
|
} else {
|
|
39930
|
-
this[kClient] = clientFactory(url, { connect:
|
|
40084
|
+
this[kClient] = clientFactory(url, { connect: connect4 });
|
|
39931
40085
|
}
|
|
39932
40086
|
this[kAgent] = new Agent4({
|
|
39933
40087
|
...opts,
|
|
@@ -40533,7 +40687,7 @@ var require_h2c_client = __commonJS({
|
|
|
40533
40687
|
"h2c-client: Only h2c protocol is supported"
|
|
40534
40688
|
);
|
|
40535
40689
|
}
|
|
40536
|
-
const { connect:
|
|
40690
|
+
const { connect: connect4, maxConcurrentStreams, pipelining, ...opts } = clientOpts ?? {};
|
|
40537
40691
|
let defaultMaxConcurrentStreams = 100;
|
|
40538
40692
|
let defaultPipelining = 100;
|
|
40539
40693
|
if (maxConcurrentStreams != null && Number.isInteger(maxConcurrentStreams) && maxConcurrentStreams > 0) {
|
|
@@ -41715,10 +41869,10 @@ var require_api_connect = __commonJS({
|
|
|
41715
41869
|
}
|
|
41716
41870
|
}
|
|
41717
41871
|
};
|
|
41718
|
-
function
|
|
41872
|
+
function connect4(opts, callback) {
|
|
41719
41873
|
if (callback === void 0) {
|
|
41720
41874
|
return new Promise((resolve9, reject) => {
|
|
41721
|
-
|
|
41875
|
+
connect4.call(this, opts, (err, data) => {
|
|
41722
41876
|
return err ? reject(err) : resolve9(data);
|
|
41723
41877
|
});
|
|
41724
41878
|
});
|
|
@@ -41735,7 +41889,7 @@ var require_api_connect = __commonJS({
|
|
|
41735
41889
|
queueMicrotask(() => callback(err, { opaque }));
|
|
41736
41890
|
}
|
|
41737
41891
|
}
|
|
41738
|
-
module2.exports =
|
|
41892
|
+
module2.exports = connect4;
|
|
41739
41893
|
}
|
|
41740
41894
|
});
|
|
41741
41895
|
|
|
@@ -41921,20 +42075,20 @@ var require_mock_utils = __commonJS({
|
|
|
41921
42075
|
}
|
|
41922
42076
|
return normalizedQp;
|
|
41923
42077
|
}
|
|
41924
|
-
function safeUrl(
|
|
41925
|
-
if (typeof
|
|
41926
|
-
return
|
|
42078
|
+
function safeUrl(path23) {
|
|
42079
|
+
if (typeof path23 !== "string") {
|
|
42080
|
+
return path23;
|
|
41927
42081
|
}
|
|
41928
|
-
const pathSegments =
|
|
42082
|
+
const pathSegments = path23.split("?", 3);
|
|
41929
42083
|
if (pathSegments.length !== 2) {
|
|
41930
|
-
return
|
|
42084
|
+
return path23;
|
|
41931
42085
|
}
|
|
41932
42086
|
const qp = new URLSearchParams(pathSegments.pop());
|
|
41933
42087
|
qp.sort();
|
|
41934
42088
|
return [...pathSegments, qp.toString()].join("?");
|
|
41935
42089
|
}
|
|
41936
|
-
function matchKey(mockDispatch2, { path:
|
|
41937
|
-
const pathMatch = matchValue(mockDispatch2.path,
|
|
42090
|
+
function matchKey(mockDispatch2, { path: path23, method, body, headers }) {
|
|
42091
|
+
const pathMatch = matchValue(mockDispatch2.path, path23);
|
|
41938
42092
|
const methodMatch = matchValue(mockDispatch2.method, method);
|
|
41939
42093
|
const bodyMatch = typeof mockDispatch2.body !== "undefined" ? matchValue(mockDispatch2.body, body) : true;
|
|
41940
42094
|
const headersMatch = matchHeaders(mockDispatch2, headers);
|
|
@@ -41959,8 +42113,8 @@ var require_mock_utils = __commonJS({
|
|
|
41959
42113
|
const basePath = key.query ? serializePathWithQuery(key.path, key.query) : key.path;
|
|
41960
42114
|
const resolvedPath = typeof basePath === "string" ? safeUrl(basePath) : basePath;
|
|
41961
42115
|
const resolvedPathWithoutTrailingSlash = removeTrailingSlash(resolvedPath);
|
|
41962
|
-
let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path:
|
|
41963
|
-
return ignoreTrailingSlash ? matchValue(removeTrailingSlash(safeUrl(
|
|
42116
|
+
let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path: path23, ignoreTrailingSlash }) => {
|
|
42117
|
+
return ignoreTrailingSlash ? matchValue(removeTrailingSlash(safeUrl(path23)), resolvedPathWithoutTrailingSlash) : matchValue(safeUrl(path23), resolvedPath);
|
|
41964
42118
|
});
|
|
41965
42119
|
if (matchedMockDispatches.length === 0) {
|
|
41966
42120
|
throw new MockNotMatchedError(`Mock dispatch not matched for path '${resolvedPath}'`);
|
|
@@ -41999,19 +42153,19 @@ var require_mock_utils = __commonJS({
|
|
|
41999
42153
|
mockDispatches.splice(index, 1);
|
|
42000
42154
|
}
|
|
42001
42155
|
}
|
|
42002
|
-
function removeTrailingSlash(
|
|
42003
|
-
while (
|
|
42004
|
-
|
|
42156
|
+
function removeTrailingSlash(path23) {
|
|
42157
|
+
while (path23.endsWith("/")) {
|
|
42158
|
+
path23 = path23.slice(0, -1);
|
|
42005
42159
|
}
|
|
42006
|
-
if (
|
|
42007
|
-
|
|
42160
|
+
if (path23.length === 0) {
|
|
42161
|
+
path23 = "/";
|
|
42008
42162
|
}
|
|
42009
|
-
return
|
|
42163
|
+
return path23;
|
|
42010
42164
|
}
|
|
42011
42165
|
function buildKey(opts) {
|
|
42012
|
-
const { path:
|
|
42166
|
+
const { path: path23, method, body, headers, query } = opts;
|
|
42013
42167
|
return {
|
|
42014
|
-
path:
|
|
42168
|
+
path: path23,
|
|
42015
42169
|
method,
|
|
42016
42170
|
body,
|
|
42017
42171
|
headers,
|
|
@@ -42701,10 +42855,10 @@ var require_pending_interceptors_formatter = __commonJS({
|
|
|
42701
42855
|
}
|
|
42702
42856
|
format(pendingInterceptors) {
|
|
42703
42857
|
const withPrettyHeaders = pendingInterceptors.map(
|
|
42704
|
-
({ method, path:
|
|
42858
|
+
({ method, path: path23, data: { statusCode }, persist, times, timesInvoked, origin }) => ({
|
|
42705
42859
|
Method: method,
|
|
42706
42860
|
Origin: origin,
|
|
42707
|
-
Path:
|
|
42861
|
+
Path: path23,
|
|
42708
42862
|
"Status code": statusCode,
|
|
42709
42863
|
Persistent: persist ? PERSISTENT : NOT_PERSISTENT,
|
|
42710
42864
|
Invocations: timesInvoked,
|
|
@@ -42786,9 +42940,9 @@ var require_mock_agent = __commonJS({
|
|
|
42786
42940
|
const acceptNonStandardSearchParameters = this[kMockAgentAcceptsNonStandardSearchParameters];
|
|
42787
42941
|
const dispatchOpts = { ...opts };
|
|
42788
42942
|
if (acceptNonStandardSearchParameters && dispatchOpts.path) {
|
|
42789
|
-
const [
|
|
42943
|
+
const [path23, searchParams] = dispatchOpts.path.split("?");
|
|
42790
42944
|
const normalizedSearchParams = normalizeSearchParams(searchParams, acceptNonStandardSearchParameters);
|
|
42791
|
-
dispatchOpts.path = `${
|
|
42945
|
+
dispatchOpts.path = `${path23}?${normalizedSearchParams}`;
|
|
42792
42946
|
}
|
|
42793
42947
|
return this[kAgent].dispatch(dispatchOpts, handler);
|
|
42794
42948
|
}
|
|
@@ -42993,7 +43147,7 @@ var require_snapshot_recorder = __commonJS({
|
|
|
42993
43147
|
"ts/node_modules/.pnpm/undici@7.24.8/node_modules/undici/lib/mock/snapshot-recorder.js"(exports2, module2) {
|
|
42994
43148
|
"use strict";
|
|
42995
43149
|
var { writeFile, readFile, mkdir } = __require("node:fs/promises");
|
|
42996
|
-
var { dirname:
|
|
43150
|
+
var { dirname: dirname13, resolve: resolve9 } = __require("node:path");
|
|
42997
43151
|
var { setTimeout: setTimeout2, clearTimeout: clearTimeout2 } = __require("node:timers");
|
|
42998
43152
|
var { InvalidArgumentError, UndiciError } = require_errors();
|
|
42999
43153
|
var { hashId, isUrlExcludedFactory, normalizeHeaders, createHeaderFilters } = require_snapshot_utils();
|
|
@@ -43189,12 +43343,12 @@ var require_snapshot_recorder = __commonJS({
|
|
|
43189
43343
|
* @return {Promise<void>} - Resolves when snapshots are loaded
|
|
43190
43344
|
*/
|
|
43191
43345
|
async loadSnapshots(filePath) {
|
|
43192
|
-
const
|
|
43193
|
-
if (!
|
|
43346
|
+
const path23 = filePath || this.#snapshotPath;
|
|
43347
|
+
if (!path23) {
|
|
43194
43348
|
throw new InvalidArgumentError("Snapshot path is required");
|
|
43195
43349
|
}
|
|
43196
43350
|
try {
|
|
43197
|
-
const data = await readFile(resolve9(
|
|
43351
|
+
const data = await readFile(resolve9(path23), "utf8");
|
|
43198
43352
|
const parsed = JSON.parse(data);
|
|
43199
43353
|
if (Array.isArray(parsed)) {
|
|
43200
43354
|
this.#snapshots.clear();
|
|
@@ -43208,7 +43362,7 @@ var require_snapshot_recorder = __commonJS({
|
|
|
43208
43362
|
if (error.code === "ENOENT") {
|
|
43209
43363
|
this.#snapshots.clear();
|
|
43210
43364
|
} else {
|
|
43211
|
-
throw new UndiciError(`Failed to load snapshots from ${
|
|
43365
|
+
throw new UndiciError(`Failed to load snapshots from ${path23}`, { cause: error });
|
|
43212
43366
|
}
|
|
43213
43367
|
}
|
|
43214
43368
|
}
|
|
@@ -43219,12 +43373,12 @@ var require_snapshot_recorder = __commonJS({
|
|
|
43219
43373
|
* @returns {Promise<void>} - Resolves when snapshots are saved
|
|
43220
43374
|
*/
|
|
43221
43375
|
async saveSnapshots(filePath) {
|
|
43222
|
-
const
|
|
43223
|
-
if (!
|
|
43376
|
+
const path23 = filePath || this.#snapshotPath;
|
|
43377
|
+
if (!path23) {
|
|
43224
43378
|
throw new InvalidArgumentError("Snapshot path is required");
|
|
43225
43379
|
}
|
|
43226
|
-
const resolvedPath = resolve9(
|
|
43227
|
-
await mkdir(
|
|
43380
|
+
const resolvedPath = resolve9(path23);
|
|
43381
|
+
await mkdir(dirname13(resolvedPath), { recursive: true });
|
|
43228
43382
|
const data = Array.from(this.#snapshots.entries()).map(([hash, snapshot]) => ({
|
|
43229
43383
|
hash,
|
|
43230
43384
|
snapshot
|
|
@@ -43848,15 +44002,15 @@ var require_redirect_handler = __commonJS({
|
|
|
43848
44002
|
return;
|
|
43849
44003
|
}
|
|
43850
44004
|
const { origin, pathname, search } = util.parseURL(new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin)));
|
|
43851
|
-
const
|
|
43852
|
-
const redirectUrlString = `${origin}${
|
|
44005
|
+
const path23 = search ? `${pathname}${search}` : pathname;
|
|
44006
|
+
const redirectUrlString = `${origin}${path23}`;
|
|
43853
44007
|
for (const historyUrl of this.history) {
|
|
43854
44008
|
if (historyUrl.toString() === redirectUrlString) {
|
|
43855
44009
|
throw new InvalidArgumentError(`Redirect loop detected. Cannot redirect to ${origin}. This typically happens when using a Client or Pool with cross-origin redirects. Use an Agent for cross-origin redirects.`);
|
|
43856
44010
|
}
|
|
43857
44011
|
}
|
|
43858
44012
|
this.opts.headers = cleanRequestHeaders(this.opts.headers, statusCode === 303, this.opts.origin !== origin);
|
|
43859
|
-
this.opts.path =
|
|
44013
|
+
this.opts.path = path23;
|
|
43860
44014
|
this.opts.origin = origin;
|
|
43861
44015
|
this.opts.query = null;
|
|
43862
44016
|
}
|
|
@@ -50063,11 +50217,11 @@ var require_fetch = __commonJS({
|
|
|
50063
50217
|
function dispatch({ body }) {
|
|
50064
50218
|
const url = requestCurrentURL(request3);
|
|
50065
50219
|
const agent = fetchParams.controller.dispatcher;
|
|
50066
|
-
const
|
|
50220
|
+
const path23 = url.pathname + url.search;
|
|
50067
50221
|
const hasTrailingQuestionMark = url.search.length === 0 && url.href[url.href.length - url.hash.length - 1] === "?";
|
|
50068
50222
|
return new Promise((resolve9, reject) => agent.dispatch(
|
|
50069
50223
|
{
|
|
50070
|
-
path: hasTrailingQuestionMark ? `${
|
|
50224
|
+
path: hasTrailingQuestionMark ? `${path23}?` : path23,
|
|
50071
50225
|
origin: url.origin,
|
|
50072
50226
|
method: request3.method,
|
|
50073
50227
|
body: agent.isMockActive ? request3.body && (request3.body.source || request3.body.stream) : body,
|
|
@@ -51014,9 +51168,9 @@ var require_util5 = __commonJS({
|
|
|
51014
51168
|
}
|
|
51015
51169
|
}
|
|
51016
51170
|
}
|
|
51017
|
-
function validateCookiePath(
|
|
51018
|
-
for (let i = 0; i <
|
|
51019
|
-
const code =
|
|
51171
|
+
function validateCookiePath(path23) {
|
|
51172
|
+
for (let i = 0; i < path23.length; ++i) {
|
|
51173
|
+
const code = path23.charCodeAt(i);
|
|
51020
51174
|
if (code < 32 || // exclude CTLs (0-31)
|
|
51021
51175
|
code === 127 || // DEL
|
|
51022
51176
|
code === 59) {
|
|
@@ -54186,11 +54340,11 @@ var require_undici = __commonJS({
|
|
|
54186
54340
|
if (typeof opts.path !== "string") {
|
|
54187
54341
|
throw new InvalidArgumentError("invalid opts.path");
|
|
54188
54342
|
}
|
|
54189
|
-
let
|
|
54343
|
+
let path23 = opts.path;
|
|
54190
54344
|
if (!opts.path.startsWith("/")) {
|
|
54191
|
-
|
|
54345
|
+
path23 = `/${path23}`;
|
|
54192
54346
|
}
|
|
54193
|
-
url = new URL(util.parseOrigin(url).origin +
|
|
54347
|
+
url = new URL(util.parseOrigin(url).origin + path23);
|
|
54194
54348
|
} else {
|
|
54195
54349
|
if (!opts) {
|
|
54196
54350
|
opts = typeof url === "object" ? url : {};
|
|
@@ -58161,7 +58315,7 @@ var require_websocket2 = __commonJS({
|
|
|
58161
58315
|
var EventEmitter = __require("events");
|
|
58162
58316
|
var https3 = __require("https");
|
|
58163
58317
|
var http3 = __require("http");
|
|
58164
|
-
var
|
|
58318
|
+
var net3 = __require("net");
|
|
58165
58319
|
var tls = __require("tls");
|
|
58166
58320
|
var { randomBytes: randomBytes2, createHash: createHash5 } = __require("crypto");
|
|
58167
58321
|
var { Duplex, Readable: Readable2 } = __require("stream");
|
|
@@ -58895,12 +59049,12 @@ var require_websocket2 = __commonJS({
|
|
|
58895
59049
|
}
|
|
58896
59050
|
function netConnect(options) {
|
|
58897
59051
|
options.path = options.socketPath;
|
|
58898
|
-
return
|
|
59052
|
+
return net3.connect(options);
|
|
58899
59053
|
}
|
|
58900
59054
|
function tlsConnect(options) {
|
|
58901
59055
|
options.path = void 0;
|
|
58902
59056
|
if (!options.servername && options.servername !== "") {
|
|
58903
|
-
options.servername =
|
|
59057
|
+
options.servername = net3.isIP(options.host) ? "" : options.host;
|
|
58904
59058
|
}
|
|
58905
59059
|
return tls.connect(options);
|
|
58906
59060
|
}
|
|
@@ -64914,9 +65068,280 @@ var init_filesystem = __esm({
|
|
|
64914
65068
|
}
|
|
64915
65069
|
});
|
|
64916
65070
|
|
|
65071
|
+
// ts/daemon/dist/local-control.js
|
|
65072
|
+
import { chmodSync as chmodSync2, existsSync as existsSync10, mkdirSync as mkdirSync8, rmSync as rmSync4, statSync } from "node:fs";
|
|
65073
|
+
import * as net2 from "node:net";
|
|
65074
|
+
import * as path17 from "node:path";
|
|
65075
|
+
function localControlSocketPath(env = process.env) {
|
|
65076
|
+
return path17.join(daemonConfigDir(env), "run", "control.sock");
|
|
65077
|
+
}
|
|
65078
|
+
function isSocketLive(sockPath) {
|
|
65079
|
+
return new Promise((resolve9) => {
|
|
65080
|
+
const probe = net2.connect(sockPath);
|
|
65081
|
+
const done = (live) => {
|
|
65082
|
+
probe.removeAllListeners();
|
|
65083
|
+
probe.destroy();
|
|
65084
|
+
clearTimeout(timer);
|
|
65085
|
+
resolve9(live);
|
|
65086
|
+
};
|
|
65087
|
+
const timer = setTimeout(() => done(true), 1e3);
|
|
65088
|
+
probe.once("connect", () => done(true));
|
|
65089
|
+
probe.once("error", (err) => {
|
|
65090
|
+
done(!(err.code === "ECONNREFUSED" || err.code === "ENOENT"));
|
|
65091
|
+
});
|
|
65092
|
+
});
|
|
65093
|
+
}
|
|
65094
|
+
var LocalControlError, MAX_LINE_BYTES, LocalControlServer;
|
|
65095
|
+
var init_local_control = __esm({
|
|
65096
|
+
"ts/daemon/dist/local-control.js"() {
|
|
65097
|
+
"use strict";
|
|
65098
|
+
init_daemon_paths();
|
|
65099
|
+
LocalControlError = class extends Error {
|
|
65100
|
+
code;
|
|
65101
|
+
constructor(code, message) {
|
|
65102
|
+
super(message);
|
|
65103
|
+
this.code = code;
|
|
65104
|
+
this.name = "LocalControlError";
|
|
65105
|
+
}
|
|
65106
|
+
};
|
|
65107
|
+
MAX_LINE_BYTES = 16 * 1024;
|
|
65108
|
+
LocalControlServer = class {
|
|
65109
|
+
opts;
|
|
65110
|
+
server = null;
|
|
65111
|
+
sockets = /* @__PURE__ */ new Set();
|
|
65112
|
+
constructor(opts) {
|
|
65113
|
+
this.opts = opts;
|
|
65114
|
+
}
|
|
65115
|
+
async start() {
|
|
65116
|
+
if (this.server)
|
|
65117
|
+
throw new Error("local control server already started");
|
|
65118
|
+
const sockPath = this.opts.socketPath;
|
|
65119
|
+
const dir = path17.dirname(sockPath);
|
|
65120
|
+
mkdirSync8(dir, { recursive: true, mode: 448 });
|
|
65121
|
+
try {
|
|
65122
|
+
chmodSync2(dir, 448);
|
|
65123
|
+
} catch (err) {
|
|
65124
|
+
throw new Error(`could not restrict control socket directory: ${String(err)}`);
|
|
65125
|
+
}
|
|
65126
|
+
if (existsSync10(sockPath)) {
|
|
65127
|
+
let st;
|
|
65128
|
+
try {
|
|
65129
|
+
st = statSync(sockPath);
|
|
65130
|
+
} catch (err) {
|
|
65131
|
+
throw new Error(`could not inspect existing control socket: ${String(err)}`);
|
|
65132
|
+
}
|
|
65133
|
+
if (st.isSocket()) {
|
|
65134
|
+
if (await isSocketLive(sockPath)) {
|
|
65135
|
+
throw new Error(`another process is already serving the local control socket at ${sockPath}`);
|
|
65136
|
+
}
|
|
65137
|
+
rmSync4(sockPath, { force: true });
|
|
65138
|
+
}
|
|
65139
|
+
}
|
|
65140
|
+
const server = net2.createServer((socket) => this.handleConnection(socket));
|
|
65141
|
+
this.server = server;
|
|
65142
|
+
await new Promise((resolve9, reject) => {
|
|
65143
|
+
const onError = (err) => {
|
|
65144
|
+
this.server = null;
|
|
65145
|
+
reject(err);
|
|
65146
|
+
};
|
|
65147
|
+
server.once("error", onError);
|
|
65148
|
+
server.listen(sockPath, () => {
|
|
65149
|
+
server.removeListener("error", onError);
|
|
65150
|
+
try {
|
|
65151
|
+
chmodSync2(sockPath, 384);
|
|
65152
|
+
} catch (err) {
|
|
65153
|
+
server.close();
|
|
65154
|
+
this.server = null;
|
|
65155
|
+
reject(new Error(`could not restrict control socket permissions: ${String(err)}`));
|
|
65156
|
+
return;
|
|
65157
|
+
}
|
|
65158
|
+
resolve9();
|
|
65159
|
+
});
|
|
65160
|
+
});
|
|
65161
|
+
server.on("error", (err) => this.opts.log.warn(`local control server error: ${String(err)}`));
|
|
65162
|
+
this.opts.log.info(`local control socket listening at ${sockPath}`);
|
|
65163
|
+
}
|
|
65164
|
+
async stop() {
|
|
65165
|
+
const server = this.server;
|
|
65166
|
+
if (!server)
|
|
65167
|
+
return;
|
|
65168
|
+
this.server = null;
|
|
65169
|
+
for (const s of this.sockets)
|
|
65170
|
+
s.destroy();
|
|
65171
|
+
this.sockets.clear();
|
|
65172
|
+
await new Promise((resolve9) => server.close(() => resolve9()));
|
|
65173
|
+
try {
|
|
65174
|
+
rmSync4(this.opts.socketPath, { force: true });
|
|
65175
|
+
} catch {
|
|
65176
|
+
}
|
|
65177
|
+
}
|
|
65178
|
+
handleConnection(socket) {
|
|
65179
|
+
this.sockets.add(socket);
|
|
65180
|
+
socket.on("close", () => this.sockets.delete(socket));
|
|
65181
|
+
socket.on("error", () => socket.destroy());
|
|
65182
|
+
socket.setEncoding("utf8");
|
|
65183
|
+
let buffer = "";
|
|
65184
|
+
socket.on("data", (chunk) => {
|
|
65185
|
+
buffer += chunk;
|
|
65186
|
+
if (Buffer.byteLength(buffer) > MAX_LINE_BYTES) {
|
|
65187
|
+
this.reply(socket, void 0, { code: "INVALID_REQUEST", message: "request too large" });
|
|
65188
|
+
socket.end();
|
|
65189
|
+
return;
|
|
65190
|
+
}
|
|
65191
|
+
let newline = buffer.indexOf("\n");
|
|
65192
|
+
while (newline !== -1) {
|
|
65193
|
+
const line = buffer.slice(0, newline).trim();
|
|
65194
|
+
buffer = buffer.slice(newline + 1);
|
|
65195
|
+
if (line)
|
|
65196
|
+
void this.handleLine(socket, line);
|
|
65197
|
+
newline = buffer.indexOf("\n");
|
|
65198
|
+
}
|
|
65199
|
+
});
|
|
65200
|
+
}
|
|
65201
|
+
async handleLine(socket, line) {
|
|
65202
|
+
let req;
|
|
65203
|
+
try {
|
|
65204
|
+
const parsed = JSON.parse(line);
|
|
65205
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
65206
|
+
throw new Error("not an object");
|
|
65207
|
+
}
|
|
65208
|
+
req = parsed;
|
|
65209
|
+
} catch {
|
|
65210
|
+
this.reply(socket, void 0, { code: "INVALID_REQUEST", message: "invalid JSON request" });
|
|
65211
|
+
socket.end();
|
|
65212
|
+
return;
|
|
65213
|
+
}
|
|
65214
|
+
const id = typeof req.id === "string" ? req.id : void 0;
|
|
65215
|
+
try {
|
|
65216
|
+
switch (req.command) {
|
|
65217
|
+
case "ping": {
|
|
65218
|
+
const result = await this.opts.handlers.ping();
|
|
65219
|
+
this.reply(socket, id, void 0, result);
|
|
65220
|
+
return;
|
|
65221
|
+
}
|
|
65222
|
+
case "profile.open":
|
|
65223
|
+
case "profile.stop":
|
|
65224
|
+
case "profile.reset": {
|
|
65225
|
+
const action = req.command.slice("profile.".length);
|
|
65226
|
+
const profileId = typeof req.profile_id === "string" ? req.profile_id.trim() : "";
|
|
65227
|
+
const requester = typeof req.requester_user_id === "string" ? req.requester_user_id.trim() : "";
|
|
65228
|
+
if (!profileId || !requester) {
|
|
65229
|
+
throw new LocalControlError("INVALID_REQUEST", "profile_id and requester_user_id are required");
|
|
65230
|
+
}
|
|
65231
|
+
await this.opts.handlers.profileControl(action, profileId, requester);
|
|
65232
|
+
this.reply(socket, id, void 0, { status: "ok" });
|
|
65233
|
+
return;
|
|
65234
|
+
}
|
|
65235
|
+
default:
|
|
65236
|
+
throw new LocalControlError("UNKNOWN_COMMAND", `unknown command ${String(req.command)}`);
|
|
65237
|
+
}
|
|
65238
|
+
} catch (err) {
|
|
65239
|
+
if (err instanceof LocalControlError) {
|
|
65240
|
+
this.reply(socket, id, { code: err.code, message: err.message });
|
|
65241
|
+
} else {
|
|
65242
|
+
this.opts.log.warn(`local control command failed: ${String(err)}`);
|
|
65243
|
+
this.reply(socket, id, {
|
|
65244
|
+
code: "INTERNAL",
|
|
65245
|
+
message: err instanceof Error ? err.message : String(err)
|
|
65246
|
+
});
|
|
65247
|
+
}
|
|
65248
|
+
}
|
|
65249
|
+
}
|
|
65250
|
+
reply(socket, id, error, result) {
|
|
65251
|
+
if (socket.destroyed)
|
|
65252
|
+
return;
|
|
65253
|
+
const payload = { ok: !error };
|
|
65254
|
+
if (id !== void 0)
|
|
65255
|
+
payload.id = id;
|
|
65256
|
+
if (error)
|
|
65257
|
+
payload.error = error;
|
|
65258
|
+
if (result !== void 0)
|
|
65259
|
+
payload.result = result;
|
|
65260
|
+
try {
|
|
65261
|
+
socket.write(`${JSON.stringify(payload)}
|
|
65262
|
+
`);
|
|
65263
|
+
} catch {
|
|
65264
|
+
socket.destroy();
|
|
65265
|
+
}
|
|
65266
|
+
}
|
|
65267
|
+
};
|
|
65268
|
+
}
|
|
65269
|
+
});
|
|
65270
|
+
|
|
65271
|
+
// ts/daemon/dist/local-profile-control.js
|
|
65272
|
+
async function startLocalProfileControl(deps) {
|
|
65273
|
+
if (process.env.KUBERNETES_SERVICE_HOST || process.platform === "win32")
|
|
65274
|
+
return null;
|
|
65275
|
+
const server = new LocalControlServer({
|
|
65276
|
+
socketPath: localControlSocketPath(),
|
|
65277
|
+
log: deps.log,
|
|
65278
|
+
handlers: {
|
|
65279
|
+
ping: async () => ({
|
|
65280
|
+
machine_id: deps.machineId(),
|
|
65281
|
+
org_id: deps.orgId(),
|
|
65282
|
+
profile_control: deps.pool() !== null
|
|
65283
|
+
}),
|
|
65284
|
+
profileControl: (action, profileId, requesterUserId) => handleLocalProfileControl(deps, action, profileId, requesterUserId)
|
|
65285
|
+
}
|
|
65286
|
+
});
|
|
65287
|
+
try {
|
|
65288
|
+
await server.start();
|
|
65289
|
+
return server;
|
|
65290
|
+
} catch (err) {
|
|
65291
|
+
deps.log.warn(`local control socket unavailable: ${String(err)}`);
|
|
65292
|
+
return null;
|
|
65293
|
+
}
|
|
65294
|
+
}
|
|
65295
|
+
async function handleLocalProfileControl(deps, action, profileId, requesterUserId) {
|
|
65296
|
+
const owner = deps.owner();
|
|
65297
|
+
if (!owner || !requesterUserId || requesterUserId !== owner) {
|
|
65298
|
+
throw new LocalControlError("OWNER_MISMATCH", "Only the machine owner can control local browser profiles");
|
|
65299
|
+
}
|
|
65300
|
+
const pool = deps.pool();
|
|
65301
|
+
if (!pool) {
|
|
65302
|
+
throw new LocalControlError("RUNTIME_DISABLED", "Browser profile runtime is disabled on this daemon");
|
|
65303
|
+
}
|
|
65304
|
+
let profiles;
|
|
65305
|
+
try {
|
|
65306
|
+
profiles = await deps.listProfiles();
|
|
65307
|
+
} catch (err) {
|
|
65308
|
+
throw new LocalControlError("SERVER_UNAVAILABLE", `could not verify the profile with the server: ${String(err)}`);
|
|
65309
|
+
}
|
|
65310
|
+
const profile = profiles.find((p) => p.id === profileId && p.machine_id);
|
|
65311
|
+
if (!profile) {
|
|
65312
|
+
throw new LocalControlError("PROFILE_NOT_ON_MACHINE", "Browser profile is not assigned to this machine");
|
|
65313
|
+
}
|
|
65314
|
+
const generation = profile.lifecycle_generation;
|
|
65315
|
+
if (action === "open") {
|
|
65316
|
+
const resetGen = profile.reset_generation ?? 0;
|
|
65317
|
+
const wipeGen = resetGen > pool.appliedResetGeneration(profileId) ? resetGen : null;
|
|
65318
|
+
if (wipeGen !== null)
|
|
65319
|
+
pool.fence(profileId);
|
|
65320
|
+
const sinceSeq = pool.stopSeqOf(profileId);
|
|
65321
|
+
await deps.enqueueRevive(profileId, async () => {
|
|
65322
|
+
if (wipeGen !== null)
|
|
65323
|
+
await deps.wipeBeforeRevive(pool, profileId, wipeGen, generation);
|
|
65324
|
+
await pool.openProfile(profileId, void 0, sinceSeq, generation);
|
|
65325
|
+
});
|
|
65326
|
+
return;
|
|
65327
|
+
}
|
|
65328
|
+
pool.fence(profileId);
|
|
65329
|
+
if (action === "stop") {
|
|
65330
|
+
await deps.enqueueOp(profileId, () => pool.stopProfile(profileId, generation));
|
|
65331
|
+
return;
|
|
65332
|
+
}
|
|
65333
|
+
await deps.enqueueOp(profileId, () => pool.resetProfile(profileId, generation, profile.reset_generation));
|
|
65334
|
+
}
|
|
65335
|
+
var init_local_profile_control = __esm({
|
|
65336
|
+
"ts/daemon/dist/local-profile-control.js"() {
|
|
65337
|
+
"use strict";
|
|
65338
|
+
init_local_control();
|
|
65339
|
+
}
|
|
65340
|
+
});
|
|
65341
|
+
|
|
64917
65342
|
// ts/daemon/dist/home-isolation.js
|
|
64918
65343
|
import * as fs10 from "node:fs";
|
|
64919
|
-
import * as
|
|
65344
|
+
import * as path18 from "node:path";
|
|
64920
65345
|
function ensureIsolatedHome(spec, agentId, log2, platform2 = process.platform) {
|
|
64921
65346
|
fs10.mkdirSync(spec.homeDir, { recursive: true });
|
|
64922
65347
|
const failures = [];
|
|
@@ -64928,18 +65353,18 @@ function ensureIsolatedHome(spec, agentId, log2, platform2 = process.platform) {
|
|
|
64928
65353
|
}
|
|
64929
65354
|
};
|
|
64930
65355
|
attempt(".claude link", () => {
|
|
64931
|
-
fs10.mkdirSync(
|
|
64932
|
-
ensureLink(
|
|
65356
|
+
fs10.mkdirSync(path18.join(spec.claudeStateRoot, ".claude"), { recursive: true });
|
|
65357
|
+
ensureLink(path18.join(spec.homeDir, ".claude"), path18.join(spec.claudeStateRoot, ".claude"), agentId, log2);
|
|
64933
65358
|
});
|
|
64934
|
-
attempt(".claude.json link", () => ensureLink(
|
|
65359
|
+
attempt(".claude.json link", () => ensureLink(path18.join(spec.homeDir, ".claude.json"), path18.join(spec.claudeStateRoot, ".claude.json"), agentId, log2));
|
|
64935
65360
|
if (platform2 === "darwin") {
|
|
64936
65361
|
attempt("Library/Keychains link", () => {
|
|
64937
|
-
fs10.mkdirSync(
|
|
64938
|
-
ensureLink(
|
|
65362
|
+
fs10.mkdirSync(path18.join(spec.homeDir, "Library"), { recursive: true });
|
|
65363
|
+
ensureLink(path18.join(spec.homeDir, "Library", "Keychains"), path18.join(spec.systemHome, "Library", "Keychains"), agentId, log2);
|
|
64939
65364
|
});
|
|
64940
65365
|
}
|
|
64941
65366
|
attempt(".gitconfig", () => {
|
|
64942
|
-
const gitconfig =
|
|
65367
|
+
const gitconfig = path18.join(spec.homeDir, ".gitconfig");
|
|
64943
65368
|
if (!fs10.existsSync(gitconfig)) {
|
|
64944
65369
|
fs10.writeFileSync(gitconfig, `[user]
|
|
64945
65370
|
name = ${gitConfigValue(spec.gitUserName)}
|
|
@@ -64965,7 +65390,7 @@ function ensureLink(linkPath, target, agentId, log2) {
|
|
|
64965
65390
|
if (existing) {
|
|
64966
65391
|
if (existing.isSymbolicLink()) {
|
|
64967
65392
|
const current = fs10.readlinkSync(linkPath);
|
|
64968
|
-
if (
|
|
65393
|
+
if (path18.resolve(path18.dirname(linkPath), current) === path18.resolve(target))
|
|
64969
65394
|
return;
|
|
64970
65395
|
fs10.unlinkSync(linkPath);
|
|
64971
65396
|
log2.info(`agent ${agentId}: relinking ${linkPath} \u2192 ${target}`);
|
|
@@ -64978,16 +65403,16 @@ function ensureLink(linkPath, target, agentId, log2) {
|
|
|
64978
65403
|
fs10.symlinkSync(target, linkPath);
|
|
64979
65404
|
}
|
|
64980
65405
|
function ensureSharedCredentialLink(rootClaudeHome, agentClaudeHome, agentId, log2) {
|
|
64981
|
-
const sharedCredentials =
|
|
65406
|
+
const sharedCredentials = path18.resolve(sharedClaudeCredentialsFileFor(rootClaudeHome));
|
|
64982
65407
|
const agentCredentials = agentClaudeCredentialsFileFor(agentClaudeHome);
|
|
64983
|
-
const agentCredentialsDir =
|
|
64984
|
-
fs10.mkdirSync(
|
|
65408
|
+
const agentCredentialsDir = path18.dirname(agentCredentials);
|
|
65409
|
+
fs10.mkdirSync(path18.dirname(sharedCredentials), { recursive: true });
|
|
64985
65410
|
fs10.mkdirSync(agentCredentialsDir, { recursive: true });
|
|
64986
65411
|
try {
|
|
64987
65412
|
const existing = fs10.lstatSync(agentCredentials);
|
|
64988
65413
|
if (existing.isSymbolicLink()) {
|
|
64989
65414
|
const currentTarget = fs10.readlinkSync(agentCredentials);
|
|
64990
|
-
if (
|
|
65415
|
+
if (path18.resolve(agentCredentialsDir, currentTarget) === sharedCredentials) {
|
|
64991
65416
|
return;
|
|
64992
65417
|
}
|
|
64993
65418
|
fs10.unlinkSync(agentCredentials);
|
|
@@ -65015,7 +65440,7 @@ var init_home_isolation = __esm({
|
|
|
65015
65440
|
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
65016
65441
|
import * as fs11 from "node:fs";
|
|
65017
65442
|
import * as os6 from "node:os";
|
|
65018
|
-
import * as
|
|
65443
|
+
import * as path19 from "node:path";
|
|
65019
65444
|
function runtimeBinaryEnvVar(runtimeType) {
|
|
65020
65445
|
return RUNTIME_BINARIES[runtimeType]?.envVar;
|
|
65021
65446
|
}
|
|
@@ -65092,16 +65517,16 @@ function resolveRuntimeCommand(command, env, inheritedPath, primaryPath, fallbac
|
|
|
65092
65517
|
function resolveDirectPath(command) {
|
|
65093
65518
|
if (!command.includes("/") && !command.includes("\\"))
|
|
65094
65519
|
return null;
|
|
65095
|
-
const abs =
|
|
65520
|
+
const abs = path19.isAbsolute(command) ? command : path19.resolve(process.cwd(), command);
|
|
65096
65521
|
return isExecutable(abs) ? abs : null;
|
|
65097
65522
|
}
|
|
65098
65523
|
function resolveFromPath(command, pathValue, env, platform2) {
|
|
65099
65524
|
if (!pathValue || command.includes("/") || command.includes("\\"))
|
|
65100
65525
|
return null;
|
|
65101
|
-
const dirs = pathValue.split(
|
|
65526
|
+
const dirs = pathValue.split(path19.delimiter).filter(Boolean);
|
|
65102
65527
|
for (const dir of dirs) {
|
|
65103
65528
|
for (const file of commandCandidates(command, env, platform2)) {
|
|
65104
|
-
const candidate =
|
|
65529
|
+
const candidate = path19.join(dir, file);
|
|
65105
65530
|
if (isExecutable(candidate))
|
|
65106
65531
|
return { binaryPath: candidate, pathValue };
|
|
65107
65532
|
}
|
|
@@ -65142,7 +65567,7 @@ __PRLL_PATH__%s
|
|
|
65142
65567
|
if (line.startsWith("__PRLL_PATH__"))
|
|
65143
65568
|
pathValue = line.slice("__PRLL_PATH__".length);
|
|
65144
65569
|
}
|
|
65145
|
-
if (
|
|
65570
|
+
if (path19.isAbsolute(binaryPath) && isExecutable(binaryPath)) {
|
|
65146
65571
|
return { binaryPath, pathValue: pathValue || void 0 };
|
|
65147
65572
|
}
|
|
65148
65573
|
} catch {
|
|
@@ -65162,18 +65587,18 @@ function cachedCandidatePathPlan(env, platform2) {
|
|
|
65162
65587
|
function candidatePathPlan(env, platform2 = process.platform) {
|
|
65163
65588
|
const home = env.HOME || os6.homedir();
|
|
65164
65589
|
if (platform2 === "win32") {
|
|
65165
|
-
const appData = env.APPDATA ||
|
|
65166
|
-
const localAppData = env.LOCALAPPDATA ||
|
|
65590
|
+
const appData = env.APPDATA || path19.join(home, "AppData", "Roaming");
|
|
65591
|
+
const localAppData = env.LOCALAPPDATA || path19.join(home, "AppData", "Local");
|
|
65167
65592
|
const winPrimaryDirs = [
|
|
65168
65593
|
...splitPath(env.PRLL_DAEMON_RUNTIME_PATH),
|
|
65169
65594
|
...splitPath(env.PRLL_DAEMON_EXTRA_PATH),
|
|
65170
|
-
|
|
65595
|
+
path19.dirname(process.execPath),
|
|
65171
65596
|
env.PNPM_HOME,
|
|
65172
|
-
|
|
65173
|
-
|
|
65174
|
-
|
|
65175
|
-
|
|
65176
|
-
|
|
65597
|
+
path19.join(appData, "npm"),
|
|
65598
|
+
path19.join(localAppData, "pnpm"),
|
|
65599
|
+
path19.join(localAppData, "Volta", "bin"),
|
|
65600
|
+
path19.join(home, ".volta", "bin"),
|
|
65601
|
+
path19.join(home, ".bun", "bin")
|
|
65177
65602
|
];
|
|
65178
65603
|
return {
|
|
65179
65604
|
primaryDirs: unique(winPrimaryDirs).filter((dir) => !!dir && isDirectory(dir)),
|
|
@@ -65183,21 +65608,21 @@ function candidatePathPlan(env, platform2 = process.platform) {
|
|
|
65183
65608
|
const primaryDirs = [
|
|
65184
65609
|
...splitPath(env.PRLL_DAEMON_RUNTIME_PATH),
|
|
65185
65610
|
...splitPath(env.PRLL_DAEMON_EXTRA_PATH),
|
|
65186
|
-
|
|
65187
|
-
|
|
65188
|
-
|
|
65189
|
-
|
|
65190
|
-
|
|
65191
|
-
|
|
65192
|
-
|
|
65193
|
-
|
|
65194
|
-
|
|
65195
|
-
|
|
65196
|
-
|
|
65197
|
-
|
|
65198
|
-
|
|
65199
|
-
|
|
65200
|
-
|
|
65611
|
+
path19.dirname(process.execPath),
|
|
65612
|
+
path19.join(path19.dirname(process.execPath), "bin"),
|
|
65613
|
+
path19.resolve(path19.dirname(process.execPath), "..", "Resources", "bin"),
|
|
65614
|
+
path19.join(home, ".local", "bin"),
|
|
65615
|
+
path19.join(home, "bin"),
|
|
65616
|
+
path19.join(home, ".npm-global", "bin"),
|
|
65617
|
+
path19.join(home, "Library", "pnpm"),
|
|
65618
|
+
path19.join(home, ".local", "share", "pnpm"),
|
|
65619
|
+
path19.join(home, ".volta", "bin"),
|
|
65620
|
+
path19.join(home, ".bun", "bin"),
|
|
65621
|
+
path19.join(home, ".asdf", "shims"),
|
|
65622
|
+
path19.join(home, ".local", "share", "mise", "shims"),
|
|
65623
|
+
path19.join(home, ".mise", "shims"),
|
|
65624
|
+
path19.join(home, ".fnm", "aliases", "default", "bin"),
|
|
65625
|
+
path19.join(home, "Library", "Application Support", "fnm", "aliases", "default", "bin"),
|
|
65201
65626
|
"/opt/homebrew/bin",
|
|
65202
65627
|
"/usr/local/bin",
|
|
65203
65628
|
"/usr/bin",
|
|
@@ -65216,19 +65641,19 @@ function candidatePathPlan(env, platform2 = process.platform) {
|
|
|
65216
65641
|
};
|
|
65217
65642
|
}
|
|
65218
65643
|
function nvmVersionBinDirs(home) {
|
|
65219
|
-
const root =
|
|
65644
|
+
const root = path19.join(home, ".nvm", "versions", "node");
|
|
65220
65645
|
let versions;
|
|
65221
65646
|
try {
|
|
65222
65647
|
versions = fs11.readdirSync(root);
|
|
65223
65648
|
} catch {
|
|
65224
65649
|
return [];
|
|
65225
65650
|
}
|
|
65226
|
-
return sortVersionNamesDesc(versions).map((version) =>
|
|
65651
|
+
return sortVersionNamesDesc(versions).map((version) => path19.join(root, version, "bin"));
|
|
65227
65652
|
}
|
|
65228
65653
|
function fnmVersionBinDirs(home) {
|
|
65229
65654
|
const roots = [
|
|
65230
|
-
|
|
65231
|
-
|
|
65655
|
+
path19.join(home, ".fnm", "node-versions"),
|
|
65656
|
+
path19.join(home, "Library", "Application Support", "fnm", "node-versions")
|
|
65232
65657
|
];
|
|
65233
65658
|
const dirs = [];
|
|
65234
65659
|
for (const root of roots) {
|
|
@@ -65238,7 +65663,7 @@ function fnmVersionBinDirs(home) {
|
|
|
65238
65663
|
} catch {
|
|
65239
65664
|
continue;
|
|
65240
65665
|
}
|
|
65241
|
-
dirs.push(...sortVersionNamesDesc(versions).map((version) =>
|
|
65666
|
+
dirs.push(...sortVersionNamesDesc(versions).map((version) => path19.join(root, version, "installation", "bin")));
|
|
65242
65667
|
}
|
|
65243
65668
|
return dirs;
|
|
65244
65669
|
}
|
|
@@ -65260,13 +65685,13 @@ function parseVersionName(value) {
|
|
|
65260
65685
|
return value.replace(/^v/i, "").split(".").map((part) => Number.parseInt(part, 10)).filter((part) => Number.isFinite(part));
|
|
65261
65686
|
}
|
|
65262
65687
|
function splitPath(value) {
|
|
65263
|
-
return value?.split(
|
|
65688
|
+
return value?.split(path19.delimiter).filter(Boolean) ?? [];
|
|
65264
65689
|
}
|
|
65265
65690
|
function mergePath(prependDirs, existing) {
|
|
65266
|
-
return unique([...prependDirs, ...splitPath(existing)]).join(
|
|
65691
|
+
return unique([...prependDirs, ...splitPath(existing)]).join(path19.delimiter);
|
|
65267
65692
|
}
|
|
65268
65693
|
function anchorResolvedPath(pathValue, resolution) {
|
|
65269
|
-
return mergePath([
|
|
65694
|
+
return mergePath([path19.dirname(resolution.binaryPath), ...splitPath(resolution.pathValue)], pathValue);
|
|
65270
65695
|
}
|
|
65271
65696
|
function commandCandidates(command, env, platform2 = process.platform) {
|
|
65272
65697
|
if (platform2 !== "win32")
|
|
@@ -65421,7 +65846,7 @@ var init_runtime_detector = __esm({
|
|
|
65421
65846
|
import { spawn as spawn5 } from "node:child_process";
|
|
65422
65847
|
import { createHash as createHash4 } from "node:crypto";
|
|
65423
65848
|
import * as fs12 from "node:fs";
|
|
65424
|
-
import * as
|
|
65849
|
+
import * as path20 from "node:path";
|
|
65425
65850
|
async function prepareWorkspace(opts) {
|
|
65426
65851
|
const prior = opts.attached.workspace_state;
|
|
65427
65852
|
const plan = buildWorkspacePlan(opts.attached.daemon_config, opts.defaultWorkspaceDir, prior?.config_hash);
|
|
@@ -65566,8 +65991,8 @@ async function ensureWorkspace(plan, log2) {
|
|
|
65566
65991
|
assertSafeCustomWorkspacePath(plan);
|
|
65567
65992
|
}
|
|
65568
65993
|
if (!fs12.existsSync(plan.workspaceDir)) {
|
|
65569
|
-
fs12.mkdirSync(
|
|
65570
|
-
assertWritableWorkspaceDir(
|
|
65994
|
+
fs12.mkdirSync(path20.dirname(plan.workspaceDir), { recursive: true });
|
|
65995
|
+
assertWritableWorkspaceDir(path20.dirname(plan.workspaceDir));
|
|
65571
65996
|
await runCommand("git", ["clone", remote, plan.workspaceDir], process.cwd());
|
|
65572
65997
|
} else {
|
|
65573
65998
|
const st = fs12.statSync(plan.workspaceDir);
|
|
@@ -65749,10 +66174,10 @@ ${tail}`)));
|
|
|
65749
66174
|
});
|
|
65750
66175
|
}
|
|
65751
66176
|
function requireAbsolute(value, field) {
|
|
65752
|
-
if (!value || !
|
|
66177
|
+
if (!value || !path20.isAbsolute(value)) {
|
|
65753
66178
|
throw new Error(`${field} must be an absolute path`);
|
|
65754
66179
|
}
|
|
65755
|
-
return
|
|
66180
|
+
return path20.resolve(value);
|
|
65756
66181
|
}
|
|
65757
66182
|
function assertSafeCustomWorkspacePath(plan, candidate = plan.workspaceDir) {
|
|
65758
66183
|
if (!plan.customWorkspaceField)
|
|
@@ -65762,14 +66187,14 @@ function assertSafeCustomWorkspacePath(plan, candidate = plan.workspaceDir) {
|
|
|
65762
66187
|
if (reason) {
|
|
65763
66188
|
throw new Error(`${plan.customWorkspaceField} must point to a project folder, not ${reason}: ${normalized}`);
|
|
65764
66189
|
}
|
|
65765
|
-
const defaultWorkspace =
|
|
66190
|
+
const defaultWorkspace = path20.resolve(plan.defaultWorkspaceDir);
|
|
65766
66191
|
if (isAncestorPath(normalized, defaultWorkspace) || normalized === defaultWorkspace) {
|
|
65767
66192
|
throw new Error(`${plan.customWorkspaceField} must not point at daemon state directories: ${normalized}`);
|
|
65768
66193
|
}
|
|
65769
66194
|
}
|
|
65770
66195
|
function assertWritableWorkspaceDir(dir) {
|
|
65771
66196
|
fs12.accessSync(dir, fs12.constants.R_OK | fs12.constants.W_OK | fs12.constants.X_OK);
|
|
65772
|
-
const probe =
|
|
66197
|
+
const probe = path20.join(dir, `.parall-workspace-check-${process.pid}-${Date.now()}`);
|
|
65773
66198
|
const fd = fs12.openSync(probe, "wx", 384);
|
|
65774
66199
|
fs12.closeSync(fd);
|
|
65775
66200
|
fs12.unlinkSync(probe);
|
|
@@ -65833,11 +66258,11 @@ function workspacePathDenyReason(value) {
|
|
|
65833
66258
|
return "";
|
|
65834
66259
|
}
|
|
65835
66260
|
function isAncestorPath(parent, child) {
|
|
65836
|
-
const relative2 =
|
|
65837
|
-
return relative2 !== "" && !relative2.startsWith("..") && !
|
|
66261
|
+
const relative2 = path20.relative(parent, child);
|
|
66262
|
+
return relative2 !== "" && !relative2.startsWith("..") && !path20.isAbsolute(relative2);
|
|
65838
66263
|
}
|
|
65839
66264
|
function toPolicyPath(value) {
|
|
65840
|
-
return
|
|
66265
|
+
return path20.resolve(value).split(path20.sep).join("/");
|
|
65841
66266
|
}
|
|
65842
66267
|
function isNodeError(err) {
|
|
65843
66268
|
return err instanceof Error && "code" in err;
|
|
@@ -65856,7 +66281,7 @@ var init_workspace = __esm({
|
|
|
65856
66281
|
import { spawn as spawn6 } from "node:child_process";
|
|
65857
66282
|
import * as fs13 from "node:fs";
|
|
65858
66283
|
import * as os7 from "node:os";
|
|
65859
|
-
import * as
|
|
66284
|
+
import * as path21 from "node:path";
|
|
65860
66285
|
function sleepCancellable(ms, signal) {
|
|
65861
66286
|
if (signal.aborted)
|
|
65862
66287
|
return Promise.resolve(false);
|
|
@@ -65885,6 +66310,7 @@ var init_supervisor = __esm({
|
|
|
65885
66310
|
init_config();
|
|
65886
66311
|
init_browser_profile_reconcile();
|
|
65887
66312
|
init_filesystem();
|
|
66313
|
+
init_local_profile_control();
|
|
65888
66314
|
init_home_isolation();
|
|
65889
66315
|
init_runtimes();
|
|
65890
66316
|
init_runtime_bin_resolver();
|
|
@@ -65938,6 +66364,11 @@ var init_supervisor = __esm({
|
|
|
65938
66364
|
running = false;
|
|
65939
66365
|
machineId = null;
|
|
65940
66366
|
machineOrgId = null;
|
|
66367
|
+
// machines.created_by — the machine owner. The local control socket's profile
|
|
66368
|
+
// commands are authorized against it (requester must BE the owner); kept
|
|
66369
|
+
// fresh via bootstrap + refreshMachineConfig. Null until bootstrap → the
|
|
66370
|
+
// local control plane fails closed.
|
|
66371
|
+
machineCreatedBy = null;
|
|
65941
66372
|
machineLlmSource = "parall";
|
|
65942
66373
|
// Whether this machine contributes its local clips as a hub provider. The
|
|
65943
66374
|
// org admin toggles it via PATCH /machines/{id}/provider-enabled; default true.
|
|
@@ -65956,6 +66387,7 @@ var init_supervisor = __esm({
|
|
|
65956
66387
|
// browserProfilePool replaces the old single browserProfileManager.
|
|
65957
66388
|
healthGate = null;
|
|
65958
66389
|
browserProfilePool = null;
|
|
66390
|
+
localControl = null;
|
|
65959
66391
|
clipManager = null;
|
|
65960
66392
|
clipProvider = null;
|
|
65961
66393
|
clipReconcileTimer = null;
|
|
@@ -66009,7 +66441,7 @@ var init_supervisor = __esm({
|
|
|
66009
66441
|
this.migrateFlatLayout();
|
|
66010
66442
|
if (process.env.PRLL_CLIP_RUNTIME_ENABLED === "true") {
|
|
66011
66443
|
this.browserProfilePool = new BrowserProfilePool({
|
|
66012
|
-
baseHomeDir:
|
|
66444
|
+
baseHomeDir: path21.join(this.config.rootStateDir, "bb-browser"),
|
|
66013
66445
|
log: this.log,
|
|
66014
66446
|
reportStatus: (profileId, status, errorMsg, generation) => {
|
|
66015
66447
|
this.client.reportBrowserProfileStatus(profileId, status, errorMsg, generation).catch((err) => this.log.warn(`browser profile status report failed: ${String(err)}`));
|
|
@@ -66018,8 +66450,8 @@ var init_supervisor = __esm({
|
|
|
66018
66450
|
proxyProbeUrl: this.resolveBrowserProxyProbeUrl()
|
|
66019
66451
|
});
|
|
66020
66452
|
this.clipManager = new ClipProcessManager({
|
|
66021
|
-
clipsDir:
|
|
66022
|
-
dataDir:
|
|
66453
|
+
clipsDir: path21.join(this.config.rootStateDir, "clips"),
|
|
66454
|
+
dataDir: path21.join(this.config.rootStateDir, "clip-data"),
|
|
66023
66455
|
browserProfileManager: this.browserProfilePool,
|
|
66024
66456
|
// Execution side: nested browser dependency invokes resolve their
|
|
66025
66457
|
// binding and route through the hub (no local shortcut).
|
|
@@ -66039,6 +66471,7 @@ var init_supervisor = __esm({
|
|
|
66039
66471
|
await this.applyClipProviderState();
|
|
66040
66472
|
this.startClipReconcileTimer();
|
|
66041
66473
|
}
|
|
66474
|
+
this.localControl = await startLocalProfileControl(this.localProfileControlDeps());
|
|
66042
66475
|
void this.detectAndReportRuntimes(true);
|
|
66043
66476
|
this.runtimeDetectTimer = setInterval(() => {
|
|
66044
66477
|
void this.detectAndReportRuntimes(false);
|
|
@@ -66164,6 +66597,10 @@ var init_supervisor = __esm({
|
|
|
66164
66597
|
}
|
|
66165
66598
|
exits.push(this.terminateChild(state));
|
|
66166
66599
|
}
|
|
66600
|
+
if (this.localControl) {
|
|
66601
|
+
exits.push(this.localControl.stop());
|
|
66602
|
+
this.localControl = null;
|
|
66603
|
+
}
|
|
66167
66604
|
if (this.clipProvider) {
|
|
66168
66605
|
exits.push(this.clipProvider.disconnect());
|
|
66169
66606
|
this.clipProvider = null;
|
|
@@ -66192,6 +66629,7 @@ var init_supervisor = __esm({
|
|
|
66192
66629
|
const machine = await this.client.getMachineSelf();
|
|
66193
66630
|
this.machineId = machine.id;
|
|
66194
66631
|
this.machineOrgId = machine.org_id;
|
|
66632
|
+
this.machineCreatedBy = machine.created_by ?? null;
|
|
66195
66633
|
this.machineLlmSource = machine.llm_source ?? "parall";
|
|
66196
66634
|
this.machineProviderEnabled = machine.provider_enabled ?? true;
|
|
66197
66635
|
this.machineClipProviderUrl = machine.clip_provider_url ?? null;
|
|
@@ -66365,12 +66803,12 @@ var init_supervisor = __esm({
|
|
|
66365
66803
|
*/
|
|
66366
66804
|
migrateFlatLayout() {
|
|
66367
66805
|
const root = this.config.rootStateDir;
|
|
66368
|
-
const agentsDir =
|
|
66369
|
-
const flatWorkspace =
|
|
66806
|
+
const agentsDir = path21.join(root, "agents");
|
|
66807
|
+
const flatWorkspace = path21.join(root, "workspace");
|
|
66370
66808
|
if (!fs13.existsSync(flatWorkspace) || fs13.existsSync(agentsDir))
|
|
66371
66809
|
return;
|
|
66372
66810
|
let ownerAgentId;
|
|
66373
|
-
const sessionsDir =
|
|
66811
|
+
const sessionsDir = path21.join(root, "sessions");
|
|
66374
66812
|
if (fs13.existsSync(sessionsDir)) {
|
|
66375
66813
|
try {
|
|
66376
66814
|
for (const file of fs13.readdirSync(sessionsDir)) {
|
|
@@ -66387,13 +66825,13 @@ var init_supervisor = __esm({
|
|
|
66387
66825
|
}
|
|
66388
66826
|
}
|
|
66389
66827
|
const targetId = ownerAgentId ?? "_orphan";
|
|
66390
|
-
const targetDir =
|
|
66828
|
+
const targetDir = path21.join(agentsDir, targetId);
|
|
66391
66829
|
try {
|
|
66392
66830
|
fs13.mkdirSync(targetDir, { recursive: true });
|
|
66393
66831
|
for (const sub of ["workspace", "sessions", "dispatch-context"]) {
|
|
66394
|
-
const src =
|
|
66832
|
+
const src = path21.join(root, sub);
|
|
66395
66833
|
if (fs13.existsSync(src)) {
|
|
66396
|
-
fs13.renameSync(src,
|
|
66834
|
+
fs13.renameSync(src, path21.join(targetDir, sub));
|
|
66397
66835
|
}
|
|
66398
66836
|
}
|
|
66399
66837
|
this.log.info(`migrated legacy flat state \u2192 agents/${targetId}/`);
|
|
@@ -66527,6 +66965,28 @@ var init_supervisor = __esm({
|
|
|
66527
66965
|
const op = () => this.handleBrowserProfileLifecycle(data, sinceSeq);
|
|
66528
66966
|
return data.action === "open" ? this.enqueueBrowserProfileRevive(data.profile_id, op) : this.enqueueBrowserProfileOp(data.profile_id, op);
|
|
66529
66967
|
}
|
|
66968
|
+
/**
|
|
66969
|
+
* What the supervisor lends the local control plane: identity, pool, queues.
|
|
66970
|
+
* Getters, not values — owner and pool both change over the daemon's life
|
|
66971
|
+
* (bootstrap / refresh / provider state), so the handler must read what is
|
|
66972
|
+
* true AT CALL TIME; a snapshot could authorize against a stale owner.
|
|
66973
|
+
*
|
|
66974
|
+
* One definition, used by both `run()` and the authorization tests, so the
|
|
66975
|
+
* matrix under test is wired exactly like production.
|
|
66976
|
+
*/
|
|
66977
|
+
localProfileControlDeps() {
|
|
66978
|
+
return {
|
|
66979
|
+
log: this.log,
|
|
66980
|
+
machineId: () => this.machineId,
|
|
66981
|
+
orgId: () => this.machineOrgId,
|
|
66982
|
+
owner: () => this.machineCreatedBy,
|
|
66983
|
+
pool: () => this.browserProfilePool,
|
|
66984
|
+
listProfiles: () => this.client.listMachineBrowserProfiles(),
|
|
66985
|
+
enqueueRevive: (id, op) => this.enqueueBrowserProfileRevive(id, op),
|
|
66986
|
+
enqueueOp: (id, op) => this.enqueueBrowserProfileOp(id, op),
|
|
66987
|
+
wipeBeforeRevive: (pool, id, resetGen, gen) => this.wipeBeforeRevive(pool, id, resetGen, gen)
|
|
66988
|
+
};
|
|
66989
|
+
}
|
|
66530
66990
|
enqueueBrowserProfileOp(profileId, op) {
|
|
66531
66991
|
const previous = this.browserProfileOpQueues.get(profileId) ?? Promise.resolve();
|
|
66532
66992
|
const next = previous.catch(() => {
|
|
@@ -66689,7 +67149,7 @@ var init_supervisor = __esm({
|
|
|
66689
67149
|
return this.runtimeDetectInFlight;
|
|
66690
67150
|
}
|
|
66691
67151
|
machineClipToConfig(clip) {
|
|
66692
|
-
const clipPath =
|
|
67152
|
+
const clipPath = path21.join(this.config.rootStateDir, "clips", clip.alias);
|
|
66693
67153
|
return {
|
|
66694
67154
|
clipId: clip.clip_id,
|
|
66695
67155
|
name: clip.alias,
|
|
@@ -66755,7 +67215,7 @@ var init_supervisor = __esm({
|
|
|
66755
67215
|
if (!sourceRef) {
|
|
66756
67216
|
throw new Error(`registry clip "${config.name}" is missing source_ref`);
|
|
66757
67217
|
}
|
|
66758
|
-
const expectedPath =
|
|
67218
|
+
const expectedPath = path21.join(this.config.rootStateDir, "clips", config.name);
|
|
66759
67219
|
const localVersion = this.readInstalledClipVersion(expectedPath);
|
|
66760
67220
|
if (localVersion && (!config.version || localVersion === config.version)) {
|
|
66761
67221
|
return { ...config, path: expectedPath, source: expectedPath };
|
|
@@ -66773,7 +67233,7 @@ var init_supervisor = __esm({
|
|
|
66773
67233
|
const result = await installClip({
|
|
66774
67234
|
source,
|
|
66775
67235
|
alias: config.name,
|
|
66776
|
-
clipsDir:
|
|
67236
|
+
clipsDir: path21.join(this.config.rootStateDir, "clips"),
|
|
66777
67237
|
registryUrl: process.env.PRLL_PINIX_REGISTRY_URL?.trim() || void 0
|
|
66778
67238
|
});
|
|
66779
67239
|
this.log.info(`clip ensured: ${result.alias} v${result.version} at ${result.path}`);
|
|
@@ -66788,7 +67248,7 @@ var init_supervisor = __esm({
|
|
|
66788
67248
|
readInstalledClipVersion(dir) {
|
|
66789
67249
|
for (const file of ["clip.json", "package.json"]) {
|
|
66790
67250
|
try {
|
|
66791
|
-
const raw = fs13.readFileSync(
|
|
67251
|
+
const raw = fs13.readFileSync(path21.join(dir, file), "utf-8");
|
|
66792
67252
|
const parsed = JSON.parse(raw);
|
|
66793
67253
|
if (typeof parsed.version === "string" && parsed.version.trim()) {
|
|
66794
67254
|
return parsed.version.trim();
|
|
@@ -66857,6 +67317,7 @@ var init_supervisor = __esm({
|
|
|
66857
67317
|
async refreshMachineConfig() {
|
|
66858
67318
|
try {
|
|
66859
67319
|
const machine = await this.client.getMachineSelf();
|
|
67320
|
+
this.machineCreatedBy = machine.created_by ?? null;
|
|
66860
67321
|
const newSource = machine.llm_source ?? "parall";
|
|
66861
67322
|
if (newSource !== this.machineLlmSource) {
|
|
66862
67323
|
this.log.info(`machine config refreshed: llm_source ${this.machineLlmSource} \u2192 ${newSource}`);
|
|
@@ -67511,7 +67972,7 @@ var init_daemon_main = __esm({
|
|
|
67511
67972
|
init_daemon_paths();
|
|
67512
67973
|
init_daemon_update_mode();
|
|
67513
67974
|
import * as fs14 from "node:fs";
|
|
67514
|
-
import * as
|
|
67975
|
+
import * as path22 from "node:path";
|
|
67515
67976
|
var UPDATE_EXIT_CODE2 = 42;
|
|
67516
67977
|
function formatError2(reason) {
|
|
67517
67978
|
if (reason instanceof Error) {
|
|
@@ -67536,7 +67997,7 @@ function clearRunningMarker(markerPath) {
|
|
|
67536
67997
|
}
|
|
67537
67998
|
function prepareDaemonBootstrap(env = process.env, args = process.argv.slice(2)) {
|
|
67538
67999
|
const bundleDir = resolveBundleDir(env);
|
|
67539
|
-
const runningMarker =
|
|
68000
|
+
const runningMarker = path22.join(bundleDir, "daemon-running");
|
|
67540
68001
|
const lifecycleMarkerEnabled = args.length === 0 && !isSelfUpdateDisabledByEnv(env) && isSelfUpdateManaged(bundleDir, env);
|
|
67541
68002
|
if (!lifecycleMarkerEnabled) {
|
|
67542
68003
|
return { lifecycleMarkerEnabled: false, runningMarker, uncleanPrevExit: false };
|