@parall/daemon 1.42.1 → 1.44.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundle/manifest.json +15 -11
- package/bundle/parall-browser-pod.js +30 -17
- package/bundle/parall-channel-exec.js +224 -0
- package/bundle/parall-claude-agent.js +1847 -1470
- package/bundle/parall-codex-agent.js +1887 -1505
- package/bundle/parall-daemon.js +388 -216
- package/dist/clip-runtime/hub-client.d.ts +1 -1
- package/dist/clip-runtime/hub-client.js +1 -1
- package/dist/clip-runtime/process-manager.d.ts +2 -2
- package/dist/clip-runtime/process-manager.js +2 -2
- package/dist/config.d.ts +9 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +5 -0
- package/dist/home-isolation.d.ts +68 -0
- package/dist/home-isolation.d.ts.map +1 -0
- package/dist/home-isolation.js +130 -0
- package/dist/runtimes.d.ts +7 -0
- package/dist/runtimes.d.ts.map +1 -1
- package/dist/runtimes.js +20 -0
- package/dist/supervisor.d.ts +8 -1
- package/dist/supervisor.d.ts.map +1 -1
- package/dist/supervisor.js +97 -45
- package/package.json +6 -6
package/bundle/parall-daemon.js
CHANGED
|
@@ -122,63 +122,6 @@ var init_lane_key = __esm({
|
|
|
122
122
|
}
|
|
123
123
|
});
|
|
124
124
|
|
|
125
|
-
// ts/agent-core/dist/session-state.js
|
|
126
|
-
var init_session_state = __esm({
|
|
127
|
-
"ts/agent-core/dist/session-state.js"() {
|
|
128
|
-
"use strict";
|
|
129
|
-
}
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
// ts/agent-core/dist/routing.js
|
|
133
|
-
var init_routing = __esm({
|
|
134
|
-
"ts/agent-core/dist/routing.js"() {
|
|
135
|
-
"use strict";
|
|
136
|
-
}
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
// ts/agent-core/dist/event-format.js
|
|
140
|
-
var init_event_format = __esm({
|
|
141
|
-
"ts/agent-core/dist/event-format.js"() {
|
|
142
|
-
"use strict";
|
|
143
|
-
}
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
// ts/agent-core/dist/prompt-fragments.js
|
|
147
|
-
var init_prompt_fragments = __esm({
|
|
148
|
-
"ts/agent-core/dist/prompt-fragments.js"() {
|
|
149
|
-
"use strict";
|
|
150
|
-
}
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
// ts/agent-core/dist/bridge-workspace.js
|
|
154
|
-
var init_bridge_workspace = __esm({
|
|
155
|
-
"ts/agent-core/dist/bridge-workspace.js"() {
|
|
156
|
-
"use strict";
|
|
157
|
-
}
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
// ts/agent-core/dist/dispatch-adapter.js
|
|
161
|
-
var init_dispatch_adapter = __esm({
|
|
162
|
-
"ts/agent-core/dist/dispatch-adapter.js"() {
|
|
163
|
-
"use strict";
|
|
164
|
-
}
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
// ts/agent-core/dist/logger.js
|
|
168
|
-
function createLogger(prefix) {
|
|
169
|
-
return {
|
|
170
|
-
info: (msg) => console.log(`${(/* @__PURE__ */ new Date()).toISOString()} [${prefix}] ${msg}`),
|
|
171
|
-
warn: (msg) => console.warn(`${(/* @__PURE__ */ new Date()).toISOString()} [${prefix}] ${msg}`),
|
|
172
|
-
error: (msg) => console.error(`${(/* @__PURE__ */ new Date()).toISOString()} [${prefix}] ${msg}`),
|
|
173
|
-
child: (sub) => createLogger(`${prefix}:${sub}`)
|
|
174
|
-
};
|
|
175
|
-
}
|
|
176
|
-
var init_logger = __esm({
|
|
177
|
-
"ts/agent-core/dist/logger.js"() {
|
|
178
|
-
"use strict";
|
|
179
|
-
}
|
|
180
|
-
});
|
|
181
|
-
|
|
182
125
|
// ts/sdk/dist/types.js
|
|
183
126
|
var init_types2 = __esm({
|
|
184
127
|
"ts/sdk/dist/types.js"() {
|
|
@@ -672,6 +615,7 @@ var init_client = __esm({
|
|
|
672
615
|
setTokens;
|
|
673
616
|
refreshPromise = null;
|
|
674
617
|
swimlaneName;
|
|
618
|
+
getFeatureFlagOverrides;
|
|
675
619
|
/** Auth endpoints excluded from automatic 401 refresh to prevent recursion. */
|
|
676
620
|
static AUTH_PATHS = /* @__PURE__ */ new Set([
|
|
677
621
|
"/auth/login",
|
|
@@ -702,7 +646,7 @@ var init_client = __esm({
|
|
|
702
646
|
return apiError;
|
|
703
647
|
}
|
|
704
648
|
/** Build headers common to all requests (auth, swimlane). */
|
|
705
|
-
buildHeaders(extra) {
|
|
649
|
+
buildHeaders(path19, extra) {
|
|
706
650
|
const headers = {
|
|
707
651
|
"Content-Type": "application/json",
|
|
708
652
|
...extra
|
|
@@ -713,6 +657,11 @@ var init_client = __esm({
|
|
|
713
657
|
if (this.swimlaneName) {
|
|
714
658
|
headers["X-Prll-Swimlane"] = this.swimlaneName;
|
|
715
659
|
}
|
|
660
|
+
if (path19.startsWith(API_BASE)) {
|
|
661
|
+
const overrides = this.getFeatureFlagOverrides?.();
|
|
662
|
+
if (overrides)
|
|
663
|
+
headers["X-Prll-FF-Override"] = overrides;
|
|
664
|
+
}
|
|
716
665
|
return headers;
|
|
717
666
|
}
|
|
718
667
|
constructor(options = {}) {
|
|
@@ -723,6 +672,7 @@ var init_client = __esm({
|
|
|
723
672
|
this.getRefreshToken = options.getRefreshToken;
|
|
724
673
|
this.setTokens = options.setTokens;
|
|
725
674
|
this.swimlaneName = options.swimlaneName;
|
|
675
|
+
this.getFeatureFlagOverrides = options.getFeatureFlagOverrides;
|
|
726
676
|
}
|
|
727
677
|
/**
|
|
728
678
|
* Pick the origin for a request path: wiki-service base for `/wiki/v1`
|
|
@@ -730,8 +680,8 @@ var init_client = __esm({
|
|
|
730
680
|
* is authoritative, so wiki vs api routing can't drift from how a caller
|
|
731
681
|
* happens to invoke the client.
|
|
732
682
|
*/
|
|
733
|
-
baseUrlFor(
|
|
734
|
-
return
|
|
683
|
+
baseUrlFor(path19) {
|
|
684
|
+
return path19.startsWith(WIKI_BASE) ? this.wikiBaseUrl : this.baseUrl;
|
|
735
685
|
}
|
|
736
686
|
setToken(token) {
|
|
737
687
|
this.token = token;
|
|
@@ -758,10 +708,10 @@ var init_client = __esm({
|
|
|
758
708
|
* REFRESH_THRESHOLD_S, refresh it **before** sending the request.
|
|
759
709
|
* No-op when the token is still fresh, missing, or un-parseable.
|
|
760
710
|
*/
|
|
761
|
-
async ensureFreshToken(
|
|
711
|
+
async ensureFreshToken(path19) {
|
|
762
712
|
if (!this.token || !this.getRefreshToken)
|
|
763
713
|
return;
|
|
764
|
-
const pathSuffix =
|
|
714
|
+
const pathSuffix = path19.replace(/^\/api\/v1/, "");
|
|
765
715
|
if (_ParallClient.AUTH_PATHS.has(pathSuffix))
|
|
766
716
|
return;
|
|
767
717
|
const exp = _ParallClient.decodeJwtExp(this.token);
|
|
@@ -793,11 +743,11 @@ var init_client = __esm({
|
|
|
793
743
|
this.refreshPromise = null;
|
|
794
744
|
}
|
|
795
745
|
}
|
|
796
|
-
async request(method,
|
|
746
|
+
async request(method, path19, body, query, retried = false, opts) {
|
|
797
747
|
if (!retried) {
|
|
798
|
-
await this.ensureFreshToken(
|
|
748
|
+
await this.ensureFreshToken(path19);
|
|
799
749
|
}
|
|
800
|
-
let url = `${this.baseUrlFor(
|
|
750
|
+
let url = `${this.baseUrlFor(path19)}${path19}`;
|
|
801
751
|
if (query) {
|
|
802
752
|
const params = new URLSearchParams();
|
|
803
753
|
for (const [key, value] of Object.entries(query)) {
|
|
@@ -809,7 +759,7 @@ var init_client = __esm({
|
|
|
809
759
|
if (qs)
|
|
810
760
|
url += `?${qs}`;
|
|
811
761
|
}
|
|
812
|
-
const headers = this.buildHeaders();
|
|
762
|
+
const headers = this.buildHeaders(path19);
|
|
813
763
|
const timeoutSignal = AbortSignal.timeout(opts?.timeoutMs ?? 15e3);
|
|
814
764
|
const signal = opts?.signal ? AbortSignal.any([opts.signal, timeoutSignal]) : timeoutSignal;
|
|
815
765
|
let res;
|
|
@@ -827,12 +777,12 @@ var init_client = __esm({
|
|
|
827
777
|
throw _ParallClient.normalizeFetchError(err);
|
|
828
778
|
}
|
|
829
779
|
if (res.status === 401) {
|
|
830
|
-
const pathSuffix =
|
|
780
|
+
const pathSuffix = path19.replace(/^\/api\/v1/, "");
|
|
831
781
|
const isAuthPath = _ParallClient.AUTH_PATHS.has(pathSuffix);
|
|
832
782
|
if (!retried && !isAuthPath && this.getRefreshToken) {
|
|
833
783
|
const refreshed = await this.tryRefresh();
|
|
834
784
|
if (refreshed) {
|
|
835
|
-
return this.request(method,
|
|
785
|
+
return this.request(method, path19, body, query, true, opts);
|
|
836
786
|
}
|
|
837
787
|
}
|
|
838
788
|
if (this.onTokenExpired && !isAuthPath) {
|
|
@@ -862,15 +812,15 @@ var init_client = __esm({
|
|
|
862
812
|
* hit the 100 MiB cap, so a longer 5-minute timeout is used so a
|
|
863
813
|
* 50 MiB blob on a slow connection doesn't get chopped at 15 s.
|
|
864
814
|
*/
|
|
865
|
-
async multipartRequest(method,
|
|
815
|
+
async multipartRequest(method, path19, body, retried = false) {
|
|
866
816
|
if (!retried) {
|
|
867
|
-
await this.ensureFreshToken(
|
|
817
|
+
await this.ensureFreshToken(path19);
|
|
868
818
|
}
|
|
869
|
-
const { "Content-Type": _drop, ...headers } = this.buildHeaders();
|
|
819
|
+
const { "Content-Type": _drop, ...headers } = this.buildHeaders(path19);
|
|
870
820
|
void _drop;
|
|
871
821
|
let res;
|
|
872
822
|
try {
|
|
873
|
-
res = await fetch(`${this.baseUrlFor(
|
|
823
|
+
res = await fetch(`${this.baseUrlFor(path19)}${path19}`, {
|
|
874
824
|
method,
|
|
875
825
|
headers,
|
|
876
826
|
body,
|
|
@@ -880,12 +830,12 @@ var init_client = __esm({
|
|
|
880
830
|
throw _ParallClient.normalizeFetchError(err);
|
|
881
831
|
}
|
|
882
832
|
if (res.status === 401) {
|
|
883
|
-
const pathSuffix =
|
|
833
|
+
const pathSuffix = path19.replace(/^\/api\/v1/, "");
|
|
884
834
|
const isAuthPath = _ParallClient.AUTH_PATHS.has(pathSuffix);
|
|
885
835
|
if (!retried && !isAuthPath && this.getRefreshToken) {
|
|
886
836
|
const refreshed = await this.tryRefresh();
|
|
887
837
|
if (refreshed) {
|
|
888
|
-
return this.multipartRequest(method,
|
|
838
|
+
return this.multipartRequest(method, path19, body, true);
|
|
889
839
|
}
|
|
890
840
|
}
|
|
891
841
|
if (this.onTokenExpired && !isAuthPath) {
|
|
@@ -1589,8 +1539,8 @@ var init_client = __esm({
|
|
|
1589
1539
|
async requestMachineUpdate(orgId, machineId, mandatory = false) {
|
|
1590
1540
|
await this.request("POST", ENDPOINTS.MACHINE_REQUEST_UPDATE(orgId, machineId), { mandatory });
|
|
1591
1541
|
}
|
|
1592
|
-
async browseMachineFilesystem(orgId, machineId,
|
|
1593
|
-
return this.request("POST", ENDPOINTS.MACHINE_BROWSE(orgId, machineId), { path:
|
|
1542
|
+
async browseMachineFilesystem(orgId, machineId, path19) {
|
|
1543
|
+
return this.request("POST", ENDPOINTS.MACHINE_BROWSE(orgId, machineId), { path: path19 }, void 0, false, { timeoutMs: 15e3 });
|
|
1594
1544
|
}
|
|
1595
1545
|
/** Create a new machine key. Returns the raw key string (shown once) + metadata. */
|
|
1596
1546
|
async createMachineKey(orgId, machineId, name) {
|
|
@@ -1675,7 +1625,6 @@ var init_client = __esm({
|
|
|
1675
1625
|
async steerDispatch(orgId, req) {
|
|
1676
1626
|
return this.request("POST", ENDPOINTS.DISPATCH_STEER(orgId), req);
|
|
1677
1627
|
}
|
|
1678
|
-
/** End a turn: no_action sweep of the lane's members + lane release + re-drive check. */
|
|
1679
1628
|
async completeDispatch(orgId, req) {
|
|
1680
1629
|
return this.request("POST", ENDPOINTS.DISPATCH_COMPLETE(orgId), req);
|
|
1681
1630
|
}
|
|
@@ -1683,6 +1632,10 @@ var init_client = __esm({
|
|
|
1683
1632
|
* End a turn for a lane-less runtime: resolve the turn's folded WorkItems
|
|
1684
1633
|
* by source — broad-cover to the turn's reply Effect when one exists,
|
|
1685
1634
|
* no_action sweep otherwise. Idempotent.
|
|
1635
|
+
*
|
|
1636
|
+
* @deprecated Legacy ok-only alias — use {@link completeDispatch} with the
|
|
1637
|
+
* `sources` form, which also carries `turn_outcome`. The endpoint retires
|
|
1638
|
+
* at S3b (dispatch-convergence-design.md §3).
|
|
1686
1639
|
*/
|
|
1687
1640
|
async completeDispatchSources(orgId, req) {
|
|
1688
1641
|
return this.request("POST", ENDPOINTS.DISPATCH_COMPLETE_SOURCES(orgId), req);
|
|
@@ -1711,7 +1664,7 @@ var init_client = __esm({
|
|
|
1711
1664
|
if (currentVersion !== void 0) {
|
|
1712
1665
|
extra["If-None-Match"] = currentVersion;
|
|
1713
1666
|
}
|
|
1714
|
-
const headers = this.buildHeaders(extra);
|
|
1667
|
+
const headers = this.buildHeaders(ENDPOINTS.PLATFORM_CONFIG, extra);
|
|
1715
1668
|
let res;
|
|
1716
1669
|
try {
|
|
1717
1670
|
res = await fetch(url, {
|
|
@@ -2159,8 +2112,8 @@ var init_client = __esm({
|
|
|
2159
2112
|
async deleteWikiRestriction(orgId, wikiId, restrictionId) {
|
|
2160
2113
|
await this.request("DELETE", ENDPOINTS.WIKI_RESTRICTION(orgId, wikiId, restrictionId));
|
|
2161
2114
|
}
|
|
2162
|
-
async getWikiAccessStatus(orgId, wikiId,
|
|
2163
|
-
return this.request("GET", ENDPOINTS.WIKI_ACCESS_STATUS(orgId, wikiId), void 0,
|
|
2115
|
+
async getWikiAccessStatus(orgId, wikiId, path19) {
|
|
2116
|
+
return this.request("GET", ENDPOINTS.WIKI_ACCESS_STATUS(orgId, wikiId), void 0, path19 ? { path: path19 } : void 0);
|
|
2164
2117
|
}
|
|
2165
2118
|
async createWikiAccessRequest(orgId, wikiId, data) {
|
|
2166
2119
|
await this.request("POST", ENDPOINTS.WIKI_ACCESS_REQUESTS(orgId, wikiId), data);
|
|
@@ -2169,14 +2122,14 @@ var init_client = __esm({
|
|
|
2169
2122
|
async getWikiCommits(orgId, wikiId, params) {
|
|
2170
2123
|
return this.request("GET", ENDPOINTS.WIKI_COMMITS(orgId, wikiId), void 0, params);
|
|
2171
2124
|
}
|
|
2172
|
-
async getWikiFileCommits(orgId, wikiId,
|
|
2125
|
+
async getWikiFileCommits(orgId, wikiId, path19, params) {
|
|
2173
2126
|
return this.request("GET", ENDPOINTS.WIKI_FILE_COMMITS(orgId, wikiId), void 0, {
|
|
2174
|
-
path:
|
|
2127
|
+
path: path19,
|
|
2175
2128
|
...params
|
|
2176
2129
|
});
|
|
2177
2130
|
}
|
|
2178
|
-
async getWikiBlame(orgId, wikiId,
|
|
2179
|
-
return this.request("GET", ENDPOINTS.WIKI_BLAME(orgId, wikiId), void 0, { path:
|
|
2131
|
+
async getWikiBlame(orgId, wikiId, path19, ref) {
|
|
2132
|
+
return this.request("GET", ENDPOINTS.WIKI_BLAME(orgId, wikiId), void 0, { path: path19, ref });
|
|
2180
2133
|
}
|
|
2181
2134
|
// ---- Wiki Operations (audit log) ----
|
|
2182
2135
|
async getWikiOperations(orgId, wikiId, params) {
|
|
@@ -2824,10 +2777,69 @@ var init_lane_ledger = __esm({
|
|
|
2824
2777
|
});
|
|
2825
2778
|
|
|
2826
2779
|
// ts/agent-core/dist/gateway-lane-flow.js
|
|
2780
|
+
var TYPED_BACKOFF_CAP_MS;
|
|
2827
2781
|
var init_gateway_lane_flow = __esm({
|
|
2828
2782
|
"ts/agent-core/dist/gateway-lane-flow.js"() {
|
|
2829
2783
|
"use strict";
|
|
2830
2784
|
init_lane_ledger();
|
|
2785
|
+
TYPED_BACKOFF_CAP_MS = 5 * 6e4;
|
|
2786
|
+
}
|
|
2787
|
+
});
|
|
2788
|
+
|
|
2789
|
+
// ts/agent-core/dist/session-state.js
|
|
2790
|
+
var init_session_state = __esm({
|
|
2791
|
+
"ts/agent-core/dist/session-state.js"() {
|
|
2792
|
+
"use strict";
|
|
2793
|
+
}
|
|
2794
|
+
});
|
|
2795
|
+
|
|
2796
|
+
// ts/agent-core/dist/routing.js
|
|
2797
|
+
var init_routing = __esm({
|
|
2798
|
+
"ts/agent-core/dist/routing.js"() {
|
|
2799
|
+
"use strict";
|
|
2800
|
+
}
|
|
2801
|
+
});
|
|
2802
|
+
|
|
2803
|
+
// ts/agent-core/dist/event-format.js
|
|
2804
|
+
var init_event_format = __esm({
|
|
2805
|
+
"ts/agent-core/dist/event-format.js"() {
|
|
2806
|
+
"use strict";
|
|
2807
|
+
}
|
|
2808
|
+
});
|
|
2809
|
+
|
|
2810
|
+
// ts/agent-core/dist/prompt-fragments.js
|
|
2811
|
+
var init_prompt_fragments = __esm({
|
|
2812
|
+
"ts/agent-core/dist/prompt-fragments.js"() {
|
|
2813
|
+
"use strict";
|
|
2814
|
+
}
|
|
2815
|
+
});
|
|
2816
|
+
|
|
2817
|
+
// ts/agent-core/dist/bridge-workspace.js
|
|
2818
|
+
var init_bridge_workspace = __esm({
|
|
2819
|
+
"ts/agent-core/dist/bridge-workspace.js"() {
|
|
2820
|
+
"use strict";
|
|
2821
|
+
}
|
|
2822
|
+
});
|
|
2823
|
+
|
|
2824
|
+
// ts/agent-core/dist/dispatch-adapter.js
|
|
2825
|
+
var init_dispatch_adapter = __esm({
|
|
2826
|
+
"ts/agent-core/dist/dispatch-adapter.js"() {
|
|
2827
|
+
"use strict";
|
|
2828
|
+
}
|
|
2829
|
+
});
|
|
2830
|
+
|
|
2831
|
+
// ts/agent-core/dist/logger.js
|
|
2832
|
+
function createLogger(prefix) {
|
|
2833
|
+
return {
|
|
2834
|
+
info: (msg) => console.log(`${(/* @__PURE__ */ new Date()).toISOString()} [${prefix}] ${msg}`),
|
|
2835
|
+
warn: (msg) => console.warn(`${(/* @__PURE__ */ new Date()).toISOString()} [${prefix}] ${msg}`),
|
|
2836
|
+
error: (msg) => console.error(`${(/* @__PURE__ */ new Date()).toISOString()} [${prefix}] ${msg}`),
|
|
2837
|
+
child: (sub) => createLogger(`${prefix}:${sub}`)
|
|
2838
|
+
};
|
|
2839
|
+
}
|
|
2840
|
+
var init_logger = __esm({
|
|
2841
|
+
"ts/agent-core/dist/logger.js"() {
|
|
2842
|
+
"use strict";
|
|
2831
2843
|
}
|
|
2832
2844
|
});
|
|
2833
2845
|
|
|
@@ -20510,9 +20522,9 @@ var require_getMachineId_linux = __commonJS({
|
|
|
20510
20522
|
var api_1 = (init_esm(), __toCommonJS(esm_exports));
|
|
20511
20523
|
async function getMachineId() {
|
|
20512
20524
|
const paths = ["/etc/machine-id", "/var/lib/dbus/machine-id"];
|
|
20513
|
-
for (const
|
|
20525
|
+
for (const path19 of paths) {
|
|
20514
20526
|
try {
|
|
20515
|
-
const result = await fs_1.promises.readFile(
|
|
20527
|
+
const result = await fs_1.promises.readFile(path19, { encoding: "utf8" });
|
|
20516
20528
|
return result.trim();
|
|
20517
20529
|
} catch (e) {
|
|
20518
20530
|
api_1.diag.debug(`error reading machine id: ${e}`);
|
|
@@ -20722,7 +20734,7 @@ var require_ProcessDetectorSync = __commonJS({
|
|
|
20722
20734
|
var api_1 = (init_esm(), __toCommonJS(esm_exports));
|
|
20723
20735
|
var semantic_conventions_1 = (init_esm2(), __toCommonJS(esm_exports2));
|
|
20724
20736
|
var Resource_1 = require_Resource();
|
|
20725
|
-
var
|
|
20737
|
+
var os8 = __require("os");
|
|
20726
20738
|
var ProcessDetectorSync = class {
|
|
20727
20739
|
detect(_config) {
|
|
20728
20740
|
const attributes = {
|
|
@@ -20742,7 +20754,7 @@ var require_ProcessDetectorSync = __commonJS({
|
|
|
20742
20754
|
attributes[semantic_conventions_1.SEMRESATTRS_PROCESS_COMMAND] = process.argv[1];
|
|
20743
20755
|
}
|
|
20744
20756
|
try {
|
|
20745
|
-
const userInfo =
|
|
20757
|
+
const userInfo = os8.userInfo();
|
|
20746
20758
|
attributes[semantic_conventions_1.SEMRESATTRS_PROCESS_OWNER] = userInfo.username;
|
|
20747
20759
|
} catch (e) {
|
|
20748
20760
|
api_1.diag.debug(`error obtaining process owner: ${e}`);
|
|
@@ -23915,7 +23927,7 @@ function appendRootPathToUrlIfNeeded(url) {
|
|
|
23915
23927
|
return void 0;
|
|
23916
23928
|
}
|
|
23917
23929
|
}
|
|
23918
|
-
function appendResourcePathToUrl(url,
|
|
23930
|
+
function appendResourcePathToUrl(url, path19) {
|
|
23919
23931
|
try {
|
|
23920
23932
|
new URL(url);
|
|
23921
23933
|
} catch (_a) {
|
|
@@ -23925,11 +23937,11 @@ function appendResourcePathToUrl(url, path18) {
|
|
|
23925
23937
|
if (!url.endsWith("/")) {
|
|
23926
23938
|
url = url + "/";
|
|
23927
23939
|
}
|
|
23928
|
-
url +=
|
|
23940
|
+
url += path19;
|
|
23929
23941
|
try {
|
|
23930
23942
|
new URL(url);
|
|
23931
23943
|
} catch (_b) {
|
|
23932
|
-
diag2.warn("Configuration: Provided URL appended with '" +
|
|
23944
|
+
diag2.warn("Configuration: Provided URL appended with '" + path19 + "' is not a valid URL, using 'undefined' instead of '" + url + "'");
|
|
23933
23945
|
return void 0;
|
|
23934
23946
|
}
|
|
23935
23947
|
return url;
|
|
@@ -29390,6 +29402,20 @@ var init_platform_config = __esm({
|
|
|
29390
29402
|
}
|
|
29391
29403
|
});
|
|
29392
29404
|
|
|
29405
|
+
// ts/agent-core/dist/channel-capability.js
|
|
29406
|
+
var init_channel_capability = __esm({
|
|
29407
|
+
"ts/agent-core/dist/channel-capability.js"() {
|
|
29408
|
+
"use strict";
|
|
29409
|
+
}
|
|
29410
|
+
});
|
|
29411
|
+
|
|
29412
|
+
// ts/agent-core/dist/channel-token.js
|
|
29413
|
+
var init_channel_token = __esm({
|
|
29414
|
+
"ts/agent-core/dist/channel-token.js"() {
|
|
29415
|
+
"use strict";
|
|
29416
|
+
}
|
|
29417
|
+
});
|
|
29418
|
+
|
|
29393
29419
|
// ts/agent-core/dist/skills/parall-platform.js
|
|
29394
29420
|
var init_parall_platform = __esm({
|
|
29395
29421
|
"ts/agent-core/dist/skills/parall-platform.js"() {
|
|
@@ -29458,6 +29484,7 @@ var init_dist2 = __esm({
|
|
|
29458
29484
|
init_provider_config();
|
|
29459
29485
|
init_types();
|
|
29460
29486
|
init_lane_key();
|
|
29487
|
+
init_gateway_lane_flow();
|
|
29461
29488
|
init_session_state();
|
|
29462
29489
|
init_routing();
|
|
29463
29490
|
init_event_format();
|
|
@@ -29467,6 +29494,8 @@ var init_dist2 = __esm({
|
|
|
29467
29494
|
init_logger();
|
|
29468
29495
|
init_gateway_base();
|
|
29469
29496
|
init_platform_config();
|
|
29497
|
+
init_channel_capability();
|
|
29498
|
+
init_channel_token();
|
|
29470
29499
|
init_skills();
|
|
29471
29500
|
init_telemetry();
|
|
29472
29501
|
}
|
|
@@ -29477,6 +29506,7 @@ var config_exports = {};
|
|
|
29477
29506
|
__export(config_exports, {
|
|
29478
29507
|
agentClaudeCredentialsFileFor: () => agentClaudeCredentialsFileFor,
|
|
29479
29508
|
agentClaudeHomeFor: () => agentClaudeHomeFor,
|
|
29509
|
+
agentHomeDirFor: () => agentHomeDirFor,
|
|
29480
29510
|
agentStateDirFor: () => agentStateDirFor,
|
|
29481
29511
|
agentWorkspaceDirFor: () => agentWorkspaceDirFor,
|
|
29482
29512
|
daemonConfigDir: () => daemonConfigDir,
|
|
@@ -29563,7 +29593,8 @@ function resolveClaudeDaemonConfig(env = process.env) {
|
|
|
29563
29593
|
updateCdnUrl: env.PRLL_DAEMON_UPDATE_CDN_URL?.trim() || ((env.PRLL_DAEMON_UPDATE_CHANNEL?.trim() ?? "production") === "staging" ? "https://releases.staging.prll.sh/daemon/staging" : "https://releases.parall.com/daemon/production"),
|
|
29564
29594
|
updateIntervalMs: parseMsAllowZero(env.PRLL_DAEMON_UPDATE_INTERVAL_MS, 6 * 60 * 6e4),
|
|
29565
29595
|
updateDisabled: env.PRLL_DAEMON_UPDATE_DISABLED === "true" || !!env.KUBERNETES_SERVICE_HOST,
|
|
29566
|
-
updateConfirmDelayMs: parseMsAllowZero(env.PRLL_DAEMON_UPDATE_CONFIRM_DELAY_MS?.trim() || void 0, 6e4)
|
|
29596
|
+
updateConfirmDelayMs: parseMsAllowZero(env.PRLL_DAEMON_UPDATE_CONFIRM_DELAY_MS?.trim() || void 0, 6e4),
|
|
29597
|
+
homeIsolationDisabled: env.PRLL_DAEMON_HOME_ISOLATION?.trim() === "0"
|
|
29567
29598
|
};
|
|
29568
29599
|
}
|
|
29569
29600
|
function assertSafeAgentId(agentId) {
|
|
@@ -29587,6 +29618,9 @@ function agentClaudeCredentialsFileFor(agentClaudeHome) {
|
|
|
29587
29618
|
function agentWorkspaceDirFor(rootStateDir, agentId) {
|
|
29588
29619
|
return path3.join(rootStateDir, "agents", assertSafeAgentId(agentId), "workspace");
|
|
29589
29620
|
}
|
|
29621
|
+
function agentHomeDirFor(rootStateDir, agentId) {
|
|
29622
|
+
return path3.join(rootStateDir, "agents", assertSafeAgentId(agentId), "home");
|
|
29623
|
+
}
|
|
29590
29624
|
function resolveUpdateSigningEnabled(env = process.env) {
|
|
29591
29625
|
return env.PRLL_DAEMON_SIGNING_DISABLED !== "1";
|
|
29592
29626
|
}
|
|
@@ -31101,6 +31135,7 @@ var init_manifest = __esm({
|
|
|
31101
31135
|
|
|
31102
31136
|
// ts/daemon/dist/runtimes.js
|
|
31103
31137
|
import * as fs7 from "node:fs";
|
|
31138
|
+
import * as os4 from "node:os";
|
|
31104
31139
|
import * as path9 from "node:path";
|
|
31105
31140
|
function buildStandardEnv(baseEnv, agentId, orgId, apiKey, dirs, pc) {
|
|
31106
31141
|
const env = { ...baseEnv };
|
|
@@ -31113,6 +31148,8 @@ function buildStandardEnv(baseEnv, agentId, orgId, apiKey, dirs, pc) {
|
|
|
31113
31148
|
env.PRLL_WORKSPACE_DIR = dirs.workspaceDir;
|
|
31114
31149
|
if (pc)
|
|
31115
31150
|
env.PRLL_PROVIDER_CONFIG = JSON.stringify(pc);
|
|
31151
|
+
if (dirs.homeDir)
|
|
31152
|
+
env.HOME = dirs.homeDir;
|
|
31116
31153
|
delete env.PRLL_DAEMON_MODE;
|
|
31117
31154
|
return env;
|
|
31118
31155
|
}
|
|
@@ -31158,6 +31195,8 @@ var init_runtimes = __esm({
|
|
|
31158
31195
|
const env = buildStandardEnv(baseEnv, agentId, orgId, apiKey, dirs, pc);
|
|
31159
31196
|
if (baseEnv.KUBERNETES_SERVICE_HOST || llmSource(pc) !== "runtime_auth") {
|
|
31160
31197
|
env.PRLL_CODEX_HOME = path9.join(dirs.stateDir, ".codex");
|
|
31198
|
+
} else if (dirs.homeDir && !env.CODEX_HOME) {
|
|
31199
|
+
env.CODEX_HOME = path9.join(baseEnv.HOME || os4.homedir(), ".codex");
|
|
31161
31200
|
}
|
|
31162
31201
|
return env;
|
|
31163
31202
|
}
|
|
@@ -32408,7 +32447,7 @@ var init_process_manager = __esm({
|
|
|
32408
32447
|
* (GetBindings), then forward the invoke through the hub (Invoke) to the bound
|
|
32409
32448
|
* BrowserProfile's host. No local shortcut, no fallback — unbound is rejected.
|
|
32410
32449
|
* The execution daemon never verifies clip_token; the hub does.
|
|
32411
|
-
* See docs/engineering-design/browser-profile-clip-integration.md §11.3.
|
|
32450
|
+
* See docs/archive/engineering-design/browser-profile-clip-integration.md §11.3.
|
|
32412
32451
|
*/
|
|
32413
32452
|
async invokeDependency(clipName, command, input, context2) {
|
|
32414
32453
|
if (!isBrowserDependencyName(clipName)) {
|
|
@@ -32441,7 +32480,7 @@ var init_process_manager = __esm({
|
|
|
32441
32480
|
* synthetic "browser" clip). The hub forwards clip_token as the PLAINTEXT
|
|
32442
32481
|
* browser_profile_id, which the host daemon uses directly as the bb-browser
|
|
32443
32482
|
* account. Only daemons that host BrowserProfiles register this capability.
|
|
32444
|
-
* See docs/engineering-design/browser-profile-clip-integration.md §11.2.
|
|
32483
|
+
* See docs/archive/engineering-design/browser-profile-clip-integration.md §11.2.
|
|
32445
32484
|
*/
|
|
32446
32485
|
async invokeBrowserCapability(clipToken, command, input) {
|
|
32447
32486
|
if (!this.browserProfileManager) {
|
|
@@ -34796,7 +34835,7 @@ var init_clip_runtime = __esm({
|
|
|
34796
34835
|
// ts/daemon/dist/filesystem.js
|
|
34797
34836
|
import * as fs9 from "fs";
|
|
34798
34837
|
import * as path13 from "path";
|
|
34799
|
-
import * as
|
|
34838
|
+
import * as os5 from "os";
|
|
34800
34839
|
function browseDenyReason(value) {
|
|
34801
34840
|
const normalized = path13.resolve(value).split(path13.sep).join("/");
|
|
34802
34841
|
if (normalized === "/")
|
|
@@ -34816,8 +34855,8 @@ function browseDenyReason(value) {
|
|
|
34816
34855
|
}
|
|
34817
34856
|
function syntheticRoots() {
|
|
34818
34857
|
const roots = [];
|
|
34819
|
-
const platform2 =
|
|
34820
|
-
const candidates = platform2 === "darwin" ? ["/Users",
|
|
34858
|
+
const platform2 = os5.platform();
|
|
34859
|
+
const candidates = platform2 === "darwin" ? ["/Users", os5.homedir()] : ["/home", os5.homedir()];
|
|
34821
34860
|
for (const dir of [...new Set(candidates)]) {
|
|
34822
34861
|
try {
|
|
34823
34862
|
fs9.accessSync(dir, fs9.constants.R_OK);
|
|
@@ -34913,11 +34952,108 @@ var init_filesystem = __esm({
|
|
|
34913
34952
|
}
|
|
34914
34953
|
});
|
|
34915
34954
|
|
|
34916
|
-
// ts/daemon/dist/
|
|
34917
|
-
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
34955
|
+
// ts/daemon/dist/home-isolation.js
|
|
34918
34956
|
import * as fs10 from "node:fs";
|
|
34919
|
-
import * as os5 from "node:os";
|
|
34920
34957
|
import * as path14 from "node:path";
|
|
34958
|
+
function ensureIsolatedHome(spec, agentId, log2, platform2 = process.platform) {
|
|
34959
|
+
fs10.mkdirSync(spec.homeDir, { recursive: true });
|
|
34960
|
+
const failures = [];
|
|
34961
|
+
const attempt = (label, fn) => {
|
|
34962
|
+
try {
|
|
34963
|
+
fn();
|
|
34964
|
+
} catch (err) {
|
|
34965
|
+
failures.push(`${label}: ${String(err)}`);
|
|
34966
|
+
}
|
|
34967
|
+
};
|
|
34968
|
+
attempt(".claude link", () => {
|
|
34969
|
+
fs10.mkdirSync(path14.join(spec.claudeStateRoot, ".claude"), { recursive: true });
|
|
34970
|
+
ensureLink(path14.join(spec.homeDir, ".claude"), path14.join(spec.claudeStateRoot, ".claude"), agentId, log2);
|
|
34971
|
+
});
|
|
34972
|
+
attempt(".claude.json link", () => ensureLink(path14.join(spec.homeDir, ".claude.json"), path14.join(spec.claudeStateRoot, ".claude.json"), agentId, log2));
|
|
34973
|
+
if (platform2 === "darwin") {
|
|
34974
|
+
attempt("Library/Keychains link", () => {
|
|
34975
|
+
fs10.mkdirSync(path14.join(spec.homeDir, "Library"), { recursive: true });
|
|
34976
|
+
ensureLink(path14.join(spec.homeDir, "Library", "Keychains"), path14.join(spec.systemHome, "Library", "Keychains"), agentId, log2);
|
|
34977
|
+
});
|
|
34978
|
+
}
|
|
34979
|
+
attempt(".gitconfig", () => {
|
|
34980
|
+
const gitconfig = path14.join(spec.homeDir, ".gitconfig");
|
|
34981
|
+
if (!fs10.existsSync(gitconfig)) {
|
|
34982
|
+
fs10.writeFileSync(gitconfig, `[user]
|
|
34983
|
+
name = ${gitConfigValue(spec.gitUserName)}
|
|
34984
|
+
email = ${gitConfigValue(spec.gitUserEmail)}
|
|
34985
|
+
`, { mode: 420 });
|
|
34986
|
+
log2.info(`agent ${agentId}: wrote per-agent .gitconfig (${spec.gitUserName})`);
|
|
34987
|
+
}
|
|
34988
|
+
});
|
|
34989
|
+
return failures;
|
|
34990
|
+
}
|
|
34991
|
+
function gitConfigValue(value) {
|
|
34992
|
+
const flat = value.replace(/[\r\n\t]+/g, " ").trim();
|
|
34993
|
+
return `"${flat.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
|
|
34994
|
+
}
|
|
34995
|
+
function ensureLink(linkPath, target, agentId, log2) {
|
|
34996
|
+
let existing;
|
|
34997
|
+
try {
|
|
34998
|
+
existing = fs10.lstatSync(linkPath);
|
|
34999
|
+
} catch (err) {
|
|
35000
|
+
if (err.code !== "ENOENT")
|
|
35001
|
+
throw err;
|
|
35002
|
+
}
|
|
35003
|
+
if (existing) {
|
|
35004
|
+
if (existing.isSymbolicLink()) {
|
|
35005
|
+
const current = fs10.readlinkSync(linkPath);
|
|
35006
|
+
if (path14.resolve(path14.dirname(linkPath), current) === path14.resolve(target))
|
|
35007
|
+
return;
|
|
35008
|
+
fs10.unlinkSync(linkPath);
|
|
35009
|
+
log2.info(`agent ${agentId}: relinking ${linkPath} \u2192 ${target}`);
|
|
35010
|
+
} else {
|
|
35011
|
+
const preserved = `${linkPath}.pre-isolation.${Date.now()}`;
|
|
35012
|
+
fs10.renameSync(linkPath, preserved);
|
|
35013
|
+
log2.warn(`agent ${agentId}: ${linkPath} was a real ${existing.isDirectory() ? "directory" : "file"}, not the expected passthrough symlink \u2014 preserved at ${preserved} and relinked`);
|
|
35014
|
+
}
|
|
35015
|
+
}
|
|
35016
|
+
fs10.symlinkSync(target, linkPath);
|
|
35017
|
+
}
|
|
35018
|
+
function ensureSharedCredentialLink(rootClaudeHome, agentClaudeHome, agentId, log2) {
|
|
35019
|
+
const sharedCredentials = path14.resolve(sharedClaudeCredentialsFileFor(rootClaudeHome));
|
|
35020
|
+
const agentCredentials = agentClaudeCredentialsFileFor(agentClaudeHome);
|
|
35021
|
+
const agentCredentialsDir = path14.dirname(agentCredentials);
|
|
35022
|
+
fs10.mkdirSync(path14.dirname(sharedCredentials), { recursive: true });
|
|
35023
|
+
fs10.mkdirSync(agentCredentialsDir, { recursive: true });
|
|
35024
|
+
try {
|
|
35025
|
+
const existing = fs10.lstatSync(agentCredentials);
|
|
35026
|
+
if (existing.isSymbolicLink()) {
|
|
35027
|
+
const currentTarget = fs10.readlinkSync(agentCredentials);
|
|
35028
|
+
if (path14.resolve(agentCredentialsDir, currentTarget) === sharedCredentials) {
|
|
35029
|
+
return;
|
|
35030
|
+
}
|
|
35031
|
+
fs10.unlinkSync(agentCredentials);
|
|
35032
|
+
} else if (existing.isDirectory()) {
|
|
35033
|
+
log2.warn(`agent ${agentId}: credential path is a directory, cannot link ${agentCredentials}`);
|
|
35034
|
+
return;
|
|
35035
|
+
} else {
|
|
35036
|
+
fs10.unlinkSync(agentCredentials);
|
|
35037
|
+
}
|
|
35038
|
+
} catch (err) {
|
|
35039
|
+
if (err.code !== "ENOENT") {
|
|
35040
|
+
throw err;
|
|
35041
|
+
}
|
|
35042
|
+
}
|
|
35043
|
+
fs10.symlinkSync(sharedCredentials, agentCredentials);
|
|
35044
|
+
}
|
|
35045
|
+
var init_home_isolation = __esm({
|
|
35046
|
+
"ts/daemon/dist/home-isolation.js"() {
|
|
35047
|
+
"use strict";
|
|
35048
|
+
init_config();
|
|
35049
|
+
}
|
|
35050
|
+
});
|
|
35051
|
+
|
|
35052
|
+
// ts/daemon/dist/runtime-bin-resolver.js
|
|
35053
|
+
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
35054
|
+
import * as fs11 from "node:fs";
|
|
35055
|
+
import * as os6 from "node:os";
|
|
35056
|
+
import * as path15 from "node:path";
|
|
34921
35057
|
function runtimeBinaryEnvVar(runtimeType) {
|
|
34922
35058
|
return RUNTIME_BINARIES[runtimeType]?.envVar;
|
|
34923
35059
|
}
|
|
@@ -34994,16 +35130,16 @@ function resolveRuntimeCommand(command, env, inheritedPath, primaryPath, fallbac
|
|
|
34994
35130
|
function resolveDirectPath(command) {
|
|
34995
35131
|
if (!command.includes("/") && !command.includes("\\"))
|
|
34996
35132
|
return null;
|
|
34997
|
-
const abs =
|
|
35133
|
+
const abs = path15.isAbsolute(command) ? command : path15.resolve(process.cwd(), command);
|
|
34998
35134
|
return isExecutable(abs) ? abs : null;
|
|
34999
35135
|
}
|
|
35000
35136
|
function resolveFromPath(command, pathValue, env) {
|
|
35001
35137
|
if (!pathValue || command.includes("/") || command.includes("\\"))
|
|
35002
35138
|
return null;
|
|
35003
|
-
const dirs = pathValue.split(
|
|
35139
|
+
const dirs = pathValue.split(path15.delimiter).filter(Boolean);
|
|
35004
35140
|
for (const dir of dirs) {
|
|
35005
35141
|
for (const file of commandCandidates(command, env)) {
|
|
35006
|
-
const candidate =
|
|
35142
|
+
const candidate = path15.join(dir, file);
|
|
35007
35143
|
if (isExecutable(candidate))
|
|
35008
35144
|
return { binaryPath: candidate, pathValue };
|
|
35009
35145
|
}
|
|
@@ -35042,7 +35178,7 @@ __PRLL_PATH__%s
|
|
|
35042
35178
|
if (line.startsWith("__PRLL_PATH__"))
|
|
35043
35179
|
pathValue = line.slice("__PRLL_PATH__".length);
|
|
35044
35180
|
}
|
|
35045
|
-
if (
|
|
35181
|
+
if (path15.isAbsolute(binaryPath) && isExecutable(binaryPath)) {
|
|
35046
35182
|
return { binaryPath, pathValue: pathValue || void 0 };
|
|
35047
35183
|
}
|
|
35048
35184
|
} catch {
|
|
@@ -35060,25 +35196,25 @@ function cachedCandidatePathPlan(env) {
|
|
|
35060
35196
|
return value;
|
|
35061
35197
|
}
|
|
35062
35198
|
function candidatePathPlan(env) {
|
|
35063
|
-
const home = env.HOME ||
|
|
35199
|
+
const home = env.HOME || os6.homedir();
|
|
35064
35200
|
const primaryDirs = [
|
|
35065
35201
|
...splitPath(env.PRLL_DAEMON_RUNTIME_PATH),
|
|
35066
35202
|
...splitPath(env.PRLL_DAEMON_EXTRA_PATH),
|
|
35067
|
-
|
|
35068
|
-
|
|
35069
|
-
|
|
35070
|
-
|
|
35071
|
-
|
|
35072
|
-
|
|
35073
|
-
|
|
35074
|
-
|
|
35075
|
-
|
|
35076
|
-
|
|
35077
|
-
|
|
35078
|
-
|
|
35079
|
-
|
|
35080
|
-
|
|
35081
|
-
|
|
35203
|
+
path15.dirname(process.execPath),
|
|
35204
|
+
path15.join(path15.dirname(process.execPath), "bin"),
|
|
35205
|
+
path15.resolve(path15.dirname(process.execPath), "..", "Resources", "bin"),
|
|
35206
|
+
path15.join(home, ".local", "bin"),
|
|
35207
|
+
path15.join(home, "bin"),
|
|
35208
|
+
path15.join(home, ".npm-global", "bin"),
|
|
35209
|
+
path15.join(home, "Library", "pnpm"),
|
|
35210
|
+
path15.join(home, ".local", "share", "pnpm"),
|
|
35211
|
+
path15.join(home, ".volta", "bin"),
|
|
35212
|
+
path15.join(home, ".bun", "bin"),
|
|
35213
|
+
path15.join(home, ".asdf", "shims"),
|
|
35214
|
+
path15.join(home, ".local", "share", "mise", "shims"),
|
|
35215
|
+
path15.join(home, ".mise", "shims"),
|
|
35216
|
+
path15.join(home, ".fnm", "aliases", "default", "bin"),
|
|
35217
|
+
path15.join(home, "Library", "Application Support", "fnm", "aliases", "default", "bin"),
|
|
35082
35218
|
"/opt/homebrew/bin",
|
|
35083
35219
|
"/usr/local/bin",
|
|
35084
35220
|
"/usr/bin",
|
|
@@ -35097,29 +35233,29 @@ function candidatePathPlan(env) {
|
|
|
35097
35233
|
};
|
|
35098
35234
|
}
|
|
35099
35235
|
function nvmVersionBinDirs(home) {
|
|
35100
|
-
const root =
|
|
35236
|
+
const root = path15.join(home, ".nvm", "versions", "node");
|
|
35101
35237
|
let versions;
|
|
35102
35238
|
try {
|
|
35103
|
-
versions =
|
|
35239
|
+
versions = fs11.readdirSync(root);
|
|
35104
35240
|
} catch {
|
|
35105
35241
|
return [];
|
|
35106
35242
|
}
|
|
35107
|
-
return sortVersionNamesDesc(versions).map((version) =>
|
|
35243
|
+
return sortVersionNamesDesc(versions).map((version) => path15.join(root, version, "bin"));
|
|
35108
35244
|
}
|
|
35109
35245
|
function fnmVersionBinDirs(home) {
|
|
35110
35246
|
const roots = [
|
|
35111
|
-
|
|
35112
|
-
|
|
35247
|
+
path15.join(home, ".fnm", "node-versions"),
|
|
35248
|
+
path15.join(home, "Library", "Application Support", "fnm", "node-versions")
|
|
35113
35249
|
];
|
|
35114
35250
|
const dirs = [];
|
|
35115
35251
|
for (const root of roots) {
|
|
35116
35252
|
let versions;
|
|
35117
35253
|
try {
|
|
35118
|
-
versions =
|
|
35254
|
+
versions = fs11.readdirSync(root);
|
|
35119
35255
|
} catch {
|
|
35120
35256
|
continue;
|
|
35121
35257
|
}
|
|
35122
|
-
dirs.push(...sortVersionNamesDesc(versions).map((version) =>
|
|
35258
|
+
dirs.push(...sortVersionNamesDesc(versions).map((version) => path15.join(root, version, "installation", "bin")));
|
|
35123
35259
|
}
|
|
35124
35260
|
return dirs;
|
|
35125
35261
|
}
|
|
@@ -35141,13 +35277,13 @@ function parseVersionName(value) {
|
|
|
35141
35277
|
return value.replace(/^v/i, "").split(".").map((part) => Number.parseInt(part, 10)).filter((part) => Number.isFinite(part));
|
|
35142
35278
|
}
|
|
35143
35279
|
function splitPath(value) {
|
|
35144
|
-
return value?.split(
|
|
35280
|
+
return value?.split(path15.delimiter).filter(Boolean) ?? [];
|
|
35145
35281
|
}
|
|
35146
35282
|
function mergePath(prependDirs, existing) {
|
|
35147
|
-
return unique([...prependDirs, ...splitPath(existing)]).join(
|
|
35283
|
+
return unique([...prependDirs, ...splitPath(existing)]).join(path15.delimiter);
|
|
35148
35284
|
}
|
|
35149
35285
|
function anchorResolvedPath(pathValue, resolution) {
|
|
35150
|
-
return mergePath([
|
|
35286
|
+
return mergePath([path15.dirname(resolution.binaryPath), ...splitPath(resolution.pathValue)], pathValue);
|
|
35151
35287
|
}
|
|
35152
35288
|
function commandCandidates(command, env) {
|
|
35153
35289
|
if (process.platform !== "win32")
|
|
@@ -35173,10 +35309,10 @@ function setCachedResolution(cacheKey, value) {
|
|
|
35173
35309
|
}
|
|
35174
35310
|
function isExecutable(file) {
|
|
35175
35311
|
try {
|
|
35176
|
-
const stat =
|
|
35312
|
+
const stat = fs11.statSync(file);
|
|
35177
35313
|
if (!stat.isFile())
|
|
35178
35314
|
return false;
|
|
35179
|
-
|
|
35315
|
+
fs11.accessSync(file, fs11.constants.X_OK);
|
|
35180
35316
|
return true;
|
|
35181
35317
|
} catch {
|
|
35182
35318
|
return false;
|
|
@@ -35184,7 +35320,7 @@ function isExecutable(file) {
|
|
|
35184
35320
|
}
|
|
35185
35321
|
function isDirectory(dir) {
|
|
35186
35322
|
try {
|
|
35187
|
-
return
|
|
35323
|
+
return fs11.statSync(dir).isDirectory();
|
|
35188
35324
|
} catch {
|
|
35189
35325
|
return false;
|
|
35190
35326
|
}
|
|
@@ -35301,8 +35437,8 @@ var init_runtime_detector = __esm({
|
|
|
35301
35437
|
// ts/daemon/dist/workspace.js
|
|
35302
35438
|
import { spawn as spawn5 } from "node:child_process";
|
|
35303
35439
|
import { createHash as createHash3 } from "node:crypto";
|
|
35304
|
-
import * as
|
|
35305
|
-
import * as
|
|
35440
|
+
import * as fs12 from "node:fs";
|
|
35441
|
+
import * as path16 from "node:path";
|
|
35306
35442
|
async function prepareWorkspace(opts) {
|
|
35307
35443
|
const prior = opts.attached.workspace_state;
|
|
35308
35444
|
const plan = buildWorkspacePlan(opts.attached.daemon_config, opts.defaultWorkspaceDir, prior?.config_hash);
|
|
@@ -35417,7 +35553,7 @@ function resolveWorkspaceDir(workspace, defaultWorkspaceDir) {
|
|
|
35417
35553
|
async function ensureWorkspace(plan, log2) {
|
|
35418
35554
|
const ws = plan.workspace;
|
|
35419
35555
|
if (ws.mode === "default") {
|
|
35420
|
-
|
|
35556
|
+
fs12.mkdirSync(plan.workspaceDir, { recursive: true });
|
|
35421
35557
|
assertWritableWorkspaceDir(plan.workspaceDir);
|
|
35422
35558
|
return;
|
|
35423
35559
|
}
|
|
@@ -35425,7 +35561,7 @@ async function ensureWorkspace(plan, log2) {
|
|
|
35425
35561
|
assertSafeCustomWorkspacePath(plan);
|
|
35426
35562
|
let st;
|
|
35427
35563
|
try {
|
|
35428
|
-
st =
|
|
35564
|
+
st = fs12.statSync(plan.workspaceDir);
|
|
35429
35565
|
} catch (err) {
|
|
35430
35566
|
if (isNodeError(err) && err.code === "ENOENT") {
|
|
35431
35567
|
throw new Error(`workspace path does not exist: ${plan.workspaceDir}`);
|
|
@@ -35435,7 +35571,7 @@ async function ensureWorkspace(plan, log2) {
|
|
|
35435
35571
|
if (!st.isDirectory()) {
|
|
35436
35572
|
throw new Error(`workspace path is not a directory: ${plan.workspaceDir}`);
|
|
35437
35573
|
}
|
|
35438
|
-
assertSafeCustomWorkspacePath(plan,
|
|
35574
|
+
assertSafeCustomWorkspacePath(plan, fs12.realpathSync(plan.workspaceDir));
|
|
35439
35575
|
assertWritableWorkspaceDir(plan.workspaceDir);
|
|
35440
35576
|
return;
|
|
35441
35577
|
}
|
|
@@ -35446,17 +35582,17 @@ async function ensureWorkspace(plan, log2) {
|
|
|
35446
35582
|
if (plan.customWorkspaceField) {
|
|
35447
35583
|
assertSafeCustomWorkspacePath(plan);
|
|
35448
35584
|
}
|
|
35449
|
-
if (!
|
|
35450
|
-
|
|
35451
|
-
assertWritableWorkspaceDir(
|
|
35585
|
+
if (!fs12.existsSync(plan.workspaceDir)) {
|
|
35586
|
+
fs12.mkdirSync(path16.dirname(plan.workspaceDir), { recursive: true });
|
|
35587
|
+
assertWritableWorkspaceDir(path16.dirname(plan.workspaceDir));
|
|
35452
35588
|
await runCommand("git", ["clone", remote, plan.workspaceDir], process.cwd());
|
|
35453
35589
|
} else {
|
|
35454
|
-
const st =
|
|
35590
|
+
const st = fs12.statSync(plan.workspaceDir);
|
|
35455
35591
|
if (!st.isDirectory()) {
|
|
35456
35592
|
throw new Error(`workspace path is not a directory: ${plan.workspaceDir}`);
|
|
35457
35593
|
}
|
|
35458
35594
|
if (plan.customWorkspaceField) {
|
|
35459
|
-
assertSafeCustomWorkspacePath(plan,
|
|
35595
|
+
assertSafeCustomWorkspacePath(plan, fs12.realpathSync(plan.workspaceDir));
|
|
35460
35596
|
}
|
|
35461
35597
|
assertWritableWorkspaceDir(plan.workspaceDir);
|
|
35462
35598
|
await ensureGitWorktree(plan.workspaceDir);
|
|
@@ -35480,13 +35616,13 @@ async function verifyExistingWorkspace(plan, log2) {
|
|
|
35480
35616
|
if (plan.customWorkspaceField) {
|
|
35481
35617
|
assertSafeCustomWorkspacePath(plan);
|
|
35482
35618
|
}
|
|
35483
|
-
const st =
|
|
35619
|
+
const st = fs12.statSync(plan.workspaceDir);
|
|
35484
35620
|
if (!st.isDirectory()) {
|
|
35485
35621
|
log2.warn(`workspace ready state ignored: path is not a directory: ${plan.workspaceDir}`);
|
|
35486
35622
|
return false;
|
|
35487
35623
|
}
|
|
35488
35624
|
if (plan.customWorkspaceField) {
|
|
35489
|
-
assertSafeCustomWorkspacePath(plan,
|
|
35625
|
+
assertSafeCustomWorkspacePath(plan, fs12.realpathSync(plan.workspaceDir));
|
|
35490
35626
|
}
|
|
35491
35627
|
assertWritableWorkspaceDir(plan.workspaceDir);
|
|
35492
35628
|
if (plan.workspace.mode === "git") {
|
|
@@ -35630,10 +35766,10 @@ ${tail}`)));
|
|
|
35630
35766
|
});
|
|
35631
35767
|
}
|
|
35632
35768
|
function requireAbsolute(value, field) {
|
|
35633
|
-
if (!value || !
|
|
35769
|
+
if (!value || !path16.isAbsolute(value)) {
|
|
35634
35770
|
throw new Error(`${field} must be an absolute path`);
|
|
35635
35771
|
}
|
|
35636
|
-
return
|
|
35772
|
+
return path16.resolve(value);
|
|
35637
35773
|
}
|
|
35638
35774
|
function assertSafeCustomWorkspacePath(plan, candidate = plan.workspaceDir) {
|
|
35639
35775
|
if (!plan.customWorkspaceField)
|
|
@@ -35643,17 +35779,17 @@ function assertSafeCustomWorkspacePath(plan, candidate = plan.workspaceDir) {
|
|
|
35643
35779
|
if (reason) {
|
|
35644
35780
|
throw new Error(`${plan.customWorkspaceField} must point to a project folder, not ${reason}: ${normalized}`);
|
|
35645
35781
|
}
|
|
35646
|
-
const defaultWorkspace =
|
|
35782
|
+
const defaultWorkspace = path16.resolve(plan.defaultWorkspaceDir);
|
|
35647
35783
|
if (isAncestorPath(normalized, defaultWorkspace) || normalized === defaultWorkspace) {
|
|
35648
35784
|
throw new Error(`${plan.customWorkspaceField} must not point at daemon state directories: ${normalized}`);
|
|
35649
35785
|
}
|
|
35650
35786
|
}
|
|
35651
35787
|
function assertWritableWorkspaceDir(dir) {
|
|
35652
|
-
|
|
35653
|
-
const probe =
|
|
35654
|
-
const fd =
|
|
35655
|
-
|
|
35656
|
-
|
|
35788
|
+
fs12.accessSync(dir, fs12.constants.R_OK | fs12.constants.W_OK | fs12.constants.X_OK);
|
|
35789
|
+
const probe = path16.join(dir, `.parall-workspace-check-${process.pid}-${Date.now()}`);
|
|
35790
|
+
const fd = fs12.openSync(probe, "wx", 384);
|
|
35791
|
+
fs12.closeSync(fd);
|
|
35792
|
+
fs12.unlinkSync(probe);
|
|
35657
35793
|
}
|
|
35658
35794
|
function workspacePathDenyReason(value) {
|
|
35659
35795
|
if (value === "/")
|
|
@@ -35714,11 +35850,11 @@ function workspacePathDenyReason(value) {
|
|
|
35714
35850
|
return "";
|
|
35715
35851
|
}
|
|
35716
35852
|
function isAncestorPath(parent, child) {
|
|
35717
|
-
const relative2 =
|
|
35718
|
-
return relative2 !== "" && !relative2.startsWith("..") && !
|
|
35853
|
+
const relative2 = path16.relative(parent, child);
|
|
35854
|
+
return relative2 !== "" && !relative2.startsWith("..") && !path16.isAbsolute(relative2);
|
|
35719
35855
|
}
|
|
35720
35856
|
function toPolicyPath(value) {
|
|
35721
|
-
return
|
|
35857
|
+
return path16.resolve(value).split(path16.sep).join("/");
|
|
35722
35858
|
}
|
|
35723
35859
|
function isNodeError(err) {
|
|
35724
35860
|
return err instanceof Error && "code" in err;
|
|
@@ -35735,8 +35871,9 @@ var init_workspace = __esm({
|
|
|
35735
35871
|
|
|
35736
35872
|
// ts/daemon/dist/supervisor.js
|
|
35737
35873
|
import { spawn as spawn6 } from "node:child_process";
|
|
35738
|
-
import * as
|
|
35739
|
-
import * as
|
|
35874
|
+
import * as fs13 from "node:fs";
|
|
35875
|
+
import * as os7 from "node:os";
|
|
35876
|
+
import * as path17 from "node:path";
|
|
35740
35877
|
function sleepCancellable(ms, signal) {
|
|
35741
35878
|
if (signal.aborted)
|
|
35742
35879
|
return Promise.resolve(false);
|
|
@@ -35763,6 +35900,7 @@ var init_supervisor = __esm({
|
|
|
35763
35900
|
init_clip_runtime();
|
|
35764
35901
|
init_config();
|
|
35765
35902
|
init_filesystem();
|
|
35903
|
+
init_home_isolation();
|
|
35766
35904
|
init_runtimes();
|
|
35767
35905
|
init_runtime_bin_resolver();
|
|
35768
35906
|
init_runtime_detector();
|
|
@@ -35886,7 +36024,7 @@ var init_supervisor = __esm({
|
|
|
35886
36024
|
this.migrateFlatLayout();
|
|
35887
36025
|
if (process.env.PRLL_CLIP_RUNTIME_ENABLED === "true") {
|
|
35888
36026
|
this.browserProfilePool = new BrowserProfilePool({
|
|
35889
|
-
baseHomeDir:
|
|
36027
|
+
baseHomeDir: path17.join(this.config.rootStateDir, "bb-browser"),
|
|
35890
36028
|
log: this.log,
|
|
35891
36029
|
reportStatus: (profileId, status, errorMsg, generation) => {
|
|
35892
36030
|
this.client.reportBrowserProfileStatus(profileId, status, errorMsg, generation).catch((err) => this.log.warn(`browser profile status report failed: ${String(err)}`));
|
|
@@ -35894,8 +36032,8 @@ var init_supervisor = __esm({
|
|
|
35894
36032
|
resolveProxy: (profileId) => this.resolveBrowserProfileProxy(profileId)
|
|
35895
36033
|
});
|
|
35896
36034
|
this.clipManager = new ClipProcessManager({
|
|
35897
|
-
clipsDir:
|
|
35898
|
-
dataDir:
|
|
36035
|
+
clipsDir: path17.join(this.config.rootStateDir, "clips"),
|
|
36036
|
+
dataDir: path17.join(this.config.rootStateDir, "clip-data"),
|
|
35899
36037
|
browserProfileManager: this.browserProfilePool,
|
|
35900
36038
|
// Execution side: nested browser dependency invokes resolve their
|
|
35901
36039
|
// binding and route through the hub (no local shortcut).
|
|
@@ -36124,6 +36262,22 @@ var init_supervisor = __esm({
|
|
|
36124
36262
|
}
|
|
36125
36263
|
await this.spawnAgent(userId, orgId, a);
|
|
36126
36264
|
} else {
|
|
36265
|
+
const isolationChanged = !existing.shuttingDown && !!existing.homeIsolation !== !!this.buildHomeIsolationSpec(a, userId);
|
|
36266
|
+
if (isolationChanged) {
|
|
36267
|
+
this.log.info(`agent ${userId}: home isolation changed while disconnected \u2014 rebuilding child`);
|
|
36268
|
+
existing.shuttingDown = true;
|
|
36269
|
+
if (existing.restartTimer) {
|
|
36270
|
+
clearTimeout(existing.restartTimer);
|
|
36271
|
+
existing.restartTimer = null;
|
|
36272
|
+
}
|
|
36273
|
+
await this.terminateChild(existing);
|
|
36274
|
+
this.children.delete(userId);
|
|
36275
|
+
const orgId = this.machineOrgId;
|
|
36276
|
+
if (orgId) {
|
|
36277
|
+
await this.spawnAgent(userId, orgId, a);
|
|
36278
|
+
}
|
|
36279
|
+
continue;
|
|
36280
|
+
}
|
|
36127
36281
|
const configChanged = JSON.stringify(existing.providerConfig ?? null) !== JSON.stringify(a.provider_config ?? null);
|
|
36128
36282
|
existing.providerConfig = a.provider_config;
|
|
36129
36283
|
if (!existing.child && !existing.restartTimer && !existing.shuttingDown) {
|
|
@@ -36284,15 +36438,15 @@ var init_supervisor = __esm({
|
|
|
36284
36438
|
*/
|
|
36285
36439
|
migrateFlatLayout() {
|
|
36286
36440
|
const root = this.config.rootStateDir;
|
|
36287
|
-
const agentsDir =
|
|
36288
|
-
const flatWorkspace =
|
|
36289
|
-
if (!
|
|
36441
|
+
const agentsDir = path17.join(root, "agents");
|
|
36442
|
+
const flatWorkspace = path17.join(root, "workspace");
|
|
36443
|
+
if (!fs13.existsSync(flatWorkspace) || fs13.existsSync(agentsDir))
|
|
36290
36444
|
return;
|
|
36291
36445
|
let ownerAgentId;
|
|
36292
|
-
const sessionsDir =
|
|
36293
|
-
if (
|
|
36446
|
+
const sessionsDir = path17.join(root, "sessions");
|
|
36447
|
+
if (fs13.existsSync(sessionsDir)) {
|
|
36294
36448
|
try {
|
|
36295
|
-
for (const file of
|
|
36449
|
+
for (const file of fs13.readdirSync(sessionsDir)) {
|
|
36296
36450
|
if (!file.endsWith(".json"))
|
|
36297
36451
|
continue;
|
|
36298
36452
|
const decoded = Buffer.from(file.replace(".json", ""), "base64url").toString();
|
|
@@ -36306,13 +36460,13 @@ var init_supervisor = __esm({
|
|
|
36306
36460
|
}
|
|
36307
36461
|
}
|
|
36308
36462
|
const targetId = ownerAgentId ?? "_orphan";
|
|
36309
|
-
const targetDir =
|
|
36463
|
+
const targetDir = path17.join(agentsDir, targetId);
|
|
36310
36464
|
try {
|
|
36311
|
-
|
|
36465
|
+
fs13.mkdirSync(targetDir, { recursive: true });
|
|
36312
36466
|
for (const sub of ["workspace", "sessions", "dispatch-context"]) {
|
|
36313
|
-
const src =
|
|
36314
|
-
if (
|
|
36315
|
-
|
|
36467
|
+
const src = path17.join(root, sub);
|
|
36468
|
+
if (fs13.existsSync(src)) {
|
|
36469
|
+
fs13.renameSync(src, path17.join(targetDir, sub));
|
|
36316
36470
|
}
|
|
36317
36471
|
}
|
|
36318
36472
|
this.log.info(`migrated legacy flat state \u2192 agents/${targetId}/`);
|
|
@@ -36603,7 +36757,7 @@ var init_supervisor = __esm({
|
|
|
36603
36757
|
return this.runtimeDetectInFlight;
|
|
36604
36758
|
}
|
|
36605
36759
|
machineClipToConfig(clip) {
|
|
36606
|
-
const clipPath =
|
|
36760
|
+
const clipPath = path17.join(this.config.rootStateDir, "clips", clip.alias);
|
|
36607
36761
|
return {
|
|
36608
36762
|
clipId: clip.clip_id,
|
|
36609
36763
|
name: clip.alias,
|
|
@@ -36669,7 +36823,7 @@ var init_supervisor = __esm({
|
|
|
36669
36823
|
if (!sourceRef) {
|
|
36670
36824
|
throw new Error(`registry clip "${config.name}" is missing source_ref`);
|
|
36671
36825
|
}
|
|
36672
|
-
const expectedPath =
|
|
36826
|
+
const expectedPath = path17.join(this.config.rootStateDir, "clips", config.name);
|
|
36673
36827
|
const localVersion = this.readInstalledClipVersion(expectedPath);
|
|
36674
36828
|
if (localVersion && (!config.version || localVersion === config.version)) {
|
|
36675
36829
|
return { ...config, path: expectedPath, source: expectedPath };
|
|
@@ -36687,7 +36841,7 @@ var init_supervisor = __esm({
|
|
|
36687
36841
|
const result = await installClip({
|
|
36688
36842
|
source,
|
|
36689
36843
|
alias: config.name,
|
|
36690
|
-
clipsDir:
|
|
36844
|
+
clipsDir: path17.join(this.config.rootStateDir, "clips"),
|
|
36691
36845
|
registryUrl: process.env.PRLL_PINIX_REGISTRY_URL?.trim() || void 0
|
|
36692
36846
|
});
|
|
36693
36847
|
this.log.info(`clip ensured: ${result.alias} v${result.version} at ${result.path}`);
|
|
@@ -36702,7 +36856,7 @@ var init_supervisor = __esm({
|
|
|
36702
36856
|
readInstalledClipVersion(dir) {
|
|
36703
36857
|
for (const file of ["clip.json", "package.json"]) {
|
|
36704
36858
|
try {
|
|
36705
|
-
const raw =
|
|
36859
|
+
const raw = fs13.readFileSync(path17.join(dir, file), "utf-8");
|
|
36706
36860
|
const parsed = JSON.parse(raw);
|
|
36707
36861
|
if (typeof parsed.version === "string" && parsed.version.trim()) {
|
|
36708
36862
|
return parsed.version.trim();
|
|
@@ -37012,6 +37166,28 @@ var init_supervisor = __esm({
|
|
|
37012
37166
|
});
|
|
37013
37167
|
}
|
|
37014
37168
|
}
|
|
37169
|
+
/**
|
|
37170
|
+
* Local credential isolation (home-isolation.ts): per-agent opt-in via
|
|
37171
|
+
* daemon_config.home_isolation (unset = legacy shared HOME for existing
|
|
37172
|
+
* agents), machine-level kill switch PRLL_DAEMON_HOME_ISOLATION=0. K8s
|
|
37173
|
+
* pods never take this path — they keep the isolated claude-home +
|
|
37174
|
+
* shared-credential-link branch in spawnAgentOnce.
|
|
37175
|
+
*/
|
|
37176
|
+
buildHomeIsolationSpec(attached, agentId) {
|
|
37177
|
+
if (process.env.KUBERNETES_SERVICE_HOST)
|
|
37178
|
+
return void 0;
|
|
37179
|
+
if (this.config.homeIsolationDisabled)
|
|
37180
|
+
return void 0;
|
|
37181
|
+
if (attached.daemon_config?.home_isolation !== true)
|
|
37182
|
+
return void 0;
|
|
37183
|
+
return {
|
|
37184
|
+
homeDir: agentHomeDirFor(this.config.rootStateDir, agentId),
|
|
37185
|
+
claudeStateRoot: this.config.rootClaudeHome,
|
|
37186
|
+
systemHome: os7.homedir(),
|
|
37187
|
+
gitUserName: attached.user?.display_name?.trim() || agentId,
|
|
37188
|
+
gitUserEmail: `${agentId}@noreply.parall.com`
|
|
37189
|
+
};
|
|
37190
|
+
}
|
|
37015
37191
|
async spawnAgentOnce(agentId, orgId, attached) {
|
|
37016
37192
|
let credential;
|
|
37017
37193
|
try {
|
|
@@ -37023,12 +37199,13 @@ var init_supervisor = __esm({
|
|
|
37023
37199
|
const stateDir = agentStateDirFor(this.config.rootStateDir, agentId);
|
|
37024
37200
|
const defaultWorkspaceDir = agentWorkspaceDirFor(this.config.rootStateDir, agentId);
|
|
37025
37201
|
const isK8s = !!process.env.KUBERNETES_SERVICE_HOST;
|
|
37026
|
-
const
|
|
37202
|
+
const homeIsolation = this.buildHomeIsolationSpec(attached, agentId);
|
|
37203
|
+
const claudeHome = isK8s ? agentClaudeHomeFor(this.config.rootClaudeHome, agentId) : homeIsolation?.homeDir ?? this.config.rootClaudeHome;
|
|
37027
37204
|
try {
|
|
37028
|
-
|
|
37205
|
+
fs13.mkdirSync(stateDir, { recursive: true });
|
|
37029
37206
|
if (isK8s) {
|
|
37030
|
-
|
|
37031
|
-
this.
|
|
37207
|
+
fs13.mkdirSync(claudeHome, { recursive: true });
|
|
37208
|
+
ensureSharedCredentialLink(this.config.rootClaudeHome, claudeHome, agentId, this.log);
|
|
37032
37209
|
}
|
|
37033
37210
|
} catch (err) {
|
|
37034
37211
|
this.log.warn(`mkdir agent dirs (${agentId}) failed: ${String(err)}`);
|
|
@@ -37061,6 +37238,7 @@ var init_supervisor = __esm({
|
|
|
37061
37238
|
// resolved at startChild time (see resolveProviderConfig) so a respawn
|
|
37062
37239
|
// after a machine llm_source change picks up the new source.
|
|
37063
37240
|
providerConfig: attached.provider_config,
|
|
37241
|
+
homeIsolation,
|
|
37064
37242
|
child: null,
|
|
37065
37243
|
credential,
|
|
37066
37244
|
restartAttempts: 0,
|
|
@@ -37080,17 +37258,38 @@ var init_supervisor = __esm({
|
|
|
37080
37258
|
return;
|
|
37081
37259
|
}
|
|
37082
37260
|
assertAgentKey(state.credential.api_key);
|
|
37261
|
+
const effectiveProviderConfig = effectiveLLMSourceExplicit(state.providerConfig) ? state.providerConfig : { llm_source: this.machineLlmSource };
|
|
37262
|
+
let isolation = state.homeIsolation;
|
|
37263
|
+
if (isolation) {
|
|
37264
|
+
try {
|
|
37265
|
+
const failures = ensureIsolatedHome(isolation, state.agentId, this.log);
|
|
37266
|
+
if (failures.length > 0) {
|
|
37267
|
+
const needsPassthrough = state.runtimeType === "claude-code" && llmSource(effectiveProviderConfig) === "runtime_auth";
|
|
37268
|
+
if (needsPassthrough) {
|
|
37269
|
+
this.log.warn(`agent ${state.agentId}: home isolation passthrough failed (${failures.join("; ")}) \u2014 falling back to the shared HOME for this spawn so the runtime keeps its login`);
|
|
37270
|
+
isolation = void 0;
|
|
37271
|
+
} else {
|
|
37272
|
+
this.log.warn(`agent ${state.agentId}: home isolation passthrough incomplete (${failures.join("; ")}) \u2014 keeping the fake HOME (this runtime/source does not need the shared-login links)`);
|
|
37273
|
+
}
|
|
37274
|
+
}
|
|
37275
|
+
} catch (err) {
|
|
37276
|
+
this.log.warn(`agent ${state.agentId}: home isolation setup failed \u2014 falling back to the shared HOME for this spawn: ${String(err)}`);
|
|
37277
|
+
isolation = void 0;
|
|
37278
|
+
}
|
|
37279
|
+
}
|
|
37083
37280
|
const adapter = getRuntimeAdapter(state.runtimeType);
|
|
37084
37281
|
const dirs = {
|
|
37085
37282
|
stateDir: agentStateDirFor(this.config.rootStateDir, state.agentId),
|
|
37086
37283
|
workspaceDir: state.workspacePath,
|
|
37087
|
-
claudeHome:
|
|
37284
|
+
// Only the isolation-fallback case replaces claudeHome: K8s (isolation
|
|
37285
|
+
// never set) and legacy-shared children keep their state.claudeHome.
|
|
37286
|
+
claudeHome: state.homeIsolation && !isolation ? this.config.rootClaudeHome : state.claudeHome,
|
|
37287
|
+
homeDir: isolation?.homeDir
|
|
37088
37288
|
};
|
|
37089
37289
|
let baseEnv = { ...process.env, PRLL_API_URL: this.config.apiUrl };
|
|
37090
37290
|
if (this.machineId)
|
|
37091
37291
|
baseEnv.PRLL_MACHINE_ID = this.machineId;
|
|
37092
37292
|
baseEnv = applyRuntimeBinaryEnv(state.runtimeType, baseEnv, this.log);
|
|
37093
|
-
const effectiveProviderConfig = effectiveLLMSourceExplicit(state.providerConfig) ? state.providerConfig : { llm_source: this.machineLlmSource };
|
|
37094
37293
|
const env = adapter.buildEnv(baseEnv, state.agentId, state.orgId, state.credential.api_key, dirs, effectiveProviderConfig);
|
|
37095
37294
|
const spawnCmd = adapter.args.length > 0 ? `${adapter.bin} ${adapter.args.join(" ")}` : adapter.bin;
|
|
37096
37295
|
this.log.info(`spawning agent ${state.agentId} runtime=${state.runtimeType} cmd=${spawnCmd} (attempt ${state.restartAttempts + 1})`);
|
|
@@ -37173,33 +37372,6 @@ var init_supervisor = __esm({
|
|
|
37173
37372
|
child.once("exit", () => clearTimeout(hardKill));
|
|
37174
37373
|
});
|
|
37175
37374
|
}
|
|
37176
|
-
ensureSharedCredentialLink(agentClaudeHome, agentId) {
|
|
37177
|
-
const sharedCredentials = path16.resolve(sharedClaudeCredentialsFileFor(this.config.rootClaudeHome));
|
|
37178
|
-
const agentCredentials = agentClaudeCredentialsFileFor(agentClaudeHome);
|
|
37179
|
-
const agentCredentialsDir = path16.dirname(agentCredentials);
|
|
37180
|
-
fs12.mkdirSync(path16.dirname(sharedCredentials), { recursive: true });
|
|
37181
|
-
fs12.mkdirSync(agentCredentialsDir, { recursive: true });
|
|
37182
|
-
try {
|
|
37183
|
-
const existing = fs12.lstatSync(agentCredentials);
|
|
37184
|
-
if (existing.isSymbolicLink()) {
|
|
37185
|
-
const currentTarget = fs12.readlinkSync(agentCredentials);
|
|
37186
|
-
if (path16.resolve(agentCredentialsDir, currentTarget) === sharedCredentials) {
|
|
37187
|
-
return;
|
|
37188
|
-
}
|
|
37189
|
-
fs12.unlinkSync(agentCredentials);
|
|
37190
|
-
} else if (existing.isDirectory()) {
|
|
37191
|
-
this.log.warn(`agent ${agentId}: credential path is a directory, cannot link ${agentCredentials}`);
|
|
37192
|
-
return;
|
|
37193
|
-
} else {
|
|
37194
|
-
fs12.unlinkSync(agentCredentials);
|
|
37195
|
-
}
|
|
37196
|
-
} catch (err) {
|
|
37197
|
-
if (err.code !== "ENOENT") {
|
|
37198
|
-
throw err;
|
|
37199
|
-
}
|
|
37200
|
-
}
|
|
37201
|
-
fs12.symlinkSync(sharedCredentials, agentCredentials);
|
|
37202
|
-
}
|
|
37203
37375
|
};
|
|
37204
37376
|
}
|
|
37205
37377
|
});
|
|
@@ -37405,8 +37577,8 @@ var init_daemon_main = __esm({
|
|
|
37405
37577
|
// ts/daemon/dist/index.js
|
|
37406
37578
|
init_daemon_paths();
|
|
37407
37579
|
init_daemon_update_mode();
|
|
37408
|
-
import * as
|
|
37409
|
-
import * as
|
|
37580
|
+
import * as fs14 from "node:fs";
|
|
37581
|
+
import * as path18 from "node:path";
|
|
37410
37582
|
var UPDATE_EXIT_CODE2 = 42;
|
|
37411
37583
|
function formatError2(reason) {
|
|
37412
37584
|
if (reason instanceof Error) {
|
|
@@ -37422,7 +37594,7 @@ function errnoCode(err) {
|
|
|
37422
37594
|
}
|
|
37423
37595
|
function clearRunningMarker(markerPath) {
|
|
37424
37596
|
try {
|
|
37425
|
-
|
|
37597
|
+
fs14.unlinkSync(markerPath);
|
|
37426
37598
|
} catch (err) {
|
|
37427
37599
|
if (errnoCode(err) === "ENOENT")
|
|
37428
37600
|
return;
|
|
@@ -37431,15 +37603,15 @@ function clearRunningMarker(markerPath) {
|
|
|
37431
37603
|
}
|
|
37432
37604
|
function prepareDaemonBootstrap(env = process.env, args = process.argv.slice(2)) {
|
|
37433
37605
|
const bundleDir = resolveBundleDir(env);
|
|
37434
|
-
const runningMarker =
|
|
37606
|
+
const runningMarker = path18.join(bundleDir, "daemon-running");
|
|
37435
37607
|
const lifecycleMarkerEnabled = args.length === 0 && !isSelfUpdateDisabledByEnv(env) && isSelfUpdateManaged(bundleDir, env);
|
|
37436
37608
|
if (!lifecycleMarkerEnabled) {
|
|
37437
37609
|
return { lifecycleMarkerEnabled: false, runningMarker, uncleanPrevExit: false };
|
|
37438
37610
|
}
|
|
37439
|
-
const uncleanPrevExit =
|
|
37611
|
+
const uncleanPrevExit = fs14.existsSync(runningMarker);
|
|
37440
37612
|
try {
|
|
37441
|
-
|
|
37442
|
-
|
|
37613
|
+
fs14.mkdirSync(bundleDir, { recursive: true });
|
|
37614
|
+
fs14.writeFileSync(runningMarker, String(process.pid));
|
|
37443
37615
|
} catch (err) {
|
|
37444
37616
|
console.warn(`failed to write daemon running marker: ${formatError2(err)}`);
|
|
37445
37617
|
}
|