@parall/daemon 1.43.0 → 1.45.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.
@@ -646,7 +646,7 @@ var init_client = __esm({
646
646
  return apiError;
647
647
  }
648
648
  /** Build headers common to all requests (auth, swimlane). */
649
- buildHeaders(path19, extra) {
649
+ buildHeaders(path21, extra) {
650
650
  const headers = {
651
651
  "Content-Type": "application/json",
652
652
  ...extra
@@ -657,7 +657,7 @@ var init_client = __esm({
657
657
  if (this.swimlaneName) {
658
658
  headers["X-Prll-Swimlane"] = this.swimlaneName;
659
659
  }
660
- if (path19.startsWith(API_BASE)) {
660
+ if (path21.startsWith(API_BASE)) {
661
661
  const overrides = this.getFeatureFlagOverrides?.();
662
662
  if (overrides)
663
663
  headers["X-Prll-FF-Override"] = overrides;
@@ -680,8 +680,8 @@ var init_client = __esm({
680
680
  * is authoritative, so wiki vs api routing can't drift from how a caller
681
681
  * happens to invoke the client.
682
682
  */
683
- baseUrlFor(path19) {
684
- return path19.startsWith(WIKI_BASE) ? this.wikiBaseUrl : this.baseUrl;
683
+ baseUrlFor(path21) {
684
+ return path21.startsWith(WIKI_BASE) ? this.wikiBaseUrl : this.baseUrl;
685
685
  }
686
686
  setToken(token) {
687
687
  this.token = token;
@@ -708,10 +708,10 @@ var init_client = __esm({
708
708
  * REFRESH_THRESHOLD_S, refresh it **before** sending the request.
709
709
  * No-op when the token is still fresh, missing, or un-parseable.
710
710
  */
711
- async ensureFreshToken(path19) {
711
+ async ensureFreshToken(path21) {
712
712
  if (!this.token || !this.getRefreshToken)
713
713
  return;
714
- const pathSuffix = path19.replace(/^\/api\/v1/, "");
714
+ const pathSuffix = path21.replace(/^\/api\/v1/, "");
715
715
  if (_ParallClient.AUTH_PATHS.has(pathSuffix))
716
716
  return;
717
717
  const exp = _ParallClient.decodeJwtExp(this.token);
@@ -743,11 +743,11 @@ var init_client = __esm({
743
743
  this.refreshPromise = null;
744
744
  }
745
745
  }
746
- async request(method, path19, body, query, retried = false, opts) {
746
+ async request(method, path21, body, query, retried = false, opts) {
747
747
  if (!retried) {
748
- await this.ensureFreshToken(path19);
748
+ await this.ensureFreshToken(path21);
749
749
  }
750
- let url = `${this.baseUrlFor(path19)}${path19}`;
750
+ let url = `${this.baseUrlFor(path21)}${path21}`;
751
751
  if (query) {
752
752
  const params = new URLSearchParams();
753
753
  for (const [key, value] of Object.entries(query)) {
@@ -759,7 +759,7 @@ var init_client = __esm({
759
759
  if (qs)
760
760
  url += `?${qs}`;
761
761
  }
762
- const headers = this.buildHeaders(path19);
762
+ const headers = this.buildHeaders(path21);
763
763
  const timeoutSignal = AbortSignal.timeout(opts?.timeoutMs ?? 15e3);
764
764
  const signal = opts?.signal ? AbortSignal.any([opts.signal, timeoutSignal]) : timeoutSignal;
765
765
  let res;
@@ -777,12 +777,12 @@ var init_client = __esm({
777
777
  throw _ParallClient.normalizeFetchError(err);
778
778
  }
779
779
  if (res.status === 401) {
780
- const pathSuffix = path19.replace(/^\/api\/v1/, "");
780
+ const pathSuffix = path21.replace(/^\/api\/v1/, "");
781
781
  const isAuthPath = _ParallClient.AUTH_PATHS.has(pathSuffix);
782
782
  if (!retried && !isAuthPath && this.getRefreshToken) {
783
783
  const refreshed = await this.tryRefresh();
784
784
  if (refreshed) {
785
- return this.request(method, path19, body, query, true, opts);
785
+ return this.request(method, path21, body, query, true, opts);
786
786
  }
787
787
  }
788
788
  if (this.onTokenExpired && !isAuthPath) {
@@ -812,15 +812,15 @@ var init_client = __esm({
812
812
  * hit the 100 MiB cap, so a longer 5-minute timeout is used so a
813
813
  * 50 MiB blob on a slow connection doesn't get chopped at 15 s.
814
814
  */
815
- async multipartRequest(method, path19, body, retried = false) {
815
+ async multipartRequest(method, path21, body, retried = false) {
816
816
  if (!retried) {
817
- await this.ensureFreshToken(path19);
817
+ await this.ensureFreshToken(path21);
818
818
  }
819
- const { "Content-Type": _drop, ...headers } = this.buildHeaders(path19);
819
+ const { "Content-Type": _drop, ...headers } = this.buildHeaders(path21);
820
820
  void _drop;
821
821
  let res;
822
822
  try {
823
- res = await fetch(`${this.baseUrlFor(path19)}${path19}`, {
823
+ res = await fetch(`${this.baseUrlFor(path21)}${path21}`, {
824
824
  method,
825
825
  headers,
826
826
  body,
@@ -830,12 +830,12 @@ var init_client = __esm({
830
830
  throw _ParallClient.normalizeFetchError(err);
831
831
  }
832
832
  if (res.status === 401) {
833
- const pathSuffix = path19.replace(/^\/api\/v1/, "");
833
+ const pathSuffix = path21.replace(/^\/api\/v1/, "");
834
834
  const isAuthPath = _ParallClient.AUTH_PATHS.has(pathSuffix);
835
835
  if (!retried && !isAuthPath && this.getRefreshToken) {
836
836
  const refreshed = await this.tryRefresh();
837
837
  if (refreshed) {
838
- return this.multipartRequest(method, path19, body, true);
838
+ return this.multipartRequest(method, path21, body, true);
839
839
  }
840
840
  }
841
841
  if (this.onTokenExpired && !isAuthPath) {
@@ -1539,8 +1539,8 @@ var init_client = __esm({
1539
1539
  async requestMachineUpdate(orgId, machineId, mandatory = false) {
1540
1540
  await this.request("POST", ENDPOINTS.MACHINE_REQUEST_UPDATE(orgId, machineId), { mandatory });
1541
1541
  }
1542
- async browseMachineFilesystem(orgId, machineId, path19) {
1543
- return this.request("POST", ENDPOINTS.MACHINE_BROWSE(orgId, machineId), { path: path19 }, void 0, false, { timeoutMs: 15e3 });
1542
+ async browseMachineFilesystem(orgId, machineId, path21) {
1543
+ return this.request("POST", ENDPOINTS.MACHINE_BROWSE(orgId, machineId), { path: path21 }, void 0, false, { timeoutMs: 15e3 });
1544
1544
  }
1545
1545
  /** Create a new machine key. Returns the raw key string (shown once) + metadata. */
1546
1546
  async createMachineKey(orgId, machineId, name) {
@@ -1625,7 +1625,6 @@ var init_client = __esm({
1625
1625
  async steerDispatch(orgId, req) {
1626
1626
  return this.request("POST", ENDPOINTS.DISPATCH_STEER(orgId), req);
1627
1627
  }
1628
- /** End a turn: no_action sweep of the lane's members + lane release + re-drive check. */
1629
1628
  async completeDispatch(orgId, req) {
1630
1629
  return this.request("POST", ENDPOINTS.DISPATCH_COMPLETE(orgId), req);
1631
1630
  }
@@ -1633,6 +1632,10 @@ var init_client = __esm({
1633
1632
  * End a turn for a lane-less runtime: resolve the turn's folded WorkItems
1634
1633
  * by source — broad-cover to the turn's reply Effect when one exists,
1635
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).
1636
1639
  */
1637
1640
  async completeDispatchSources(orgId, req) {
1638
1641
  return this.request("POST", ENDPOINTS.DISPATCH_COMPLETE_SOURCES(orgId), req);
@@ -2109,8 +2112,8 @@ var init_client = __esm({
2109
2112
  async deleteWikiRestriction(orgId, wikiId, restrictionId) {
2110
2113
  await this.request("DELETE", ENDPOINTS.WIKI_RESTRICTION(orgId, wikiId, restrictionId));
2111
2114
  }
2112
- async getWikiAccessStatus(orgId, wikiId, path19) {
2113
- return this.request("GET", ENDPOINTS.WIKI_ACCESS_STATUS(orgId, wikiId), void 0, path19 ? { path: path19 } : void 0);
2115
+ async getWikiAccessStatus(orgId, wikiId, path21) {
2116
+ return this.request("GET", ENDPOINTS.WIKI_ACCESS_STATUS(orgId, wikiId), void 0, path21 ? { path: path21 } : void 0);
2114
2117
  }
2115
2118
  async createWikiAccessRequest(orgId, wikiId, data) {
2116
2119
  await this.request("POST", ENDPOINTS.WIKI_ACCESS_REQUESTS(orgId, wikiId), data);
@@ -2119,14 +2122,14 @@ var init_client = __esm({
2119
2122
  async getWikiCommits(orgId, wikiId, params) {
2120
2123
  return this.request("GET", ENDPOINTS.WIKI_COMMITS(orgId, wikiId), void 0, params);
2121
2124
  }
2122
- async getWikiFileCommits(orgId, wikiId, path19, params) {
2125
+ async getWikiFileCommits(orgId, wikiId, path21, params) {
2123
2126
  return this.request("GET", ENDPOINTS.WIKI_FILE_COMMITS(orgId, wikiId), void 0, {
2124
- path: path19,
2127
+ path: path21,
2125
2128
  ...params
2126
2129
  });
2127
2130
  }
2128
- async getWikiBlame(orgId, wikiId, path19, ref) {
2129
- return this.request("GET", ENDPOINTS.WIKI_BLAME(orgId, wikiId), void 0, { path: path19, ref });
2131
+ async getWikiBlame(orgId, wikiId, path21, ref) {
2132
+ return this.request("GET", ENDPOINTS.WIKI_BLAME(orgId, wikiId), void 0, { path: path21, ref });
2130
2133
  }
2131
2134
  // ---- Wiki Operations (audit log) ----
2132
2135
  async getWikiOperations(orgId, wikiId, params) {
@@ -2778,6 +2781,7 @@ var TYPED_BACKOFF_CAP_MS;
2778
2781
  var init_gateway_lane_flow = __esm({
2779
2782
  "ts/agent-core/dist/gateway-lane-flow.js"() {
2780
2783
  "use strict";
2784
+ init_dist();
2781
2785
  init_lane_ledger();
2782
2786
  TYPED_BACKOFF_CAP_MS = 5 * 6e4;
2783
2787
  }
@@ -4781,11 +4785,11 @@ var init_bounded_queue_export_promise_handler = __esm({
4781
4785
  "ts/node_modules/.pnpm/@opentelemetry+otlp-exporter-base@0.57.2_@opentelemetry+api@1.9.1/node_modules/@opentelemetry/otlp-exporter-base/build/esm/bounded-queue-export-promise-handler.js"() {
4782
4786
  __awaiter = function(thisArg, _arguments, P, generator) {
4783
4787
  function adopt(value) {
4784
- return value instanceof P ? value : new P(function(resolve8) {
4785
- resolve8(value);
4788
+ return value instanceof P ? value : new P(function(resolve9) {
4789
+ resolve9(value);
4786
4790
  });
4787
4791
  }
4788
- return new (P || (P = Promise))(function(resolve8, reject) {
4792
+ return new (P || (P = Promise))(function(resolve9, reject) {
4789
4793
  function fulfilled(value) {
4790
4794
  try {
4791
4795
  step(generator.next(value));
@@ -4801,7 +4805,7 @@ var init_bounded_queue_export_promise_handler = __esm({
4801
4805
  }
4802
4806
  }
4803
4807
  function step(result) {
4804
- result.done ? resolve8(result.value) : adopt(result.value).then(fulfilled, rejected);
4808
+ result.done ? resolve9(result.value) : adopt(result.value).then(fulfilled, rejected);
4805
4809
  }
4806
4810
  step((generator = generator.apply(thisArg, _arguments || [])).next());
4807
4811
  });
@@ -8439,8 +8443,8 @@ var require_promise = __commonJS({
8439
8443
  exports2.Deferred = void 0;
8440
8444
  var Deferred = class {
8441
8445
  constructor() {
8442
- this._promise = new Promise((resolve8, reject) => {
8443
- this._resolve = resolve8;
8446
+ this._promise = new Promise((resolve9, reject) => {
8447
+ this._resolve = resolve9;
8444
8448
  this._reject = reject;
8445
8449
  });
8446
8450
  }
@@ -8503,10 +8507,10 @@ var require_exporter = __commonJS({
8503
8507
  var api_1 = (init_esm(), __toCommonJS(esm_exports));
8504
8508
  var suppress_tracing_1 = require_suppress_tracing();
8505
8509
  function _export(exporter, arg) {
8506
- return new Promise((resolve8) => {
8510
+ return new Promise((resolve9) => {
8507
8511
  api_1.context.with((0, suppress_tracing_1.suppressTracing)(api_1.context.active()), () => {
8508
8512
  exporter.export(arg, (result) => {
8509
- resolve8(result);
8513
+ resolve9(result);
8510
8514
  });
8511
8515
  });
8512
8516
  });
@@ -8781,11 +8785,11 @@ var init_otlp_export_delegate = __esm({
8781
8785
  init_esm();
8782
8786
  __awaiter2 = function(thisArg, _arguments, P, generator) {
8783
8787
  function adopt(value) {
8784
- return value instanceof P ? value : new P(function(resolve8) {
8785
- resolve8(value);
8788
+ return value instanceof P ? value : new P(function(resolve9) {
8789
+ resolve9(value);
8786
8790
  });
8787
8791
  }
8788
- return new (P || (P = Promise))(function(resolve8, reject) {
8792
+ return new (P || (P = Promise))(function(resolve9, reject) {
8789
8793
  function fulfilled(value) {
8790
8794
  try {
8791
8795
  step(generator.next(value));
@@ -8801,7 +8805,7 @@ var init_otlp_export_delegate = __esm({
8801
8805
  }
8802
8806
  }
8803
8807
  function step(result) {
8804
- result.done ? resolve8(result.value) : adopt(result.value).then(fulfilled, rejected);
8808
+ result.done ? resolve9(result.value) : adopt(result.value).then(fulfilled, rejected);
8805
8809
  }
8806
8810
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8807
8811
  });
@@ -9012,7 +9016,7 @@ var require_aspromise = __commonJS({
9012
9016
  var params = new Array(arguments.length - 1), offset = 0, index = 2, pending = true;
9013
9017
  while (index < arguments.length)
9014
9018
  params[offset++] = arguments[index++];
9015
- return new Promise(function executor(resolve8, reject) {
9019
+ return new Promise(function executor(resolve9, reject) {
9016
9020
  params[offset] = function callback(err) {
9017
9021
  if (pending) {
9018
9022
  pending = false;
@@ -9022,7 +9026,7 @@ var require_aspromise = __commonJS({
9022
9026
  var params2 = new Array(arguments.length - 1), offset2 = 0;
9023
9027
  while (offset2 < params2.length)
9024
9028
  params2[offset2++] = arguments[offset2];
9025
- resolve8.apply(null, params2);
9029
+ resolve9.apply(null, params2);
9026
9030
  }
9027
9031
  }
9028
9032
  };
@@ -20519,9 +20523,9 @@ var require_getMachineId_linux = __commonJS({
20519
20523
  var api_1 = (init_esm(), __toCommonJS(esm_exports));
20520
20524
  async function getMachineId() {
20521
20525
  const paths = ["/etc/machine-id", "/var/lib/dbus/machine-id"];
20522
- for (const path19 of paths) {
20526
+ for (const path21 of paths) {
20523
20527
  try {
20524
- const result = await fs_1.promises.readFile(path19, { encoding: "utf8" });
20528
+ const result = await fs_1.promises.readFile(path21, { encoding: "utf8" });
20525
20529
  return result.trim();
20526
20530
  } catch (e) {
20527
20531
  api_1.diag.debug(`error reading machine id: ${e}`);
@@ -23451,11 +23455,11 @@ var init_http_exporter_transport = __esm({
23451
23455
  "ts/node_modules/.pnpm/@opentelemetry+otlp-exporter-base@0.57.2_@opentelemetry+api@1.9.1/node_modules/@opentelemetry/otlp-exporter-base/build/esm/transport/http-exporter-transport.js"() {
23452
23456
  __awaiter3 = function(thisArg, _arguments, P, generator) {
23453
23457
  function adopt(value) {
23454
- return value instanceof P ? value : new P(function(resolve8) {
23455
- resolve8(value);
23458
+ return value instanceof P ? value : new P(function(resolve9) {
23459
+ resolve9(value);
23456
23460
  });
23457
23461
  }
23458
- return new (P || (P = Promise))(function(resolve8, reject) {
23462
+ return new (P || (P = Promise))(function(resolve9, reject) {
23459
23463
  function fulfilled(value) {
23460
23464
  try {
23461
23465
  step(generator.next(value));
@@ -23471,7 +23475,7 @@ var init_http_exporter_transport = __esm({
23471
23475
  }
23472
23476
  }
23473
23477
  function step(result) {
23474
- result.done ? resolve8(result.value) : adopt(result.value).then(fulfilled, rejected);
23478
+ result.done ? resolve9(result.value) : adopt(result.value).then(fulfilled, rejected);
23475
23479
  }
23476
23480
  step((generator = generator.apply(thisArg, _arguments || [])).next());
23477
23481
  });
@@ -23562,10 +23566,10 @@ var init_http_exporter_transport = __esm({
23562
23566
  this._agent = createHttpAgent2(this._parameters.url, this._parameters.agentOptions);
23563
23567
  this._send = sendWithHttp2;
23564
23568
  }
23565
- return [2, new Promise(function(resolve8) {
23569
+ return [2, new Promise(function(resolve9) {
23566
23570
  var _a2;
23567
23571
  (_a2 = _this._send) === null || _a2 === void 0 ? void 0 : _a2.call(_this, _this._parameters, _this._agent, data, function(result) {
23568
- resolve8(result);
23572
+ resolve9(result);
23569
23573
  }, timeoutMillis);
23570
23574
  })];
23571
23575
  });
@@ -23590,11 +23594,11 @@ var init_retrying_transport = __esm({
23590
23594
  "ts/node_modules/.pnpm/@opentelemetry+otlp-exporter-base@0.57.2_@opentelemetry+api@1.9.1/node_modules/@opentelemetry/otlp-exporter-base/build/esm/retrying-transport.js"() {
23591
23595
  __awaiter4 = function(thisArg, _arguments, P, generator) {
23592
23596
  function adopt(value) {
23593
- return value instanceof P ? value : new P(function(resolve8) {
23594
- resolve8(value);
23597
+ return value instanceof P ? value : new P(function(resolve9) {
23598
+ resolve9(value);
23595
23599
  });
23596
23600
  }
23597
- return new (P || (P = Promise))(function(resolve8, reject) {
23601
+ return new (P || (P = Promise))(function(resolve9, reject) {
23598
23602
  function fulfilled(value) {
23599
23603
  try {
23600
23604
  step(generator.next(value));
@@ -23610,7 +23614,7 @@ var init_retrying_transport = __esm({
23610
23614
  }
23611
23615
  }
23612
23616
  function step(result) {
23613
- result.done ? resolve8(result.value) : adopt(result.value).then(fulfilled, rejected);
23617
+ result.done ? resolve9(result.value) : adopt(result.value).then(fulfilled, rejected);
23614
23618
  }
23615
23619
  step((generator = generator.apply(thisArg, _arguments || [])).next());
23616
23620
  });
@@ -23696,9 +23700,9 @@ var init_retrying_transport = __esm({
23696
23700
  }
23697
23701
  RetryingTransport2.prototype.retry = function(data, timeoutMillis, inMillis) {
23698
23702
  var _this = this;
23699
- return new Promise(function(resolve8, reject) {
23703
+ return new Promise(function(resolve9, reject) {
23700
23704
  setTimeout(function() {
23701
- _this._transport.send(data, timeoutMillis).then(resolve8, reject);
23705
+ _this._transport.send(data, timeoutMillis).then(resolve9, reject);
23702
23706
  }, inMillis);
23703
23707
  });
23704
23708
  };
@@ -23924,7 +23928,7 @@ function appendRootPathToUrlIfNeeded(url) {
23924
23928
  return void 0;
23925
23929
  }
23926
23930
  }
23927
- function appendResourcePathToUrl(url, path19) {
23931
+ function appendResourcePathToUrl(url, path21) {
23928
23932
  try {
23929
23933
  new URL(url);
23930
23934
  } catch (_a) {
@@ -23934,11 +23938,11 @@ function appendResourcePathToUrl(url, path19) {
23934
23938
  if (!url.endsWith("/")) {
23935
23939
  url = url + "/";
23936
23940
  }
23937
- url += path19;
23941
+ url += path21;
23938
23942
  try {
23939
23943
  new URL(url);
23940
23944
  } catch (_b) {
23941
- diag2.warn("Configuration: Provided URL appended with '" + path19 + "' is not a valid URL, using 'undefined' instead of '" + url + "'");
23945
+ diag2.warn("Configuration: Provided URL appended with '" + path21 + "' is not a valid URL, using 'undefined' instead of '" + url + "'");
23942
23946
  return void 0;
23943
23947
  }
23944
23948
  return url;
@@ -25607,14 +25611,14 @@ var require_BatchSpanProcessorBase = __commonJS({
25607
25611
  * for all other cases _flush should be used
25608
25612
  * */
25609
25613
  _flushAll() {
25610
- return new Promise((resolve8, reject) => {
25614
+ return new Promise((resolve9, reject) => {
25611
25615
  const promises = [];
25612
25616
  const count = Math.ceil(this._finishedSpans.length / this._maxExportBatchSize);
25613
25617
  for (let i = 0, j = count; i < j; i++) {
25614
25618
  promises.push(this._flushOneBatch());
25615
25619
  }
25616
25620
  Promise.all(promises).then(() => {
25617
- resolve8();
25621
+ resolve9();
25618
25622
  }).catch(reject);
25619
25623
  });
25620
25624
  }
@@ -25623,7 +25627,7 @@ var require_BatchSpanProcessorBase = __commonJS({
25623
25627
  if (this._finishedSpans.length === 0) {
25624
25628
  return Promise.resolve();
25625
25629
  }
25626
- return new Promise((resolve8, reject) => {
25630
+ return new Promise((resolve9, reject) => {
25627
25631
  const timer = setTimeout(() => {
25628
25632
  reject(new Error("Timeout"));
25629
25633
  }, this._exportTimeoutMillis);
@@ -25639,7 +25643,7 @@ var require_BatchSpanProcessorBase = __commonJS({
25639
25643
  var _a;
25640
25644
  clearTimeout(timer);
25641
25645
  if (result.code === core_1.ExportResultCode.SUCCESS) {
25642
- resolve8();
25646
+ resolve9();
25643
25647
  } else {
25644
25648
  reject((_a = result.error) !== null && _a !== void 0 ? _a : new Error("BatchSpanProcessor: span export failed"));
25645
25649
  }
@@ -25906,12 +25910,12 @@ var require_MultiSpanProcessor = __commonJS({
25906
25910
  for (const spanProcessor of this._spanProcessors) {
25907
25911
  promises.push(spanProcessor.forceFlush());
25908
25912
  }
25909
- return new Promise((resolve8) => {
25913
+ return new Promise((resolve9) => {
25910
25914
  Promise.all(promises).then(() => {
25911
- resolve8();
25915
+ resolve9();
25912
25916
  }).catch((error) => {
25913
25917
  (0, core_1.globalErrorHandler)(error || new Error("MultiSpanProcessor: forceFlush failed"));
25914
- resolve8();
25918
+ resolve9();
25915
25919
  });
25916
25920
  });
25917
25921
  }
@@ -25930,9 +25934,9 @@ var require_MultiSpanProcessor = __commonJS({
25930
25934
  for (const spanProcessor of this._spanProcessors) {
25931
25935
  promises.push(spanProcessor.shutdown());
25932
25936
  }
25933
- return new Promise((resolve8, reject) => {
25937
+ return new Promise((resolve9, reject) => {
25934
25938
  Promise.all(promises).then(() => {
25935
- resolve8();
25939
+ resolve9();
25936
25940
  }, reject);
25937
25941
  });
25938
25942
  }
@@ -26055,32 +26059,32 @@ var require_BasicTracerProvider = __commonJS({
26055
26059
  forceFlush() {
26056
26060
  const timeout = this._config.forceFlushTimeoutMillis;
26057
26061
  const promises = this._registeredSpanProcessors.map((spanProcessor) => {
26058
- return new Promise((resolve8) => {
26062
+ return new Promise((resolve9) => {
26059
26063
  let state;
26060
26064
  const timeoutInterval = setTimeout(() => {
26061
- resolve8(new Error(`Span processor did not completed within timeout period of ${timeout} ms`));
26065
+ resolve9(new Error(`Span processor did not completed within timeout period of ${timeout} ms`));
26062
26066
  state = ForceFlushState.timeout;
26063
26067
  }, timeout);
26064
26068
  spanProcessor.forceFlush().then(() => {
26065
26069
  clearTimeout(timeoutInterval);
26066
26070
  if (state !== ForceFlushState.timeout) {
26067
26071
  state = ForceFlushState.resolved;
26068
- resolve8(state);
26072
+ resolve9(state);
26069
26073
  }
26070
26074
  }).catch((error) => {
26071
26075
  clearTimeout(timeoutInterval);
26072
26076
  state = ForceFlushState.error;
26073
- resolve8(error);
26077
+ resolve9(error);
26074
26078
  });
26075
26079
  });
26076
26080
  });
26077
- return new Promise((resolve8, reject) => {
26081
+ return new Promise((resolve9, reject) => {
26078
26082
  Promise.all(promises).then((results) => {
26079
26083
  const errors = results.filter((result) => result !== ForceFlushState.resolved);
26080
26084
  if (errors.length > 0) {
26081
26085
  reject(errors);
26082
26086
  } else {
26083
- resolve8();
26087
+ resolve9();
26084
26088
  }
26085
26089
  }).catch((error) => reject([error]));
26086
26090
  });
@@ -29099,14 +29103,14 @@ var require_BatchLogRecordProcessorBase = __commonJS({
29099
29103
  * for all other cases _flush should be used
29100
29104
  * */
29101
29105
  _flushAll() {
29102
- return new Promise((resolve8, reject) => {
29106
+ return new Promise((resolve9, reject) => {
29103
29107
  const promises = [];
29104
29108
  const batchCount = Math.ceil(this._finishedLogRecords.length / this._maxExportBatchSize);
29105
29109
  for (let i = 0; i < batchCount; i++) {
29106
29110
  promises.push(this._flushOneBatch());
29107
29111
  }
29108
29112
  Promise.all(promises).then(() => {
29109
- resolve8();
29113
+ resolve9();
29110
29114
  }).catch(reject);
29111
29115
  });
29112
29116
  }
@@ -29115,8 +29119,8 @@ var require_BatchLogRecordProcessorBase = __commonJS({
29115
29119
  if (this._finishedLogRecords.length === 0) {
29116
29120
  return Promise.resolve();
29117
29121
  }
29118
- return new Promise((resolve8, reject) => {
29119
- (0, core_1.callWithTimeout)(this._export(this._finishedLogRecords.splice(0, this._maxExportBatchSize)), this._exportTimeoutMillis).then(() => resolve8()).catch(reject);
29122
+ return new Promise((resolve9, reject) => {
29123
+ (0, core_1.callWithTimeout)(this._export(this._finishedLogRecords.splice(0, this._maxExportBatchSize)), this._exportTimeoutMillis).then(() => resolve9()).catch(reject);
29120
29124
  });
29121
29125
  }
29122
29126
  _maybeStartTimer() {
@@ -29636,6 +29640,329 @@ var init_config = __esm({
29636
29640
  }
29637
29641
  });
29638
29642
 
29643
+ // ts/daemon/dist/win-service.js
29644
+ import * as path4 from "node:path";
29645
+ function winServicePaths(home) {
29646
+ const root = path4.join(home, ".parall-daemon");
29647
+ const serviceDir = path4.join(root, "service");
29648
+ const logDir = path4.join(root, "logs");
29649
+ return {
29650
+ serviceDir,
29651
+ launcherCjs: path4.join(serviceDir, "parall-daemon-launcher.cjs"),
29652
+ legacyLauncherJs: path4.join(serviceDir, "parall-daemon-launcher.js"),
29653
+ launcherVbs: path4.join(serviceDir, "parall-daemon-launcher.vbs"),
29654
+ taskXml: path4.join(serviceDir, "task.xml"),
29655
+ pidFile: path4.join(root, "daemon.pid"),
29656
+ logDir,
29657
+ logFile: path4.join(logDir, "parall-daemon.log"),
29658
+ overlayEntry: path4.join(root, "bundle", "current", "parall-daemon.js"),
29659
+ runningMarker: path4.join(root, "bundle", "daemon-running")
29660
+ };
29661
+ }
29662
+ function vbsQuote(value) {
29663
+ return `"${value.replaceAll('"', '""')}"`;
29664
+ }
29665
+ function encodeUtf16LeBom(content) {
29666
+ return Buffer.from("\uFEFF" + content, "utf16le");
29667
+ }
29668
+ function xmlEscape(value) {
29669
+ return value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&apos;");
29670
+ }
29671
+ function buildLauncherVbs(p) {
29672
+ const runCommand2 = `"${p.nodeExe}" "${p.launcherCjs}"`;
29673
+ return [
29674
+ "' generated by `parall-daemon service install` - do not edit",
29675
+ 'Set sh = CreateObject("WScript.Shell")',
29676
+ `code = sh.Run(${vbsQuote(runCommand2)}, 0, True)`,
29677
+ "WScript.Quit code",
29678
+ ""
29679
+ ].join("\r\n");
29680
+ }
29681
+ function buildLauncherCjs(p) {
29682
+ return `// generated by \`parall-daemon service install\` - do not edit
29683
+ 'use strict';
29684
+ const fs = require('node:fs');
29685
+ const path = require('node:path');
29686
+ const { pathToFileURL } = require('node:url');
29687
+
29688
+ // Must be set before the daemon loads: the bootstrap reads it at import time
29689
+ // to enable supervised self-update.
29690
+ process.env.PRLL_DAEMON_MANAGED = '1';
29691
+
29692
+ const OVERLAY_ENTRY = ${JSON.stringify(p.overlayEntry)};
29693
+ const NPM_ENTRY = ${JSON.stringify(p.npmEntry)};
29694
+ const LOG_FILE = ${JSON.stringify(p.logFile)};
29695
+ const PID_FILE = ${JSON.stringify(p.pidFile)};
29696
+
29697
+ fs.mkdirSync(path.dirname(LOG_FILE), { recursive: true });
29698
+ try {
29699
+ if (fs.statSync(LOG_FILE).size > 20 * 1024 * 1024) {
29700
+ fs.renameSync(LOG_FILE, LOG_FILE + '.old');
29701
+ }
29702
+ } catch {}
29703
+
29704
+ // Synchronous writes so an abrupt exit (self-update exit(42), crash) cannot
29705
+ // lose the log tail. The daemon is not chatty enough for this to matter.
29706
+ const logFd = fs.openSync(LOG_FILE, 'a');
29707
+ for (const stream of [process.stdout, process.stderr]) {
29708
+ stream.write = (chunk, encoding, callback) => {
29709
+ try {
29710
+ fs.writeSync(
29711
+ logFd,
29712
+ Buffer.isBuffer(chunk)
29713
+ ? chunk
29714
+ : Buffer.from(chunk, typeof encoding === 'string' ? encoding : 'utf8'),
29715
+ );
29716
+ } catch {}
29717
+ const done = typeof encoding === 'function' ? encoding : callback;
29718
+ if (done) done();
29719
+ return true;
29720
+ };
29721
+ }
29722
+
29723
+ fs.writeFileSync(PID_FILE, String(process.pid));
29724
+ process.on('exit', () => {
29725
+ try {
29726
+ if (fs.readFileSync(PID_FILE, 'utf8').trim() === String(process.pid)) {
29727
+ fs.unlinkSync(PID_FILE);
29728
+ }
29729
+ } catch {}
29730
+ });
29731
+
29732
+ // Overlay-first, mirroring the launchd/systemd wrapper semantics.
29733
+ const entry = fs.existsSync(OVERLAY_ENTRY) ? OVERLAY_ENTRY : NPM_ENTRY;
29734
+ // The daemon derives bridge-bundle siblings and self-update mode from its
29735
+ // entry path - argv[1] must point at the real bundle entry, not this file.
29736
+ process.argv[1] = entry;
29737
+ import(pathToFileURL(entry).href).catch((err) => {
29738
+ process.stderr.write('launcher: failed to load ' + entry + ': ' + ((err && err.stack) || err) + '\\n');
29739
+ process.exit(1);
29740
+ });
29741
+ `;
29742
+ }
29743
+ function buildTaskXml(p) {
29744
+ const args = `//B //Nologo "${p.launcherVbs}"`;
29745
+ return `<?xml version="1.0" encoding="UTF-16"?>
29746
+ <Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
29747
+ <RegistrationInfo>
29748
+ <Description>Parall Daemon (BYOC machine supervisor)</Description>
29749
+ </RegistrationInfo>
29750
+ <Triggers>
29751
+ <LogonTrigger>
29752
+ <Enabled>true</Enabled>
29753
+ </LogonTrigger>
29754
+ <TimeTrigger>
29755
+ <StartBoundary>2020-01-01T00:00:00</StartBoundary>
29756
+ <Enabled>true</Enabled>
29757
+ <Repetition>
29758
+ <Interval>PT1H</Interval>
29759
+ </Repetition>
29760
+ </TimeTrigger>
29761
+ </Triggers>
29762
+ <Principals>
29763
+ <Principal id="Author">
29764
+ <LogonType>InteractiveToken</LogonType>
29765
+ <RunLevel>LeastPrivilege</RunLevel>
29766
+ </Principal>
29767
+ </Principals>
29768
+ <Settings>
29769
+ <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
29770
+ <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
29771
+ <StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
29772
+ <AllowHardTerminate>true</AllowHardTerminate>
29773
+ <StartWhenAvailable>true</StartWhenAvailable>
29774
+ <AllowStartOnDemand>true</AllowStartOnDemand>
29775
+ <Enabled>true</Enabled>
29776
+ <ExecutionTimeLimit>PT0S</ExecutionTimeLimit>
29777
+ <RestartOnFailure>
29778
+ <Interval>PT1M</Interval>
29779
+ <Count>99</Count>
29780
+ </RestartOnFailure>
29781
+ </Settings>
29782
+ <Actions Context="Author">
29783
+ <Exec>
29784
+ <Command>${xmlEscape(p.wscriptExe)}</Command>
29785
+ <Arguments>${xmlEscape(args)}</Arguments>
29786
+ </Exec>
29787
+ </Actions>
29788
+ </Task>
29789
+ `;
29790
+ }
29791
+ var WIN_TASK_NAME;
29792
+ var init_win_service = __esm({
29793
+ "ts/daemon/dist/win-service.js"() {
29794
+ "use strict";
29795
+ WIN_TASK_NAME = "ParallDaemon";
29796
+ }
29797
+ });
29798
+
29799
+ // ts/daemon/dist/win-lifecycle.js
29800
+ import * as path5 from "node:path";
29801
+ function probePidIdentity(deps, pid) {
29802
+ const script = `$p = Get-CimInstance Win32_Process -Filter 'ProcessId=${pid}'; if ($null -eq $p) { 'ABSENT' } else { 'PRESENT' + [char]9 + $p.Name + [char]9 + "$($p.CommandLine)" }`;
29803
+ const r = deps.run("powershell.exe", ["-NoProfile", "-Command", script]);
29804
+ if (r.code !== 0 || r.spawnError)
29805
+ return "indeterminate";
29806
+ const out = r.stdout.trim();
29807
+ if (out === "ABSENT")
29808
+ return "not-daemon";
29809
+ if (!out.startsWith("PRESENT "))
29810
+ return "indeterminate";
29811
+ const [, name = "", ...rest] = out.split(" ");
29812
+ const commandLine = rest.join(" ").trim();
29813
+ if (!/node/i.test(name))
29814
+ return "not-daemon";
29815
+ if (!commandLine) {
29816
+ return "indeterminate";
29817
+ }
29818
+ const launcherNeedle = path5.join(deps.paths.serviceDir, "parall-daemon-launcher").toLowerCase();
29819
+ return commandLine.toLowerCase().includes(launcherNeedle) ? "daemon" : "not-daemon";
29820
+ }
29821
+ function readTrackedPid(deps) {
29822
+ const raw = deps.fs.readFile(deps.paths.pidFile);
29823
+ if (raw === null)
29824
+ return null;
29825
+ const pid = Number(raw.trim());
29826
+ return Number.isInteger(pid) && pid > 0 ? pid : null;
29827
+ }
29828
+ function queryTaskExists(deps) {
29829
+ const script = `try { Get-ScheduledTask -TaskName '${WIN_TASK_NAME}' -ErrorAction Stop | Out-Null; 'PRESENT' } catch { if ($_.CategoryInfo.Category -eq 'ObjectNotFound') { 'ABSENT' } else { 'ERROR' } }`;
29830
+ const r = deps.run("powershell.exe", ["-NoProfile", "-Command", script]);
29831
+ if (r.code !== 0 || r.spawnError)
29832
+ return "indeterminate";
29833
+ const out = r.stdout.trim();
29834
+ if (out === "PRESENT")
29835
+ return true;
29836
+ if (out === "ABSENT")
29837
+ return false;
29838
+ return "indeterminate";
29839
+ }
29840
+ function queryTaskDisabled(deps) {
29841
+ const r = deps.run("schtasks", ["/Query", "/TN", WIN_TASK_NAME, "/XML"]);
29842
+ if (r.code !== 0 || r.spawnError)
29843
+ return "indeterminate";
29844
+ return /<Enabled>\s*false\s*<\/Enabled>/i.test(r.stdout);
29845
+ }
29846
+ function confirmProcessGone(deps, problems) {
29847
+ const pid = readTrackedPid(deps);
29848
+ if (pid === null)
29849
+ return true;
29850
+ let identity = probePidIdentity(deps, pid);
29851
+ if (identity === "not-daemon")
29852
+ return true;
29853
+ if (identity === "indeterminate") {
29854
+ problems.push(`cannot verify ownership of pid ${pid} (process query failed) \u2014 leaving the pidfile in place`);
29855
+ return false;
29856
+ }
29857
+ const kill = deps.run("taskkill", ["/T", "/F", "/PID", String(pid)]);
29858
+ const deadline = deps.now() + PROCESS_EXIT_TIMEOUT_MS;
29859
+ for (; ; ) {
29860
+ identity = probePidIdentity(deps, pid);
29861
+ if (identity === "not-daemon")
29862
+ return true;
29863
+ if (identity === "indeterminate") {
29864
+ problems.push(`process query failed while confirming pid ${pid} exited`);
29865
+ return false;
29866
+ }
29867
+ if (deps.now() >= deadline) {
29868
+ problems.push(`daemon process ${pid} is still running after taskkill` + (kill.code !== 0 ? ` (taskkill exit ${kill.code ?? "spawn-failed"})` : ""));
29869
+ return false;
29870
+ }
29871
+ deps.sleep(PROCESS_EXIT_POLL_MS);
29872
+ }
29873
+ }
29874
+ function cleanupTracking(deps, problems) {
29875
+ if (!deps.fs.unlink(deps.paths.pidFile)) {
29876
+ problems.push(`could not remove pidfile ${deps.paths.pidFile}`);
29877
+ }
29878
+ if (!deps.fs.unlink(deps.paths.runningMarker)) {
29879
+ problems.push(`could not remove crash marker ${deps.paths.runningMarker}`);
29880
+ }
29881
+ }
29882
+ function stopDaemonWindows(deps) {
29883
+ const problems = [];
29884
+ const exists = queryTaskExists(deps);
29885
+ if (exists === "indeterminate") {
29886
+ problems.push("schtasks could not be executed to query the task");
29887
+ return { ok: false, problems };
29888
+ }
29889
+ if (exists) {
29890
+ const disable = deps.run("schtasks", ["/Change", "/TN", WIN_TASK_NAME, "/DISABLE"]);
29891
+ if (disable.code !== 0) {
29892
+ problems.push(`could not disable the task (schtasks /Change exit ${disable.code ?? "spawn-failed"})`);
29893
+ return { ok: false, problems };
29894
+ }
29895
+ const disabled = queryTaskDisabled(deps);
29896
+ if (disabled !== true) {
29897
+ problems.push(disabled === "indeterminate" ? "could not read back the task state after disabling" : "task did not read back as disabled");
29898
+ return { ok: false, problems };
29899
+ }
29900
+ deps.run("schtasks", ["/End", "/TN", WIN_TASK_NAME]);
29901
+ }
29902
+ if (!confirmProcessGone(deps, problems)) {
29903
+ return { ok: false, problems };
29904
+ }
29905
+ cleanupTracking(deps, problems);
29906
+ return { ok: problems.length === 0, problems };
29907
+ }
29908
+ function uninstallDaemonWindows(deps) {
29909
+ const problems = [];
29910
+ const exists = queryTaskExists(deps);
29911
+ if (exists === "indeterminate") {
29912
+ problems.push("schtasks could not be executed to query the task");
29913
+ return { ok: false, problems };
29914
+ }
29915
+ if (exists) {
29916
+ const disable = deps.run("schtasks", ["/Change", "/TN", WIN_TASK_NAME, "/DISABLE"]);
29917
+ if (disable.code !== 0) {
29918
+ problems.push(`could not disable the task before uninstalling (schtasks /Change exit ${disable.code ?? "spawn-failed"})`);
29919
+ return { ok: false, problems };
29920
+ }
29921
+ const disabled = queryTaskDisabled(deps);
29922
+ if (disabled !== true) {
29923
+ problems.push(disabled === "indeterminate" ? "could not read back the task state after disabling" : "task did not read back as disabled before uninstall");
29924
+ return { ok: false, problems };
29925
+ }
29926
+ deps.run("schtasks", ["/End", "/TN", WIN_TASK_NAME]);
29927
+ }
29928
+ if (!confirmProcessGone(deps, problems)) {
29929
+ return { ok: false, problems };
29930
+ }
29931
+ if (exists) {
29932
+ const del = deps.run("schtasks", ["/Delete", "/TN", WIN_TASK_NAME, "/F"]);
29933
+ if (del.code !== 0) {
29934
+ problems.push(`could not delete the task (schtasks /Delete exit ${del.code ?? "spawn-failed"})`);
29935
+ return { ok: false, problems };
29936
+ }
29937
+ const stillThere = queryTaskExists(deps);
29938
+ if (stillThere !== false) {
29939
+ problems.push(stillThere === "indeterminate" ? "could not confirm the task was deleted" : "task is still registered after /Delete");
29940
+ return { ok: false, problems };
29941
+ }
29942
+ }
29943
+ cleanupTracking(deps, problems);
29944
+ for (const artifact of [
29945
+ deps.paths.launcherCjs,
29946
+ deps.paths.legacyLauncherJs,
29947
+ deps.paths.launcherVbs,
29948
+ deps.paths.taskXml
29949
+ ]) {
29950
+ if (!deps.fs.unlink(artifact)) {
29951
+ problems.push(`could not remove ${artifact}`);
29952
+ }
29953
+ }
29954
+ return { ok: problems.length === 0, problems };
29955
+ }
29956
+ var PROCESS_EXIT_TIMEOUT_MS, PROCESS_EXIT_POLL_MS;
29957
+ var init_win_lifecycle = __esm({
29958
+ "ts/daemon/dist/win-lifecycle.js"() {
29959
+ "use strict";
29960
+ init_win_service();
29961
+ PROCESS_EXIT_TIMEOUT_MS = 5e3;
29962
+ PROCESS_EXIT_POLL_MS = 200;
29963
+ }
29964
+ });
29965
+
29639
29966
  // ts/daemon/dist/updater-manifest.js
29640
29967
  import { verify } from "node:crypto";
29641
29968
  function canonicalize(obj) {
@@ -29736,7 +30063,7 @@ __export(updater_exports, {
29736
30063
  DaemonUpdater: () => DaemonUpdater
29737
30064
  });
29738
30065
  import * as fs2 from "node:fs";
29739
- import * as path4 from "node:path";
30066
+ import * as path6 from "node:path";
29740
30067
  import * as https2 from "node:https";
29741
30068
  import * as http2 from "node:http";
29742
30069
  import { createHash } from "node:crypto";
@@ -29832,20 +30159,20 @@ MCowBQYDK2VwAyEAQHQAZThNX7+deJNyHl/5DgiAa1OHx7UQoJotam0JhUk=
29832
30159
  return false;
29833
30160
  if (!state.previous_version)
29834
30161
  return false;
29835
- const previousDir = path4.join(this.bundleDir, "versions", state.previous_version);
30162
+ const previousDir = path6.join(this.bundleDir, "versions", state.previous_version);
29836
30163
  if (!fs2.existsSync(previousDir))
29837
30164
  return false;
29838
30165
  this.log.warn(`rollback: ${current.version} failed ${state.boot_count} boots, reverting to ${state.previous_version}`);
29839
30166
  if (process.platform === "win32") {
29840
- const currentDir = path4.join(this.bundleDir, "current");
30167
+ const currentDir = path6.join(this.bundleDir, "current");
29841
30168
  if (fs2.existsSync(currentDir)) {
29842
30169
  for (const file of fs2.readdirSync(currentDir)) {
29843
- fs2.unlinkSync(path4.join(currentDir, file));
30170
+ fs2.unlinkSync(path6.join(currentDir, file));
29844
30171
  }
29845
30172
  }
29846
30173
  fs2.mkdirSync(currentDir, { recursive: true });
29847
30174
  for (const file of fs2.readdirSync(previousDir)) {
29848
- fs2.copyFileSync(path4.join(previousDir, file), path4.join(currentDir, file));
30175
+ fs2.copyFileSync(path6.join(previousDir, file), path6.join(currentDir, file));
29849
30176
  }
29850
30177
  } else {
29851
30178
  this.swapSymlink(state.previous_version);
@@ -29967,11 +30294,11 @@ MCowBQYDK2VwAyEAQHQAZThNX7+deJNyHl/5DgiAa1OHx7UQoJotam0JhUk=
29967
30294
  return false;
29968
30295
  }
29969
30296
  }
29970
- const stagingDir = path4.join(this.bundleDir, "staging");
30297
+ const stagingDir = path6.join(this.bundleDir, "staging");
29971
30298
  this.cleanDir(stagingDir);
29972
30299
  fs2.mkdirSync(stagingDir, { recursive: true });
29973
30300
  for (const [filename, meta] of Object.entries(remote.files)) {
29974
- const filePath = path4.join(stagingDir, filename);
30301
+ const filePath = path6.join(stagingDir, filename);
29975
30302
  const fileUrl = `${this.cdnBaseUrl}/${remote.version}/${filename}`;
29976
30303
  try {
29977
30304
  await this.downloadFile(fileUrl, filePath);
@@ -29993,7 +30320,7 @@ MCowBQYDK2VwAyEAQHQAZThNX7+deJNyHl/5DgiAa1OHx7UQoJotam0JhUk=
29993
30320
  return false;
29994
30321
  }
29995
30322
  }
29996
- fs2.writeFileSync(path4.join(stagingDir, "manifest.json"), JSON.stringify(remote, null, 2));
30323
+ fs2.writeFileSync(path6.join(stagingDir, "manifest.json"), JSON.stringify(remote, null, 2));
29997
30324
  const rollbackVersion = state?.confirmed_version ?? local?.version;
29998
30325
  const newState = {
29999
30326
  confirmed_version: rollbackVersion,
@@ -30008,9 +30335,9 @@ MCowBQYDK2VwAyEAQHQAZThNX7+deJNyHl/5DgiAa1OHx7UQoJotam0JhUk=
30008
30335
  return true;
30009
30336
  }
30010
30337
  atomicSwap(stagingDir, newVersion) {
30011
- const versionsDir = path4.join(this.bundleDir, "versions");
30012
- const targetDir = path4.join(versionsDir, newVersion);
30013
- const currentLink = path4.join(this.bundleDir, "current");
30338
+ const versionsDir = path6.join(this.bundleDir, "versions");
30339
+ const targetDir = path6.join(versionsDir, newVersion);
30340
+ const currentLink = path6.join(this.bundleDir, "current");
30014
30341
  fs2.mkdirSync(versionsDir, { recursive: true });
30015
30342
  if (fs2.existsSync(targetDir)) {
30016
30343
  fs2.rmSync(targetDir, { recursive: true });
@@ -30020,12 +30347,12 @@ MCowBQYDK2VwAyEAQHQAZThNX7+deJNyHl/5DgiAa1OHx7UQoJotam0JhUk=
30020
30347
  const currentDir = currentLink;
30021
30348
  if (fs2.existsSync(currentDir)) {
30022
30349
  for (const file of fs2.readdirSync(currentDir)) {
30023
- fs2.unlinkSync(path4.join(currentDir, file));
30350
+ fs2.unlinkSync(path6.join(currentDir, file));
30024
30351
  }
30025
30352
  }
30026
30353
  fs2.mkdirSync(currentDir, { recursive: true });
30027
30354
  for (const file of fs2.readdirSync(targetDir)) {
30028
- fs2.copyFileSync(path4.join(targetDir, file), path4.join(currentDir, file));
30355
+ fs2.copyFileSync(path6.join(targetDir, file), path6.join(currentDir, file));
30029
30356
  }
30030
30357
  } else {
30031
30358
  this.swapSymlink(newVersion);
@@ -30033,7 +30360,7 @@ MCowBQYDK2VwAyEAQHQAZThNX7+deJNyHl/5DgiAa1OHx7UQoJotam0JhUk=
30033
30360
  this.pruneOldVersions(versionsDir, newVersion);
30034
30361
  }
30035
30362
  swapSymlink(version) {
30036
- const currentLink = path4.join(this.bundleDir, "current");
30363
+ const currentLink = path6.join(this.bundleDir, "current");
30037
30364
  const tmpLink = `${currentLink}.new`;
30038
30365
  try {
30039
30366
  fs2.unlinkSync(tmpLink);
@@ -30052,7 +30379,7 @@ MCowBQYDK2VwAyEAQHQAZThNX7+deJNyHl/5DgiAa1OHx7UQoJotam0JhUk=
30052
30379
  try {
30053
30380
  for (const entry of fs2.readdirSync(versionsDir)) {
30054
30381
  if (!keep.has(entry)) {
30055
- fs2.rmSync(path4.join(versionsDir, entry), { recursive: true });
30382
+ fs2.rmSync(path6.join(versionsDir, entry), { recursive: true });
30056
30383
  }
30057
30384
  }
30058
30385
  } catch {
@@ -30060,8 +30387,8 @@ MCowBQYDK2VwAyEAQHQAZThNX7+deJNyHl/5DgiAa1OHx7UQoJotam0JhUk=
30060
30387
  }
30061
30388
  // --- Manifest & State I/O ---
30062
30389
  loadLocalManifest() {
30063
- const currentDir = path4.join(this.bundleDir, "current");
30064
- const manifestPath = path4.join(currentDir, "manifest.json");
30390
+ const currentDir = path6.join(this.bundleDir, "current");
30391
+ const manifestPath = path6.join(currentDir, "manifest.json");
30065
30392
  try {
30066
30393
  return JSON.parse(fs2.readFileSync(manifestPath, "utf-8"));
30067
30394
  } catch {
@@ -30069,7 +30396,7 @@ MCowBQYDK2VwAyEAQHQAZThNX7+deJNyHl/5DgiAa1OHx7UQoJotam0JhUk=
30069
30396
  }
30070
30397
  }
30071
30398
  loadUpdateState() {
30072
- const statePath = path4.join(this.bundleDir, "update-state.json");
30399
+ const statePath = path6.join(this.bundleDir, "update-state.json");
30073
30400
  try {
30074
30401
  return JSON.parse(fs2.readFileSync(statePath, "utf-8"));
30075
30402
  } catch {
@@ -30077,8 +30404,8 @@ MCowBQYDK2VwAyEAQHQAZThNX7+deJNyHl/5DgiAa1OHx7UQoJotam0JhUk=
30077
30404
  }
30078
30405
  }
30079
30406
  saveUpdateState(state) {
30080
- const statePath = path4.join(this.bundleDir, "update-state.json");
30081
- const stateDir = path4.dirname(statePath);
30407
+ const statePath = path6.join(this.bundleDir, "update-state.json");
30408
+ const stateDir = path6.dirname(statePath);
30082
30409
  fs2.mkdirSync(stateDir, { recursive: true });
30083
30410
  const tmpPath = `${statePath}.tmp-${process.pid}-${Date.now()}`;
30084
30411
  let fd;
@@ -30122,7 +30449,7 @@ MCowBQYDK2VwAyEAQHQAZThNX7+deJNyHl/5DgiAa1OHx7UQoJotam0JhUk=
30122
30449
  return new URL(location, fromUrl).toString();
30123
30450
  }
30124
30451
  httpGet(url, maxRedirects = 5) {
30125
- return new Promise((resolve8, reject) => {
30452
+ return new Promise((resolve9, reject) => {
30126
30453
  const mod2 = url.startsWith("https") ? https2 : http2;
30127
30454
  const req = mod2.get(url, (res) => {
30128
30455
  if (this.isRedirect(res.statusCode)) {
@@ -30136,7 +30463,7 @@ MCowBQYDK2VwAyEAQHQAZThNX7+deJNyHl/5DgiAa1OHx7UQoJotam0JhUk=
30136
30463
  return;
30137
30464
  }
30138
30465
  res.resume();
30139
- this.httpGet(redirectUrl, maxRedirects - 1).then(resolve8, reject);
30466
+ this.httpGet(redirectUrl, maxRedirects - 1).then(resolve9, reject);
30140
30467
  return;
30141
30468
  }
30142
30469
  res.resume();
@@ -30150,7 +30477,7 @@ MCowBQYDK2VwAyEAQHQAZThNX7+deJNyHl/5DgiAa1OHx7UQoJotam0JhUk=
30150
30477
  }
30151
30478
  const chunks = [];
30152
30479
  res.on("data", (chunk) => chunks.push(chunk));
30153
- res.on("end", () => resolve8(Buffer.concat(chunks).toString("utf-8")));
30480
+ res.on("end", () => resolve9(Buffer.concat(chunks).toString("utf-8")));
30154
30481
  res.on("error", reject);
30155
30482
  });
30156
30483
  req.on("error", reject);
@@ -30160,7 +30487,7 @@ MCowBQYDK2VwAyEAQHQAZThNX7+deJNyHl/5DgiAa1OHx7UQoJotam0JhUk=
30160
30487
  });
30161
30488
  }
30162
30489
  downloadFile(url, dest, maxRedirects = 5) {
30163
- return new Promise((resolve8, reject) => {
30490
+ return new Promise((resolve9, reject) => {
30164
30491
  const mod2 = url.startsWith("https") ? https2 : http2;
30165
30492
  const req = mod2.get(url, (res) => {
30166
30493
  if (this.isRedirect(res.statusCode)) {
@@ -30174,7 +30501,7 @@ MCowBQYDK2VwAyEAQHQAZThNX7+deJNyHl/5DgiAa1OHx7UQoJotam0JhUk=
30174
30501
  return;
30175
30502
  }
30176
30503
  res.resume();
30177
- this.downloadFile(redirectUrl, dest, maxRedirects - 1).then(resolve8, reject);
30504
+ this.downloadFile(redirectUrl, dest, maxRedirects - 1).then(resolve9, reject);
30178
30505
  return;
30179
30506
  }
30180
30507
  res.resume();
@@ -30190,7 +30517,7 @@ MCowBQYDK2VwAyEAQHQAZThNX7+deJNyHl/5DgiAa1OHx7UQoJotam0JhUk=
30190
30517
  res.pipe(file);
30191
30518
  file.on("finish", () => {
30192
30519
  file.close();
30193
- resolve8();
30520
+ resolve9();
30194
30521
  });
30195
30522
  file.on("error", (err) => {
30196
30523
  fs2.unlinkSync(dest);
@@ -30214,10 +30541,10 @@ MCowBQYDK2VwAyEAQHQAZThNX7+deJNyHl/5DgiAa1OHx7UQoJotam0JhUk=
30214
30541
  });
30215
30542
 
30216
30543
  // ts/daemon/dist/cli.js
30217
- import { execSync, spawn } from "node:child_process";
30544
+ import { execFileSync, execSync, spawn } from "node:child_process";
30218
30545
  import * as fs3 from "node:fs";
30219
30546
  import * as os3 from "node:os";
30220
- import * as path5 from "node:path";
30547
+ import * as path7 from "node:path";
30221
30548
  import * as readline from "node:readline";
30222
30549
  function readConfig() {
30223
30550
  try {
@@ -30233,10 +30560,10 @@ function writeConfig(config) {
30233
30560
  }
30234
30561
  function prompt(question) {
30235
30562
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
30236
- return new Promise((resolve8) => {
30563
+ return new Promise((resolve9) => {
30237
30564
  rl.question(question, (answer) => {
30238
30565
  rl.close();
30239
- resolve8(answer.trim());
30566
+ resolve9(answer.trim());
30240
30567
  });
30241
30568
  });
30242
30569
  }
@@ -30246,11 +30573,156 @@ function isMacOS() {
30246
30573
  function isLinux() {
30247
30574
  return process.platform === "linux";
30248
30575
  }
30576
+ function isWindows() {
30577
+ return process.platform === "win32";
30578
+ }
30579
+ function sleepSync(ms) {
30580
+ Atomics.wait(SLEEP_SIGNAL, 0, 0, ms);
30581
+ }
30582
+ function runWinCmd(file, args) {
30583
+ try {
30584
+ const stdout = execFileSync(file, args, {
30585
+ encoding: "utf8",
30586
+ windowsHide: true,
30587
+ stdio: ["ignore", "pipe", "ignore"],
30588
+ timeout: WIN_CMD_TIMEOUT_MS
30589
+ });
30590
+ return { code: 0, stdout };
30591
+ } catch (err) {
30592
+ const e = err;
30593
+ const code = typeof e.status === "number" ? e.status : null;
30594
+ return {
30595
+ code,
30596
+ stdout: String(e.stdout ?? ""),
30597
+ spawnError: code === null ? String(e.message ?? err) : void 0
30598
+ };
30599
+ }
30600
+ }
30601
+ function winDeps() {
30602
+ return {
30603
+ run: runWinCmd,
30604
+ fs: {
30605
+ readFile(p) {
30606
+ try {
30607
+ return fs3.readFileSync(p, "utf8");
30608
+ } catch {
30609
+ return null;
30610
+ }
30611
+ },
30612
+ unlink(p) {
30613
+ try {
30614
+ fs3.unlinkSync(p);
30615
+ return true;
30616
+ } catch (err) {
30617
+ return err.code === "ENOENT";
30618
+ }
30619
+ }
30620
+ },
30621
+ paths: winServicePaths(os3.homedir()),
30622
+ sleep: sleepSync,
30623
+ now: () => Date.now()
30624
+ };
30625
+ }
30626
+ function reportWinProblems(problems) {
30627
+ for (const problem of problems) {
30628
+ console.error(`ERROR: ${problem}`);
30629
+ }
30630
+ console.error("State was left in place so nothing is orphaned; fix the cause and retry.");
30631
+ }
30632
+ function installServiceWindows() {
30633
+ let npmEntry;
30634
+ try {
30635
+ npmEntry = fs3.realpathSync(process.argv[1] ?? "");
30636
+ } catch {
30637
+ console.error("Cannot resolve the daemon entry script; reinstall with `npm install -g @parall/daemon`.");
30638
+ process.exit(1);
30639
+ }
30640
+ if (/[\\/]_npx[\\/]/.test(npmEntry)) {
30641
+ console.warn("Warning: installing from an npx cache path. Run `npm install -g @parall/daemon` and re-run\n`parall-daemon service install`, or the service breaks when the npx cache is pruned\n(a completed self-update heals this by switching to the overlay bundle).");
30642
+ }
30643
+ const p = winServicePaths(os3.homedir());
30644
+ fs3.mkdirSync(p.serviceDir, { recursive: true });
30645
+ fs3.mkdirSync(p.logDir, { recursive: true });
30646
+ fs3.writeFileSync(p.launcherCjs, buildLauncherCjs({
30647
+ npmEntry,
30648
+ overlayEntry: p.overlayEntry,
30649
+ pidFile: p.pidFile,
30650
+ logFile: p.logFile
30651
+ }));
30652
+ try {
30653
+ fs3.unlinkSync(p.legacyLauncherJs);
30654
+ } catch {
30655
+ }
30656
+ const wscriptExe = path7.join(process.env.SystemRoot || "C:\\Windows", "System32", "wscript.exe");
30657
+ fs3.writeFileSync(p.launcherVbs, encodeUtf16LeBom(buildLauncherVbs({ nodeExe: process.execPath, launcherCjs: p.launcherCjs })));
30658
+ fs3.writeFileSync(p.taskXml, encodeUtf16LeBom(buildTaskXml({ wscriptExe, launcherVbs: p.launcherVbs })));
30659
+ const create = runWinCmd("schtasks", ["/Create", "/TN", WIN_TASK_NAME, "/XML", p.taskXml, "/F"]);
30660
+ if (create.code !== 0) {
30661
+ console.error(`ERROR: could not register the Task Scheduler task (schtasks /Create exit ${create.code ?? "spawn-failed"}).`);
30662
+ console.error(` Task XML: ${p.taskXml}`);
30663
+ process.exit(1);
30664
+ }
30665
+ const run = runWinCmd("schtasks", ["/Run", "/TN", WIN_TASK_NAME]);
30666
+ if (run.code !== 0) {
30667
+ console.error(`ERROR: the task registered but would not start (schtasks /Run exit ${run.code ?? "spawn-failed"}).`);
30668
+ console.error(` Start it from Task Scheduler, or check ${p.logFile}.`);
30669
+ process.exit(1);
30670
+ }
30671
+ console.log(`Task Scheduler task installed: ${WIN_TASK_NAME} (artifacts in ${p.serviceDir})`);
30672
+ console.log("Task registered and triggered. Check `parall-daemon status` for the daemon itself.");
30673
+ console.log(`Logs: ${p.logFile}`);
30674
+ }
30675
+ function stopWindows() {
30676
+ const result = stopDaemonWindows(winDeps());
30677
+ if (!result.ok) {
30678
+ reportWinProblems(result.problems);
30679
+ process.exit(1);
30680
+ }
30681
+ console.log("Daemon stopped (Task Scheduler task disabled). Re-arm with `parall-daemon service install`.");
30682
+ }
30683
+ function statusWindows() {
30684
+ const deps = winDeps();
30685
+ const exists = queryTaskExists(deps);
30686
+ if (exists === "indeterminate") {
30687
+ console.log("Service: unknown (schtasks query failed)");
30688
+ } else if (!exists) {
30689
+ console.log("Service: not installed");
30690
+ } else {
30691
+ const disabled = queryTaskDisabled(deps);
30692
+ const suffix = disabled === true ? ", disabled" : disabled === "indeterminate" ? ", state unknown" : "";
30693
+ console.log(`Service: installed${suffix} (Task Scheduler: ${WIN_TASK_NAME})`);
30694
+ }
30695
+ const pid = readTrackedPid(deps);
30696
+ if (pid === null) {
30697
+ console.log("Daemon: stopped");
30698
+ return;
30699
+ }
30700
+ switch (probePidIdentity(deps, pid)) {
30701
+ case "daemon":
30702
+ console.log("Daemon: running");
30703
+ console.log(`PID: ${pid}`);
30704
+ break;
30705
+ case "not-daemon":
30706
+ console.log("Daemon: stopped (stale pidfile)");
30707
+ break;
30708
+ case "indeterminate":
30709
+ console.log(`Daemon: unknown (could not verify pid ${pid} \u2014 process query failed)`);
30710
+ break;
30711
+ }
30712
+ }
30713
+ function serviceUninstallWindows() {
30714
+ const result = uninstallDaemonWindows(winDeps());
30715
+ if (!result.ok) {
30716
+ reportWinProblems(result.problems);
30717
+ process.exit(1);
30718
+ }
30719
+ console.log("Task Scheduler task uninstalled (logs kept).");
30720
+ }
30249
30721
  function plistPath() {
30250
- return path5.join(os3.homedir(), "Library", "LaunchAgents", `${PLIST_LABEL}.plist`);
30722
+ return path7.join(os3.homedir(), "Library", "LaunchAgents", `${PLIST_LABEL}.plist`);
30251
30723
  }
30252
30724
  function systemdUnitPath() {
30253
- return path5.join(os3.homedir(), ".config", "systemd", "user", "parall-daemon.service");
30725
+ return path7.join(os3.homedir(), ".config", "systemd", "user", "parall-daemon.service");
30254
30726
  }
30255
30727
  function getDaemonBin() {
30256
30728
  try {
@@ -30260,7 +30732,7 @@ function getDaemonBin() {
30260
30732
  }
30261
30733
  }
30262
30734
  function generatePlist(daemonBin) {
30263
- const logPath = path5.join(os3.homedir(), "Library", "Logs", "parall-daemon.log");
30735
+ const logPath = path7.join(os3.homedir(), "Library", "Logs", "parall-daemon.log");
30264
30736
  return `<?xml version="1.0" encoding="UTF-8"?>
30265
30737
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
30266
30738
  <plist version="1.0">
@@ -30313,16 +30785,20 @@ function installService() {
30313
30785
  console.error("No config found. Run `parall-daemon init` first.");
30314
30786
  process.exit(1);
30315
30787
  }
30788
+ if (isWindows()) {
30789
+ installServiceWindows();
30790
+ return;
30791
+ }
30316
30792
  const bin = getDaemonBin();
30317
30793
  if (isMacOS()) {
30318
- const dir = path5.dirname(plistPath());
30794
+ const dir = path7.dirname(plistPath());
30319
30795
  fs3.mkdirSync(dir, { recursive: true });
30320
30796
  fs3.writeFileSync(plistPath(), generatePlist(bin));
30321
30797
  execSync(`launchctl bootout gui/$(id -u) ${plistPath()} 2>/dev/null || true`);
30322
30798
  execSync(`launchctl bootstrap gui/$(id -u) ${plistPath()}`);
30323
30799
  console.log(`launchd agent installed: ${plistPath()}`);
30324
30800
  } else if (isLinux()) {
30325
- const dir = path5.dirname(systemdUnitPath());
30801
+ const dir = path7.dirname(systemdUnitPath());
30326
30802
  fs3.mkdirSync(dir, { recursive: true });
30327
30803
  fs3.writeFileSync(systemdUnitPath(), generateSystemdUnit(bin));
30328
30804
  execSync("systemctl --user daemon-reload");
@@ -30351,6 +30827,10 @@ async function cmdInit() {
30351
30827
  function cmdStatus() {
30352
30828
  const config = readConfig();
30353
30829
  console.log(`Config: ${config ? CONFIG_PATH : "not configured"}`);
30830
+ if (isWindows()) {
30831
+ statusWindows();
30832
+ return;
30833
+ }
30354
30834
  if (isMacOS()) {
30355
30835
  try {
30356
30836
  const output = execSync(`launchctl print gui/$(id -u)/${PLIST_LABEL} 2>&1`, {
@@ -30374,6 +30854,10 @@ function cmdStatus() {
30374
30854
  }
30375
30855
  }
30376
30856
  function cmdStop() {
30857
+ if (isWindows()) {
30858
+ stopWindows();
30859
+ return;
30860
+ }
30377
30861
  if (isMacOS()) {
30378
30862
  execSync(`launchctl bootout gui/$(id -u) ${plistPath()} 2>/dev/null || true`, {
30379
30863
  stdio: "inherit"
@@ -30391,7 +30875,23 @@ function cmdLogs(lines) {
30391
30875
  child2.on("exit", (code) => process.exit(code ?? 0));
30392
30876
  return;
30393
30877
  }
30394
- const logPath = path5.join(os3.homedir(), "Library", "Logs", "parall-daemon.log");
30878
+ if (isWindows()) {
30879
+ const p = winServicePaths(os3.homedir());
30880
+ if (!fs3.existsSync(p.logFile)) {
30881
+ console.log("No log file found at", p.logFile);
30882
+ return;
30883
+ }
30884
+ const tailCount = Number.parseInt(lines, 10);
30885
+ const tail = Number.isInteger(tailCount) && tailCount > 0 ? tailCount : 50;
30886
+ const child2 = spawn("powershell.exe", [
30887
+ "-NoProfile",
30888
+ "-Command",
30889
+ `Get-Content -LiteralPath $env:PRLL_DAEMON_LOG_PATH -Tail ${tail} -Wait`
30890
+ ], { stdio: "inherit", env: { ...process.env, PRLL_DAEMON_LOG_PATH: p.logFile } });
30891
+ child2.on("exit", (code) => process.exit(code ?? 0));
30892
+ return;
30893
+ }
30894
+ const logPath = path7.join(os3.homedir(), "Library", "Logs", "parall-daemon.log");
30395
30895
  if (!fs3.existsSync(logPath)) {
30396
30896
  console.log("No log file found at", logPath);
30397
30897
  return;
@@ -30400,6 +30900,10 @@ function cmdLogs(lines) {
30400
30900
  child.on("exit", (code) => process.exit(code ?? 0));
30401
30901
  }
30402
30902
  function cmdServiceUninstall() {
30903
+ if (isWindows()) {
30904
+ serviceUninstallWindows();
30905
+ return;
30906
+ }
30403
30907
  if (isMacOS()) {
30404
30908
  execSync(`launchctl bootout gui/$(id -u) ${plistPath()} 2>/dev/null || true`);
30405
30909
  if (fs3.existsSync(plistPath()))
@@ -30463,7 +30967,7 @@ Usage:
30463
30967
  parall-daemon stop Stop the background service
30464
30968
  parall-daemon update [--check] Check for / apply daemon updates
30465
30969
  parall-daemon logs [-n LINES] Tail daemon logs
30466
- parall-daemon service install Install as background service (launchd/systemd)
30970
+ parall-daemon service install Install as background service (launchd/systemd/Task Scheduler)
30467
30971
  parall-daemon service uninstall Uninstall background service
30468
30972
  parall-daemon help Show this help
30469
30973
  `.trim());
@@ -30523,30 +31027,34 @@ async function runCLI(args) {
30523
31027
  return "run-daemon";
30524
31028
  }
30525
31029
  }
30526
- var CONFIG_DIR, CONFIG_PATH, PLIST_LABEL;
31030
+ var CONFIG_DIR, CONFIG_PATH, SLEEP_SIGNAL, WIN_CMD_TIMEOUT_MS, PLIST_LABEL;
30527
31031
  var init_cli = __esm({
30528
31032
  "ts/daemon/dist/cli.js"() {
30529
31033
  "use strict";
30530
31034
  init_config();
31035
+ init_win_service();
31036
+ init_win_lifecycle();
30531
31037
  CONFIG_DIR = daemonConfigDir();
30532
31038
  CONFIG_PATH = daemonConfigPath();
31039
+ SLEEP_SIGNAL = new Int32Array(new SharedArrayBuffer(4));
31040
+ WIN_CMD_TIMEOUT_MS = 2e4;
30533
31041
  PLIST_LABEL = "com.parall.daemon";
30534
31042
  }
30535
31043
  });
30536
31044
 
30537
31045
  // ts/daemon/dist/clip-runtime/bun-resolver.js
30538
31046
  import * as fs4 from "node:fs";
30539
- import * as path6 from "node:path";
30540
- import { execFileSync } from "node:child_process";
31047
+ import * as path8 from "node:path";
31048
+ import { execFileSync as execFileSync2 } from "node:child_process";
30541
31049
  function findBunBinary() {
30542
- const isWindows = process.platform === "win32";
30543
- const binName = isWindows ? "bun.exe" : "bun";
30544
- const embedded = path6.join(path6.dirname(process.execPath), binName);
31050
+ const isWindows2 = process.platform === "win32";
31051
+ const binName = isWindows2 ? "bun.exe" : "bun";
31052
+ const embedded = path8.join(path8.dirname(process.execPath), binName);
30545
31053
  if (fs4.existsSync(embedded))
30546
31054
  return embedded;
30547
- if (!isWindows) {
31055
+ if (!isWindows2) {
30548
31056
  const candidates = [
30549
- path6.join(process.env.HOME || "", ".bun", "bin", "bun"),
31057
+ path8.join(process.env.HOME || "", ".bun", "bin", "bun"),
30550
31058
  "/usr/local/bin/bun",
30551
31059
  "/opt/homebrew/bin/bun"
30552
31060
  ];
@@ -30555,10 +31063,10 @@ function findBunBinary() {
30555
31063
  return candidate;
30556
31064
  }
30557
31065
  }
30558
- const lookupCmd = isWindows ? "where.exe" : "which";
30559
- const lookupArg = isWindows ? "bun.exe" : "bun";
31066
+ const lookupCmd = isWindows2 ? "where.exe" : "which";
31067
+ const lookupArg = isWindows2 ? "bun.exe" : "bun";
30560
31068
  try {
30561
- const result = execFileSync(lookupCmd, [lookupArg], { encoding: "utf-8" }).trim();
31069
+ const result = execFileSync2(lookupCmd, [lookupArg], { encoding: "utf-8" }).trim();
30562
31070
  const firstLine = result.split("\n")[0]?.trim();
30563
31071
  if (firstLine)
30564
31072
  return firstLine;
@@ -30574,9 +31082,9 @@ var init_bun_resolver = __esm({
30574
31082
 
30575
31083
  // ts/daemon/dist/clip-runtime/clip-installer.js
30576
31084
  import * as fs5 from "node:fs";
30577
- import * as path7 from "node:path";
31085
+ import * as path9 from "node:path";
30578
31086
  import * as crypto from "node:crypto";
30579
- import { execFileSync as execFileSync2 } from "node:child_process";
31087
+ import { execFileSync as execFileSync3 } from "node:child_process";
30580
31088
  import { pipeline } from "node:stream/promises";
30581
31089
  function parseSource(source) {
30582
31090
  const trimmed = source.trim();
@@ -30615,17 +31123,17 @@ async function httpGet(url, maxRedirects = 10) {
30615
31123
  if (maxRedirects < 0)
30616
31124
  throw new Error(`too many redirects for ${url}`);
30617
31125
  const mod2 = url.startsWith("https") ? await import("node:https") : await import("node:http");
30618
- return new Promise((resolve8, reject) => {
31126
+ return new Promise((resolve9, reject) => {
30619
31127
  const req = mod2.get(url, { headers: { Accept: "application/json" } }, (res) => {
30620
31128
  if (res.statusCode && res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
30621
- httpGet(res.headers.location, maxRedirects - 1).then(resolve8, reject);
31129
+ httpGet(res.headers.location, maxRedirects - 1).then(resolve9, reject);
30622
31130
  res.resume();
30623
31131
  return;
30624
31132
  }
30625
31133
  const chunks = [];
30626
31134
  res.on("data", (chunk) => chunks.push(chunk));
30627
31135
  res.on("end", () => {
30628
- resolve8({
31136
+ resolve9({
30629
31137
  statusCode: res.statusCode ?? 0,
30630
31138
  headers: res.headers,
30631
31139
  body: Buffer.concat(chunks)
@@ -30640,10 +31148,10 @@ async function httpDownload(url, destPath, maxRedirects = 10) {
30640
31148
  if (maxRedirects < 0)
30641
31149
  throw new Error(`too many redirects for ${url}`);
30642
31150
  const mod2 = url.startsWith("https") ? await import("node:https") : await import("node:http");
30643
- return new Promise((resolve8, reject) => {
31151
+ return new Promise((resolve9, reject) => {
30644
31152
  const req = mod2.get(url, (res) => {
30645
31153
  if (res.statusCode && res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
30646
- httpDownload(res.headers.location, destPath, maxRedirects - 1).then(resolve8, reject);
31154
+ httpDownload(res.headers.location, destPath, maxRedirects - 1).then(resolve9, reject);
30647
31155
  res.resume();
30648
31156
  return;
30649
31157
  }
@@ -30653,7 +31161,7 @@ async function httpDownload(url, destPath, maxRedirects = 10) {
30653
31161
  return;
30654
31162
  }
30655
31163
  const ws = fs5.createWriteStream(destPath);
30656
- pipeline(res, ws).then(resolve8, reject);
31164
+ pipeline(res, ws).then(resolve9, reject);
30657
31165
  });
30658
31166
  req.on("error", reject);
30659
31167
  });
@@ -30788,13 +31296,13 @@ function verifyChecksum(filePath, algo, expectedHex) {
30788
31296
  hash.update(content);
30789
31297
  const actual = hash.digest("hex");
30790
31298
  if (actual !== expectedHex) {
30791
- throw new Error(`checksum mismatch for ${path7.basename(filePath)}: expected ${algo}:${expectedHex}, got ${algo}:${actual}`);
31299
+ throw new Error(`checksum mismatch for ${path9.basename(filePath)}: expected ${algo}:${expectedHex}, got ${algo}:${actual}`);
30792
31300
  }
30793
31301
  }
30794
31302
  function validateTarEntries(tarballPath) {
30795
31303
  let listing;
30796
31304
  try {
30797
- listing = execFileSync2("tar", ["tzf", tarballPath], {
31305
+ listing = execFileSync3("tar", ["tzf", tarballPath], {
30798
31306
  encoding: "utf-8",
30799
31307
  maxBuffer: 16 * 1024 * 1024
30800
31308
  });
@@ -30805,11 +31313,11 @@ function validateTarEntries(tarballPath) {
30805
31313
  const trimmed = entry.trim();
30806
31314
  if (!trimmed)
30807
31315
  continue;
30808
- if (path7.isAbsolute(trimmed)) {
31316
+ if (path9.isAbsolute(trimmed)) {
30809
31317
  throw new Error(`tarball contains absolute path: "${trimmed}"`);
30810
31318
  }
30811
- const normalized = path7.normalize(trimmed);
30812
- if (normalized.startsWith("..") || normalized.includes(`${path7.sep}..${path7.sep}`)) {
31319
+ const normalized = path9.normalize(trimmed);
31320
+ if (normalized.startsWith("..") || normalized.includes(`${path9.sep}..${path9.sep}`)) {
30813
31321
  throw new Error(`tarball contains path traversal: "${trimmed}"`);
30814
31322
  }
30815
31323
  }
@@ -30818,7 +31326,7 @@ function extractTarball(tarballPath, destDir) {
30818
31326
  const stripComponents = detectStripComponents(tarballPath);
30819
31327
  fs5.mkdirSync(destDir, { recursive: true });
30820
31328
  try {
30821
- execFileSync2("tar", [
31329
+ execFileSync3("tar", [
30822
31330
  "xzf",
30823
31331
  tarballPath,
30824
31332
  "-C",
@@ -30834,7 +31342,7 @@ function extractTarball(tarballPath, destDir) {
30834
31342
  function detectStripComponents(tarballPath) {
30835
31343
  let listing;
30836
31344
  try {
30837
- listing = execFileSync2("tar", ["tzf", tarballPath], {
31345
+ listing = execFileSync3("tar", ["tzf", tarballPath], {
30838
31346
  encoding: "utf-8",
30839
31347
  maxBuffer: 16 * 1024 * 1024
30840
31348
  });
@@ -30857,7 +31365,7 @@ function detectStripComponents(tarballPath) {
30857
31365
  return commonPrefix ? 1 : 0;
30858
31366
  }
30859
31367
  function installDeps(clipDir) {
30860
- const pkgJsonPath = path7.join(clipDir, "package.json");
31368
+ const pkgJsonPath = path9.join(clipDir, "package.json");
30861
31369
  if (!fs5.existsSync(pkgJsonPath))
30862
31370
  return;
30863
31371
  let hasDeps = false;
@@ -30876,11 +31384,11 @@ function installDeps(clipDir) {
30876
31384
  if (bunPath) {
30877
31385
  const bunEnv = {
30878
31386
  ...process.env,
30879
- PATH: `${path7.dirname(bunPath)}${path7.delimiter}${process.env.PATH ?? ""}`
31387
+ PATH: `${path9.dirname(bunPath)}${path9.delimiter}${process.env.PATH ?? ""}`
30880
31388
  };
30881
31389
  for (const args of [["install", "--frozen-lockfile"], ["install"]]) {
30882
31390
  try {
30883
- execFileSync2(bunPath, args, {
31391
+ execFileSync3(bunPath, args, {
30884
31392
  cwd: clipDir,
30885
31393
  stdio: "pipe",
30886
31394
  timeout: 12e4,
@@ -30893,7 +31401,7 @@ function installDeps(clipDir) {
30893
31401
  }
30894
31402
  }
30895
31403
  try {
30896
- execFileSync2("npm", ["install", "--production"], {
31404
+ execFileSync3("npm", ["install", "--production"], {
30897
31405
  cwd: clipDir,
30898
31406
  stdio: "pipe",
30899
31407
  timeout: 12e4
@@ -30912,19 +31420,19 @@ async function installClip(opts) {
30912
31420
  const registryUrl = (opts.registryUrl ?? DEFAULT_REGISTRY_URL).replace(/\/+$/, "");
30913
31421
  const parsed = parseSource(opts.source);
30914
31422
  const alias = opts.alias ?? deriveAlias(parsed);
30915
- const destDir = path7.join(opts.clipsDir, alias);
31423
+ const destDir = path9.join(opts.clipsDir, alias);
30916
31424
  const versionMeta = await resolveVersionMeta(registryUrl, parsed);
30917
- const tmpDir = path7.join(opts.clipsDir, `.tmp-${alias}-${Date.now()}`);
31425
+ const tmpDir = path9.join(opts.clipsDir, `.tmp-${alias}-${Date.now()}`);
30918
31426
  fs5.mkdirSync(tmpDir, { recursive: true });
30919
- const tarballPath = path7.join(tmpDir, `${alias}-${versionMeta.version}.tgz`);
30920
- const stageDir = path7.join(tmpDir, "stage");
31427
+ const tarballPath = path9.join(tmpDir, `${alias}-${versionMeta.version}.tgz`);
31428
+ const stageDir = path9.join(tmpDir, "stage");
30921
31429
  try {
30922
31430
  await httpDownload(versionMeta.tarball, tarballPath);
30923
31431
  verifyChecksum(tarballPath, versionMeta.checksumAlgo, versionMeta.checksumHex);
30924
31432
  validateTarEntries(tarballPath);
30925
31433
  extractTarball(tarballPath, stageDir);
30926
31434
  installDeps(stageDir);
30927
- const backupDir = path7.join(opts.clipsDir, `.backup-${alias}-${Date.now()}`);
31435
+ const backupDir = path9.join(opts.clipsDir, `.backup-${alias}-${Date.now()}`);
30928
31436
  let backedUp = false;
30929
31437
  try {
30930
31438
  if (fs5.existsSync(destDir)) {
@@ -30965,9 +31473,9 @@ var init_clip_installer = __esm({
30965
31473
 
30966
31474
  // ts/daemon/dist/clip-runtime/manifest.js
30967
31475
  import * as fs6 from "node:fs";
30968
- import * as path8 from "node:path";
31476
+ import * as path10 from "node:path";
30969
31477
  function loadClipJson(dir) {
30970
- const filePath = path8.join(dir, "clip.json");
31478
+ const filePath = path10.join(dir, "clip.json");
30971
31479
  try {
30972
31480
  const content = fs6.readFileSync(filePath, "utf-8");
30973
31481
  return JSON.parse(content);
@@ -30976,7 +31484,7 @@ function loadClipJson(dir) {
30976
31484
  }
30977
31485
  }
30978
31486
  function loadPackageJson(dir) {
30979
- const filePath = path8.join(dir, "package.json");
31487
+ const filePath = path10.join(dir, "package.json");
30980
31488
  try {
30981
31489
  const content = fs6.readFileSync(filePath, "utf-8");
30982
31490
  return JSON.parse(content);
@@ -31091,19 +31599,19 @@ function manifestFromIpc(ipcManifest) {
31091
31599
  function resolveEntrypoint(clip) {
31092
31600
  const clipJson = loadClipJson(clip.path);
31093
31601
  if (clipJson?.main)
31094
- return path8.join(clip.path, clipJson.main);
31602
+ return path10.join(clip.path, clipJson.main);
31095
31603
  const pkgJson = loadPackageJson(clip.path);
31096
31604
  if (pkgJson?.main)
31097
- return path8.join(clip.path, pkgJson.main);
31605
+ return path10.join(clip.path, pkgJson.main);
31098
31606
  if (pkgJson?.bin) {
31099
31607
  const binPath = typeof pkgJson.bin === "string" ? pkgJson.bin : Object.values(pkgJson.bin)[0];
31100
31608
  if (binPath)
31101
- return path8.join(clip.path, binPath);
31609
+ return path10.join(clip.path, binPath);
31102
31610
  }
31103
- const defaultEntry = path8.join(clip.path, "index.ts");
31611
+ const defaultEntry = path10.join(clip.path, "index.ts");
31104
31612
  if (fs6.existsSync(defaultEntry))
31105
31613
  return defaultEntry;
31106
- return path8.join(clip.path, "index.js");
31614
+ return path10.join(clip.path, "index.js");
31107
31615
  }
31108
31616
  function finalizeManifest(manifest) {
31109
31617
  const m = { ...manifest };
@@ -31133,7 +31641,8 @@ var init_manifest = __esm({
31133
31641
  // ts/daemon/dist/runtimes.js
31134
31642
  import * as fs7 from "node:fs";
31135
31643
  import * as os4 from "node:os";
31136
- import * as path9 from "node:path";
31644
+ import * as path11 from "node:path";
31645
+ import { fileURLToPath } from "node:url";
31137
31646
  function buildStandardEnv(baseEnv, agentId, orgId, apiKey, dirs, pc) {
31138
31647
  const env = { ...baseEnv };
31139
31648
  clearAllProviderCreds(env);
@@ -31150,19 +31659,47 @@ function buildStandardEnv(baseEnv, agentId, orgId, apiKey, dirs, pc) {
31150
31659
  delete env.PRLL_DAEMON_MODE;
31151
31660
  return env;
31152
31661
  }
31153
- function getRuntimeAdapter(runtimeType) {
31662
+ function bundledSiblingBin(overlayName, entryPath) {
31663
+ const candidateDirs = [];
31664
+ const entry = entryPath ?? process.argv[1];
31665
+ if (entry) {
31666
+ try {
31667
+ candidateDirs.push(path11.dirname(fs7.realpathSync(entry)));
31668
+ } catch {
31669
+ candidateDirs.push(path11.dirname(path11.resolve(entry)));
31670
+ }
31671
+ }
31672
+ try {
31673
+ candidateDirs.push(path11.dirname(fileURLToPath(import.meta.url)));
31674
+ } catch {
31675
+ }
31676
+ for (const dir of candidateDirs) {
31677
+ const bin = path11.join(dir, overlayName);
31678
+ try {
31679
+ if (fs7.existsSync(bin))
31680
+ return bin;
31681
+ } catch {
31682
+ }
31683
+ }
31684
+ return null;
31685
+ }
31686
+ function getRuntimeAdapter(runtimeType, opts) {
31154
31687
  const base = RUNTIME_ADAPTERS[runtimeType] ?? defaultAdapter;
31155
31688
  const overlayName = OVERLAY_BIN_NAMES[runtimeType];
31156
31689
  if (!overlayName)
31157
31690
  return base;
31158
31691
  try {
31159
- const bundleDir = resolveBundleDir();
31160
- const overlayBin = path9.join(bundleDir, "current", overlayName);
31692
+ const bundleDir = resolveBundleDir(opts?.env);
31693
+ const overlayBin = path11.join(bundleDir, "current", overlayName);
31161
31694
  if (fs7.existsSync(overlayBin)) {
31162
31695
  return { ...base, bin: process.execPath, args: [overlayBin] };
31163
31696
  }
31164
31697
  } catch {
31165
31698
  }
31699
+ const siblingBin = bundledSiblingBin(overlayName, opts?.entryPath);
31700
+ if (siblingBin) {
31701
+ return { ...base, bin: process.execPath, args: [siblingBin] };
31702
+ }
31166
31703
  return base;
31167
31704
  }
31168
31705
  function assertAgentKey(apiKey) {
@@ -31191,9 +31728,9 @@ var init_runtimes = __esm({
31191
31728
  buildEnv(baseEnv, agentId, orgId, apiKey, dirs, pc) {
31192
31729
  const env = buildStandardEnv(baseEnv, agentId, orgId, apiKey, dirs, pc);
31193
31730
  if (baseEnv.KUBERNETES_SERVICE_HOST || llmSource(pc) !== "runtime_auth") {
31194
- env.PRLL_CODEX_HOME = path9.join(dirs.stateDir, ".codex");
31731
+ env.PRLL_CODEX_HOME = path11.join(dirs.stateDir, ".codex");
31195
31732
  } else if (dirs.homeDir && !env.CODEX_HOME) {
31196
- env.CODEX_HOME = path9.join(baseEnv.HOME || os4.homedir(), ".codex");
31733
+ env.CODEX_HOME = path11.join(baseEnv.HOME || os4.homedir(), ".codex");
31197
31734
  }
31198
31735
  return env;
31199
31736
  }
@@ -31295,7 +31832,7 @@ var init_ipc = __esm({
31295
31832
  return p;
31296
31833
  }
31297
31834
  doWrite(message) {
31298
- return new Promise((resolve8, reject) => {
31835
+ return new Promise((resolve9, reject) => {
31299
31836
  if (this._closed) {
31300
31837
  reject(IPC_CLOSED_ERROR);
31301
31838
  return;
@@ -31306,7 +31843,7 @@ var init_ipc = __esm({
31306
31843
  this._closed = true;
31307
31844
  reject(err);
31308
31845
  } else {
31309
- resolve8();
31846
+ resolve9();
31310
31847
  }
31311
31848
  });
31312
31849
  });
@@ -31380,13 +31917,13 @@ function sanitizeEnvForClip(extra) {
31380
31917
  return env;
31381
31918
  }
31382
31919
  function makeDeferred() {
31383
- let resolve8;
31920
+ let resolve9;
31384
31921
  let reject;
31385
31922
  const promise = new Promise((res, rej) => {
31386
- resolve8 = res;
31923
+ resolve9 = res;
31387
31924
  reject = rej;
31388
31925
  });
31389
- return { promise, resolve: resolve8, reject };
31926
+ return { promise, resolve: resolve9, reject };
31390
31927
  }
31391
31928
  var CLIP_REGISTER_TIMEOUT_MS, CLIP_STOP_TIMEOUT_MS, ClipCommandError, ClipProcess;
31392
31929
  var init_process = __esm({
@@ -31484,12 +32021,12 @@ var init_process = __esm({
31484
32021
  throw new Error(`clip "${this.clip.name}" is not running`);
31485
32022
  const requestId = String(this.nextId++);
31486
32023
  const events = [];
31487
- const resultPromise = new Promise((resolve8, reject) => {
32024
+ const resultPromise = new Promise((resolve9, reject) => {
31488
32025
  this.pending.set(requestId, (event) => {
31489
32026
  switch (event.type) {
31490
32027
  case MessageType.Result: {
31491
32028
  this.pending.delete(requestId);
31492
- resolve8({ output: event.output });
32029
+ resolve9({ output: event.output });
31493
32030
  break;
31494
32031
  }
31495
32032
  case MessageType.Error: {
@@ -31514,7 +32051,7 @@ var init_process = __esm({
31514
32051
  if (output === void 0 && events.length > 0) {
31515
32052
  output = events.map((e) => e.output);
31516
32053
  }
31517
- resolve8({ output });
32054
+ resolve9({ output });
31518
32055
  break;
31519
32056
  }
31520
32057
  }
@@ -31540,12 +32077,12 @@ var init_process = __esm({
31540
32077
  this.stopping = true;
31541
32078
  this.child.kill("SIGTERM");
31542
32079
  let timer;
31543
- const timeout = new Promise((resolve8) => {
32080
+ const timeout = new Promise((resolve9) => {
31544
32081
  timer = setTimeout(() => {
31545
32082
  if (this.child && this.alive()) {
31546
32083
  this.child.kill("SIGKILL");
31547
32084
  }
31548
- resolve8();
32085
+ resolve9();
31549
32086
  }, timeoutMs);
31550
32087
  });
31551
32088
  try {
@@ -31896,7 +32433,7 @@ var init_hub_client = __esm({
31896
32433
  unary(method, request3) {
31897
32434
  const timeoutMs = this.opts.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
31898
32435
  const url = new URL(this.opts.serviceUrl);
31899
- return new Promise((resolve8, reject) => {
32436
+ return new Promise((resolve9, reject) => {
31900
32437
  let settled = false;
31901
32438
  const session = http22.connect(url.origin);
31902
32439
  const chunks = [];
@@ -31942,7 +32479,7 @@ var init_hub_client = __esm({
31942
32479
  return;
31943
32480
  }
31944
32481
  try {
31945
- resolve8(text ? JSON.parse(text) : {});
32482
+ resolve9(text ? JSON.parse(text) : {});
31946
32483
  } catch (err) {
31947
32484
  reject(new Error(`hub ${method} bad response: ${String(err)}`));
31948
32485
  }
@@ -31957,7 +32494,7 @@ var init_hub_client = __esm({
31957
32494
  serverStream(method, request3) {
31958
32495
  const timeoutMs = this.opts.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
31959
32496
  const url = new URL(this.opts.serviceUrl);
31960
- return new Promise((resolve8, reject) => {
32497
+ return new Promise((resolve9, reject) => {
31961
32498
  let settled = false;
31962
32499
  const session = http22.connect(url.origin);
31963
32500
  const decoder = new EnvelopeDecoder();
@@ -31983,7 +32520,7 @@ var init_hub_client = __esm({
31983
32520
  return;
31984
32521
  settled = true;
31985
32522
  cleanup();
31986
- resolve8(messages);
32523
+ resolve9(messages);
31987
32524
  };
31988
32525
  const timer = setTimeout(() => fail(new Error(`hub ${method} timed out`)), timeoutMs);
31989
32526
  timer.unref?.();
@@ -32039,7 +32576,7 @@ var init_hub_client = __esm({
32039
32576
 
32040
32577
  // ts/daemon/dist/clip-runtime/process-manager.js
32041
32578
  import * as fs8 from "node:fs";
32042
- import * as path10 from "node:path";
32579
+ import * as path12 from "node:path";
32043
32580
  function browserCapabilityConfig() {
32044
32581
  return {
32045
32582
  name: BROWSER_CAPABILITY_NAME,
@@ -32298,7 +32835,7 @@ var init_process_manager = __esm({
32298
32835
  * Reads clip-config.json if present, or scans subdirectories for clip.json files.
32299
32836
  */
32300
32837
  async loadInstalledClips() {
32301
- const configFile = path10.join(path10.dirname(this.clipsDir), "clip-config.json");
32838
+ const configFile = path12.join(path12.dirname(this.clipsDir), "clip-config.json");
32302
32839
  if (fs8.existsSync(configFile)) {
32303
32840
  try {
32304
32841
  const content = fs8.readFileSync(configFile, "utf-8");
@@ -32317,9 +32854,9 @@ var init_process_manager = __esm({
32317
32854
  for (const entry of entries) {
32318
32855
  if (!entry.isDirectory())
32319
32856
  continue;
32320
- const clipDir = path10.join(this.clipsDir, entry.name);
32321
- const clipJsonPath = path10.join(clipDir, "clip.json");
32322
- const pkgJsonPath = path10.join(clipDir, "package.json");
32857
+ const clipDir = path12.join(this.clipsDir, entry.name);
32858
+ const clipJsonPath = path12.join(clipDir, "clip.json");
32859
+ const pkgJsonPath = path12.join(clipDir, "package.json");
32323
32860
  if (fs8.existsSync(clipJsonPath)) {
32324
32861
  try {
32325
32862
  const clipJson = JSON.parse(fs8.readFileSync(clipJsonPath, "utf-8"));
@@ -32389,7 +32926,7 @@ var init_process_manager = __esm({
32389
32926
  // shells out to `bun` by name resolves it — the daemon's launchd PATH
32390
32927
  // does not include Frameworks/. Symmetric with installDeps(); relies on
32391
32928
  // the embedded binary being named `bun` (Frameworks/bun).
32392
- PATH: `${path10.dirname(bunPath)}${path10.delimiter}${process.env.PATH ?? ""}`
32929
+ PATH: `${path12.dirname(bunPath)}${path12.delimiter}${process.env.PATH ?? ""}`
32393
32930
  });
32394
32931
  this.setStatus(config.name, "running", "starting");
32395
32932
  try {
@@ -32418,7 +32955,7 @@ var init_process_manager = __esm({
32418
32955
  return proc;
32419
32956
  }
32420
32957
  ensureClipDataDir(config, context2 = {}) {
32421
- const dir = path10.join(this.dataDir, config.name, context2.clipId ?? "default");
32958
+ const dir = path12.join(this.dataDir, config.name, context2.clipId ?? "default");
32422
32959
  fs8.mkdirSync(dir, { recursive: true });
32423
32960
  return dir;
32424
32961
  }
@@ -32941,12 +33478,12 @@ var init_clip_provider = __esm({
32941
33478
  throw new Error("stream not open");
32942
33479
  }
32943
33480
  const envelope = encodeEnvelope2(msg);
32944
- return new Promise((resolve8, reject) => {
33481
+ return new Promise((resolve9, reject) => {
32945
33482
  this.stream.write(envelope, (err) => {
32946
33483
  if (err)
32947
33484
  reject(err);
32948
33485
  else
32949
- resolve8();
33486
+ resolve9();
32950
33487
  });
32951
33488
  });
32952
33489
  }
@@ -33060,7 +33597,7 @@ function formatErrorForLog(err) {
33060
33597
  return message.replace(/\s+/g, " ").slice(0, 300);
33061
33598
  }
33062
33599
  async function findFreePort() {
33063
- return new Promise((resolve8, reject) => {
33600
+ return new Promise((resolve9, reject) => {
33064
33601
  const server = net.createServer();
33065
33602
  server.unref();
33066
33603
  server.on("error", reject);
@@ -33068,7 +33605,7 @@ async function findFreePort() {
33068
33605
  const address = server.address();
33069
33606
  server.close(() => {
33070
33607
  if (address && typeof address === "object") {
33071
- resolve8(address.port);
33608
+ resolve9(address.port);
33072
33609
  } else {
33073
33610
  reject(new Error("failed to allocate free port"));
33074
33611
  }
@@ -33077,12 +33614,12 @@ async function findFreePort() {
33077
33614
  });
33078
33615
  }
33079
33616
  function sleep(ms) {
33080
- return new Promise((resolve8) => setTimeout(resolve8, ms));
33617
+ return new Promise((resolve9) => setTimeout(resolve9, ms));
33081
33618
  }
33082
33619
  function waitForChildExit(child, log2, graceMs = 5e3, hardCapMs = 15e3) {
33083
33620
  if (child.exitCode !== null || child.signalCode !== null)
33084
33621
  return Promise.resolve();
33085
- return new Promise((resolve8) => {
33622
+ return new Promise((resolve9) => {
33086
33623
  let killTimer;
33087
33624
  let capTimer;
33088
33625
  const finish = () => {
@@ -33091,7 +33628,7 @@ function waitForChildExit(child, log2, graceMs = 5e3, hardCapMs = 15e3) {
33091
33628
  clearTimeout(killTimer);
33092
33629
  if (capTimer)
33093
33630
  clearTimeout(capTimer);
33094
- resolve8();
33631
+ resolve9();
33095
33632
  };
33096
33633
  child.once("exit", finish);
33097
33634
  try {
@@ -33708,8 +34245,8 @@ import { spawn as spawn4 } from "node:child_process";
33708
34245
  import { randomBytes } from "node:crypto";
33709
34246
  import { existsSync as existsSync8, mkdirSync as mkdirSync5, readFileSync as readFileSync7 } from "node:fs";
33710
34247
  import { createRequire } from "node:module";
33711
- import * as path11 from "node:path";
33712
- import { fileURLToPath } from "node:url";
34248
+ import * as path13 from "node:path";
34249
+ import { fileURLToPath as fileURLToPath2 } from "node:url";
33713
34250
  function hostsMatch(a, b) {
33714
34251
  const norm = (h) => h.toLowerCase().replace(/^www\./, "");
33715
34252
  return norm(a) === norm(b);
@@ -33766,14 +34303,14 @@ function comparableUrl(url) {
33766
34303
  }
33767
34304
  }
33768
34305
  function resolveBbBrowserDaemonPath() {
33769
- const sibling = path11.join(path11.dirname(fileURLToPath(import.meta.url)), "bb-browser-daemon.js");
34306
+ const sibling = path13.join(path13.dirname(fileURLToPath2(import.meta.url)), "bb-browser-daemon.js");
33770
34307
  if (existsSync8(sibling))
33771
34308
  return sibling;
33772
34309
  const require2 = createRequire(import.meta.url);
33773
34310
  const pkgPath = require2.resolve("@pinixai/bb-browser-pro/package.json");
33774
34311
  const pkg = JSON.parse(readFileSync7(pkgPath, "utf8"));
33775
34312
  const rel = typeof pkg.bin === "string" ? pkg.bin : pkg.bin?.["bb-browser-daemon"] ?? "./dist/daemon.js";
33776
- const full = path11.resolve(path11.dirname(pkgPath), rel);
34313
+ const full = path13.resolve(path13.dirname(pkgPath), rel);
33777
34314
  if (!existsSync8(full)) {
33778
34315
  throw new Error(`bb-browser-daemon entrypoint not found at ${full}`);
33779
34316
  }
@@ -34336,7 +34873,7 @@ var init_browser_profile_manager = __esm({
34336
34873
 
34337
34874
  // ts/daemon/dist/clip-runtime/browser-profile-pool.js
34338
34875
  import { existsSync as existsSync9, mkdirSync as mkdirSync6, readdirSync as readdirSync3, readFileSync as readFileSync8, renameSync as renameSync3, rmSync as rmSync3, writeFileSync as writeFileSync3 } from "node:fs";
34339
- import * as path12 from "node:path";
34876
+ import * as path14 from "node:path";
34340
34877
  function isSafeProfileId(id) {
34341
34878
  return /^brp_[A-Za-z0-9_-]+$/.test(id);
34342
34879
  }
@@ -34696,11 +35233,11 @@ var init_browser_profile_pool = __esm({
34696
35233
  }
34697
35234
  }
34698
35235
  profileHome(profileId) {
34699
- return path12.join(this.opts.baseHomeDir, sanitizeProfileId(profileId));
35236
+ return path14.join(this.opts.baseHomeDir, sanitizeProfileId(profileId));
34700
35237
  }
34701
35238
  /** Legacy shared-layout cookie file for a profile (pre per-profile homes). */
34702
35239
  legacyAccountFile(profileId) {
34703
- return path12.join(this.opts.baseHomeDir, "accounts", `${sanitizeProfileId(profileId)}.json`);
35240
+ return path14.join(this.opts.baseHomeDir, "accounts", `${sanitizeProfileId(profileId)}.json`);
34704
35241
  }
34705
35242
  /**
34706
35243
  * Remove every on-disk trace of a profile: its per-profile home AND any
@@ -34728,7 +35265,7 @@ var init_browser_profile_pool = __esm({
34728
35265
  // reset_generation to this value: a newer server value means a reset was missed
34729
35266
  // while offline → wipe. Missing/corrupt reads as 0 (so any server reset wins).
34730
35267
  metaFile(profileId) {
34731
- return path12.join(this.profileHome(profileId), ".parall-profile-meta.json");
35268
+ return path14.join(this.profileHome(profileId), ".parall-profile-meta.json");
34732
35269
  }
34733
35270
  /** The reset_generation this daemon has applied for the profile (0 if unknown). */
34734
35271
  appliedResetGeneration(profileId) {
@@ -34746,7 +35283,7 @@ var init_browser_profile_pool = __esm({
34746
35283
  writeResetGeneration(profileId, generation) {
34747
35284
  const home = this.profileHome(profileId);
34748
35285
  mkdirSync6(home, { recursive: true });
34749
- const tmp = path12.join(home, `.parall-profile-meta.json.tmp-${process.pid}`);
35286
+ const tmp = path14.join(home, `.parall-profile-meta.json.tmp-${process.pid}`);
34750
35287
  writeFileSync3(tmp, JSON.stringify({ reset_generation: generation }));
34751
35288
  renameSync3(tmp, this.metaFile(profileId));
34752
35289
  }
@@ -34772,7 +35309,7 @@ var init_browser_profile_pool = __esm({
34772
35309
  } catch {
34773
35310
  }
34774
35311
  try {
34775
- const accountsDir = path12.join(this.opts.baseHomeDir, "accounts");
35312
+ const accountsDir = path14.join(this.opts.baseHomeDir, "accounts");
34776
35313
  for (const e of readdirSync3(accountsDir, { withFileTypes: true })) {
34777
35314
  if (!e.isFile() || !e.name.endsWith(".json"))
34778
35315
  continue;
@@ -34798,8 +35335,8 @@ var init_browser_profile_pool = __esm({
34798
35335
  const legacy = this.legacyAccountFile(profileId);
34799
35336
  if (!existsSync9(legacy))
34800
35337
  return;
34801
- const destDir = path12.join(this.profileHome(profileId), "accounts");
34802
- const dest = path12.join(destDir, path12.basename(legacy));
35338
+ const destDir = path14.join(this.profileHome(profileId), "accounts");
35339
+ const dest = path14.join(destDir, path14.basename(legacy));
34803
35340
  if (existsSync9(dest))
34804
35341
  return;
34805
35342
  try {
@@ -34831,10 +35368,10 @@ var init_clip_runtime = __esm({
34831
35368
 
34832
35369
  // ts/daemon/dist/filesystem.js
34833
35370
  import * as fs9 from "fs";
34834
- import * as path13 from "path";
35371
+ import * as path15 from "path";
34835
35372
  import * as os5 from "os";
34836
35373
  function browseDenyReason(value) {
34837
- const normalized = path13.resolve(value).split(path13.sep).join("/");
35374
+ const normalized = path15.resolve(value).split(path15.sep).join("/");
34838
35375
  if (normalized === "/")
34839
35376
  return "";
34840
35377
  for (const prefix of SYSTEM_DIR_PREFIXES) {
@@ -34864,8 +35401,8 @@ function syntheticRoots() {
34864
35401
  return roots;
34865
35402
  }
34866
35403
  async function listDirectory(dirPath) {
34867
- const resolved = path13.resolve(dirPath);
34868
- const normalized = resolved.split(path13.sep).join("/");
35404
+ const resolved = path15.resolve(dirPath);
35405
+ const normalized = resolved.split(path15.sep).join("/");
34869
35406
  if (normalized === "/") {
34870
35407
  return { entries: syntheticRoots() };
34871
35408
  }
@@ -34882,7 +35419,7 @@ async function listDirectory(dirPath) {
34882
35419
  return { entries: [], error: "Directory not found" };
34883
35420
  return { entries: [], error: "Permission denied" };
34884
35421
  }
34885
- const realDeny = browseDenyReason(realPath.split(path13.sep).join("/"));
35422
+ const realDeny = browseDenyReason(realPath.split(path15.sep).join("/"));
34886
35423
  if (realDeny) {
34887
35424
  return { entries: [], error: `Access denied: ${realDeny}` };
34888
35425
  }
@@ -34951,7 +35488,7 @@ var init_filesystem = __esm({
34951
35488
 
34952
35489
  // ts/daemon/dist/home-isolation.js
34953
35490
  import * as fs10 from "node:fs";
34954
- import * as path14 from "node:path";
35491
+ import * as path16 from "node:path";
34955
35492
  function ensureIsolatedHome(spec, agentId, log2, platform2 = process.platform) {
34956
35493
  fs10.mkdirSync(spec.homeDir, { recursive: true });
34957
35494
  const failures = [];
@@ -34963,18 +35500,18 @@ function ensureIsolatedHome(spec, agentId, log2, platform2 = process.platform) {
34963
35500
  }
34964
35501
  };
34965
35502
  attempt(".claude link", () => {
34966
- fs10.mkdirSync(path14.join(spec.claudeStateRoot, ".claude"), { recursive: true });
34967
- ensureLink(path14.join(spec.homeDir, ".claude"), path14.join(spec.claudeStateRoot, ".claude"), agentId, log2);
35503
+ fs10.mkdirSync(path16.join(spec.claudeStateRoot, ".claude"), { recursive: true });
35504
+ ensureLink(path16.join(spec.homeDir, ".claude"), path16.join(spec.claudeStateRoot, ".claude"), agentId, log2);
34968
35505
  });
34969
- attempt(".claude.json link", () => ensureLink(path14.join(spec.homeDir, ".claude.json"), path14.join(spec.claudeStateRoot, ".claude.json"), agentId, log2));
35506
+ attempt(".claude.json link", () => ensureLink(path16.join(spec.homeDir, ".claude.json"), path16.join(spec.claudeStateRoot, ".claude.json"), agentId, log2));
34970
35507
  if (platform2 === "darwin") {
34971
35508
  attempt("Library/Keychains link", () => {
34972
- fs10.mkdirSync(path14.join(spec.homeDir, "Library"), { recursive: true });
34973
- ensureLink(path14.join(spec.homeDir, "Library", "Keychains"), path14.join(spec.systemHome, "Library", "Keychains"), agentId, log2);
35509
+ fs10.mkdirSync(path16.join(spec.homeDir, "Library"), { recursive: true });
35510
+ ensureLink(path16.join(spec.homeDir, "Library", "Keychains"), path16.join(spec.systemHome, "Library", "Keychains"), agentId, log2);
34974
35511
  });
34975
35512
  }
34976
35513
  attempt(".gitconfig", () => {
34977
- const gitconfig = path14.join(spec.homeDir, ".gitconfig");
35514
+ const gitconfig = path16.join(spec.homeDir, ".gitconfig");
34978
35515
  if (!fs10.existsSync(gitconfig)) {
34979
35516
  fs10.writeFileSync(gitconfig, `[user]
34980
35517
  name = ${gitConfigValue(spec.gitUserName)}
@@ -35000,7 +35537,7 @@ function ensureLink(linkPath, target, agentId, log2) {
35000
35537
  if (existing) {
35001
35538
  if (existing.isSymbolicLink()) {
35002
35539
  const current = fs10.readlinkSync(linkPath);
35003
- if (path14.resolve(path14.dirname(linkPath), current) === path14.resolve(target))
35540
+ if (path16.resolve(path16.dirname(linkPath), current) === path16.resolve(target))
35004
35541
  return;
35005
35542
  fs10.unlinkSync(linkPath);
35006
35543
  log2.info(`agent ${agentId}: relinking ${linkPath} \u2192 ${target}`);
@@ -35013,16 +35550,16 @@ function ensureLink(linkPath, target, agentId, log2) {
35013
35550
  fs10.symlinkSync(target, linkPath);
35014
35551
  }
35015
35552
  function ensureSharedCredentialLink(rootClaudeHome, agentClaudeHome, agentId, log2) {
35016
- const sharedCredentials = path14.resolve(sharedClaudeCredentialsFileFor(rootClaudeHome));
35553
+ const sharedCredentials = path16.resolve(sharedClaudeCredentialsFileFor(rootClaudeHome));
35017
35554
  const agentCredentials = agentClaudeCredentialsFileFor(agentClaudeHome);
35018
- const agentCredentialsDir = path14.dirname(agentCredentials);
35019
- fs10.mkdirSync(path14.dirname(sharedCredentials), { recursive: true });
35555
+ const agentCredentialsDir = path16.dirname(agentCredentials);
35556
+ fs10.mkdirSync(path16.dirname(sharedCredentials), { recursive: true });
35020
35557
  fs10.mkdirSync(agentCredentialsDir, { recursive: true });
35021
35558
  try {
35022
35559
  const existing = fs10.lstatSync(agentCredentials);
35023
35560
  if (existing.isSymbolicLink()) {
35024
35561
  const currentTarget = fs10.readlinkSync(agentCredentials);
35025
- if (path14.resolve(agentCredentialsDir, currentTarget) === sharedCredentials) {
35562
+ if (path16.resolve(agentCredentialsDir, currentTarget) === sharedCredentials) {
35026
35563
  return;
35027
35564
  }
35028
35565
  fs10.unlinkSync(agentCredentials);
@@ -35047,17 +35584,17 @@ var init_home_isolation = __esm({
35047
35584
  });
35048
35585
 
35049
35586
  // ts/daemon/dist/runtime-bin-resolver.js
35050
- import { execFileSync as execFileSync3 } from "node:child_process";
35587
+ import { execFileSync as execFileSync4 } from "node:child_process";
35051
35588
  import * as fs11 from "node:fs";
35052
35589
  import * as os6 from "node:os";
35053
- import * as path15 from "node:path";
35590
+ import * as path17 from "node:path";
35054
35591
  function runtimeBinaryEnvVar(runtimeType) {
35055
35592
  return RUNTIME_BINARIES[runtimeType]?.envVar;
35056
35593
  }
35057
- function applyRuntimeBinaryEnv(runtimeType, baseEnv, log2) {
35594
+ function applyRuntimeBinaryEnv(runtimeType, baseEnv, log2, platform2 = process.platform) {
35058
35595
  const env = { ...baseEnv };
35059
35596
  const originalPath = env.PATH;
35060
- const pathPlan = cachedCandidatePathPlan(env);
35597
+ const pathPlan = cachedCandidatePathPlan(env, platform2);
35061
35598
  const primaryPath = mergePath(pathPlan.primaryDirs, originalPath);
35062
35599
  env.PATH = mergePath([...pathPlan.primaryDirs, ...pathPlan.versionedFallbackDirs], originalPath);
35063
35600
  const spec = RUNTIME_BINARIES[runtimeType];
@@ -35065,7 +35602,7 @@ function applyRuntimeBinaryEnv(runtimeType, baseEnv, log2) {
35065
35602
  return env;
35066
35603
  const configured = env[spec.envVar]?.trim();
35067
35604
  if (configured) {
35068
- const resolved2 = resolveRuntimeCommand(configured, env, originalPath, primaryPath, env.PATH);
35605
+ const resolved2 = resolveRuntimeCommand(configured, env, originalPath, primaryPath, env.PATH, platform2);
35069
35606
  if (resolved2) {
35070
35607
  env[spec.envVar] = resolved2.binaryPath;
35071
35608
  env.PATH = anchorResolvedPath(env.PATH, resolved2);
@@ -35075,7 +35612,7 @@ function applyRuntimeBinaryEnv(runtimeType, baseEnv, log2) {
35075
35612
  }
35076
35613
  return env;
35077
35614
  }
35078
- const resolved = resolveRuntimeCommand(spec.command, env, originalPath, primaryPath, env.PATH);
35615
+ const resolved = resolveRuntimeCommand(spec.command, env, originalPath, primaryPath, env.PATH, platform2);
35079
35616
  if (resolved) {
35080
35617
  env[spec.envVar] = resolved.binaryPath;
35081
35618
  env.PATH = anchorResolvedPath(env.PATH, resolved);
@@ -35085,8 +35622,8 @@ function applyRuntimeBinaryEnv(runtimeType, baseEnv, log2) {
35085
35622
  }
35086
35623
  return env;
35087
35624
  }
35088
- function resolveRuntimeCommand(command, env, inheritedPath, primaryPath, fallbackPath) {
35089
- const cacheKey = `runtime\0${command}\0${primaryPath}\0${fallbackPath}\0${env.SHELL ?? ""}\0${env.HOME ?? ""}`;
35625
+ function resolveRuntimeCommand(command, env, inheritedPath, primaryPath, fallbackPath, platform2) {
35626
+ const cacheKey = `runtime\0${command}\0${primaryPath}\0${fallbackPath}\0${env.SHELL ?? ""}\0${env.HOME ?? ""}\0${platform2}`;
35090
35627
  const cached = getCachedResolution(cacheKey);
35091
35628
  if (cached)
35092
35629
  return cached;
@@ -35097,24 +35634,24 @@ function resolveRuntimeCommand(command, env, inheritedPath, primaryPath, fallbac
35097
35634
  setCachedResolution(cacheKey, resolved);
35098
35635
  return resolved;
35099
35636
  }
35100
- const fromInheritedPath = resolveFromPath(command, inheritedPath, env);
35637
+ const fromInheritedPath = resolveFromPath(command, inheritedPath, env, platform2);
35101
35638
  if (fromInheritedPath) {
35102
35639
  setCachedResolution(cacheKey, fromInheritedPath);
35103
35640
  return fromInheritedPath;
35104
35641
  }
35105
35642
  if (runLoginShell) {
35106
- const fromShell = resolveFromLoginShell(command, { ...env, PATH: inheritedPath });
35643
+ const fromShell = resolveFromLoginShell(command, { ...env, PATH: inheritedPath }, platform2);
35107
35644
  if (fromShell) {
35108
35645
  setCachedResolution(cacheKey, fromShell);
35109
35646
  return fromShell;
35110
35647
  }
35111
35648
  }
35112
- const fromPrimaryPath = resolveFromPath(command, primaryPath, env);
35649
+ const fromPrimaryPath = resolveFromPath(command, primaryPath, env, platform2);
35113
35650
  if (fromPrimaryPath) {
35114
35651
  setCachedResolution(cacheKey, fromPrimaryPath);
35115
35652
  return fromPrimaryPath;
35116
35653
  }
35117
- const fromFallbackPath = fallbackPath === primaryPath ? null : resolveFromPath(command, fallbackPath, env);
35654
+ const fromFallbackPath = fallbackPath === primaryPath ? null : resolveFromPath(command, fallbackPath, env, platform2);
35118
35655
  if (fromFallbackPath) {
35119
35656
  setCachedResolution(cacheKey, fromFallbackPath);
35120
35657
  return fromFallbackPath;
@@ -35127,28 +35664,30 @@ function resolveRuntimeCommand(command, env, inheritedPath, primaryPath, fallbac
35127
35664
  function resolveDirectPath(command) {
35128
35665
  if (!command.includes("/") && !command.includes("\\"))
35129
35666
  return null;
35130
- const abs = path15.isAbsolute(command) ? command : path15.resolve(process.cwd(), command);
35667
+ const abs = path17.isAbsolute(command) ? command : path17.resolve(process.cwd(), command);
35131
35668
  return isExecutable(abs) ? abs : null;
35132
35669
  }
35133
- function resolveFromPath(command, pathValue, env) {
35670
+ function resolveFromPath(command, pathValue, env, platform2) {
35134
35671
  if (!pathValue || command.includes("/") || command.includes("\\"))
35135
35672
  return null;
35136
- const dirs = pathValue.split(path15.delimiter).filter(Boolean);
35673
+ const dirs = pathValue.split(path17.delimiter).filter(Boolean);
35137
35674
  for (const dir of dirs) {
35138
- for (const file of commandCandidates(command, env)) {
35139
- const candidate = path15.join(dir, file);
35675
+ for (const file of commandCandidates(command, env, platform2)) {
35676
+ const candidate = path17.join(dir, file);
35140
35677
  if (isExecutable(candidate))
35141
35678
  return { binaryPath: candidate, pathValue };
35142
35679
  }
35143
35680
  }
35144
35681
  return null;
35145
35682
  }
35146
- function resolveFromLoginShell(command, env) {
35683
+ function resolveFromLoginShell(command, env, platform2) {
35684
+ if (platform2 === "win32")
35685
+ return null;
35147
35686
  if (command.includes("/") || command.includes("\\"))
35148
35687
  return null;
35149
35688
  const shells = unique([
35150
35689
  env.SHELL?.trim(),
35151
- process.platform === "darwin" ? "/bin/zsh" : void 0,
35690
+ platform2 === "darwin" ? "/bin/zsh" : void 0,
35152
35691
  "/bin/bash",
35153
35692
  "/bin/sh"
35154
35693
  ]);
@@ -35156,7 +35695,7 @@ function resolveFromLoginShell(command, env) {
35156
35695
  if (!shell || !isExecutable(shell))
35157
35696
  continue;
35158
35697
  try {
35159
- const out = execFileSync3(shell, [
35698
+ const out = execFileSync4(shell, [
35160
35699
  "-lic",
35161
35700
  `resolved=$(command -v ${shellQuote(command)}) || exit $?; printf '__PRLL_BIN__%s
35162
35701
  __PRLL_PATH__%s
@@ -35175,7 +35714,7 @@ __PRLL_PATH__%s
35175
35714
  if (line.startsWith("__PRLL_PATH__"))
35176
35715
  pathValue = line.slice("__PRLL_PATH__".length);
35177
35716
  }
35178
- if (path15.isAbsolute(binaryPath) && isExecutable(binaryPath)) {
35717
+ if (path17.isAbsolute(binaryPath) && isExecutable(binaryPath)) {
35179
35718
  return { binaryPath, pathValue: pathValue || void 0 };
35180
35719
  }
35181
35720
  } catch {
@@ -35183,35 +35722,54 @@ __PRLL_PATH__%s
35183
35722
  }
35184
35723
  return null;
35185
35724
  }
35186
- function cachedCandidatePathPlan(env) {
35187
- const key = `${env.HOME ?? ""}\0${env.PRLL_DAEMON_RUNTIME_PATH ?? ""}\0${env.PRLL_DAEMON_EXTRA_PATH ?? ""}`;
35725
+ function cachedCandidatePathPlan(env, platform2) {
35726
+ const key = `${env.HOME ?? ""}\0${env.PRLL_DAEMON_RUNTIME_PATH ?? ""}\0${env.PRLL_DAEMON_EXTRA_PATH ?? ""}\0${env.APPDATA ?? ""}\0${env.LOCALAPPDATA ?? ""}\0${env.PNPM_HOME ?? ""}\0${platform2}`;
35188
35727
  const hit = pathPlanCache.get(key);
35189
35728
  if (hit && hit.expiresAt > Date.now())
35190
35729
  return hit.value;
35191
- const value = candidatePathPlan(env);
35730
+ const value = candidatePathPlan(env, platform2);
35192
35731
  pathPlanCache.set(key, { value, expiresAt: Date.now() + RESOLUTION_CACHE_TTL_MS });
35193
35732
  return value;
35194
35733
  }
35195
- function candidatePathPlan(env) {
35734
+ function candidatePathPlan(env, platform2 = process.platform) {
35196
35735
  const home = env.HOME || os6.homedir();
35736
+ if (platform2 === "win32") {
35737
+ const appData = env.APPDATA || path17.join(home, "AppData", "Roaming");
35738
+ const localAppData = env.LOCALAPPDATA || path17.join(home, "AppData", "Local");
35739
+ const winPrimaryDirs = [
35740
+ ...splitPath(env.PRLL_DAEMON_RUNTIME_PATH),
35741
+ ...splitPath(env.PRLL_DAEMON_EXTRA_PATH),
35742
+ path17.dirname(process.execPath),
35743
+ env.PNPM_HOME,
35744
+ path17.join(appData, "npm"),
35745
+ path17.join(localAppData, "pnpm"),
35746
+ path17.join(localAppData, "Volta", "bin"),
35747
+ path17.join(home, ".volta", "bin"),
35748
+ path17.join(home, ".bun", "bin")
35749
+ ];
35750
+ return {
35751
+ primaryDirs: unique(winPrimaryDirs).filter((dir) => !!dir && isDirectory(dir)),
35752
+ versionedFallbackDirs: []
35753
+ };
35754
+ }
35197
35755
  const primaryDirs = [
35198
35756
  ...splitPath(env.PRLL_DAEMON_RUNTIME_PATH),
35199
35757
  ...splitPath(env.PRLL_DAEMON_EXTRA_PATH),
35200
- path15.dirname(process.execPath),
35201
- path15.join(path15.dirname(process.execPath), "bin"),
35202
- path15.resolve(path15.dirname(process.execPath), "..", "Resources", "bin"),
35203
- path15.join(home, ".local", "bin"),
35204
- path15.join(home, "bin"),
35205
- path15.join(home, ".npm-global", "bin"),
35206
- path15.join(home, "Library", "pnpm"),
35207
- path15.join(home, ".local", "share", "pnpm"),
35208
- path15.join(home, ".volta", "bin"),
35209
- path15.join(home, ".bun", "bin"),
35210
- path15.join(home, ".asdf", "shims"),
35211
- path15.join(home, ".local", "share", "mise", "shims"),
35212
- path15.join(home, ".mise", "shims"),
35213
- path15.join(home, ".fnm", "aliases", "default", "bin"),
35214
- path15.join(home, "Library", "Application Support", "fnm", "aliases", "default", "bin"),
35758
+ path17.dirname(process.execPath),
35759
+ path17.join(path17.dirname(process.execPath), "bin"),
35760
+ path17.resolve(path17.dirname(process.execPath), "..", "Resources", "bin"),
35761
+ path17.join(home, ".local", "bin"),
35762
+ path17.join(home, "bin"),
35763
+ path17.join(home, ".npm-global", "bin"),
35764
+ path17.join(home, "Library", "pnpm"),
35765
+ path17.join(home, ".local", "share", "pnpm"),
35766
+ path17.join(home, ".volta", "bin"),
35767
+ path17.join(home, ".bun", "bin"),
35768
+ path17.join(home, ".asdf", "shims"),
35769
+ path17.join(home, ".local", "share", "mise", "shims"),
35770
+ path17.join(home, ".mise", "shims"),
35771
+ path17.join(home, ".fnm", "aliases", "default", "bin"),
35772
+ path17.join(home, "Library", "Application Support", "fnm", "aliases", "default", "bin"),
35215
35773
  "/opt/homebrew/bin",
35216
35774
  "/usr/local/bin",
35217
35775
  "/usr/bin",
@@ -35230,19 +35788,19 @@ function candidatePathPlan(env) {
35230
35788
  };
35231
35789
  }
35232
35790
  function nvmVersionBinDirs(home) {
35233
- const root = path15.join(home, ".nvm", "versions", "node");
35791
+ const root = path17.join(home, ".nvm", "versions", "node");
35234
35792
  let versions;
35235
35793
  try {
35236
35794
  versions = fs11.readdirSync(root);
35237
35795
  } catch {
35238
35796
  return [];
35239
35797
  }
35240
- return sortVersionNamesDesc(versions).map((version) => path15.join(root, version, "bin"));
35798
+ return sortVersionNamesDesc(versions).map((version) => path17.join(root, version, "bin"));
35241
35799
  }
35242
35800
  function fnmVersionBinDirs(home) {
35243
35801
  const roots = [
35244
- path15.join(home, ".fnm", "node-versions"),
35245
- path15.join(home, "Library", "Application Support", "fnm", "node-versions")
35802
+ path17.join(home, ".fnm", "node-versions"),
35803
+ path17.join(home, "Library", "Application Support", "fnm", "node-versions")
35246
35804
  ];
35247
35805
  const dirs = [];
35248
35806
  for (const root of roots) {
@@ -35252,7 +35810,7 @@ function fnmVersionBinDirs(home) {
35252
35810
  } catch {
35253
35811
  continue;
35254
35812
  }
35255
- dirs.push(...sortVersionNamesDesc(versions).map((version) => path15.join(root, version, "installation", "bin")));
35813
+ dirs.push(...sortVersionNamesDesc(versions).map((version) => path17.join(root, version, "installation", "bin")));
35256
35814
  }
35257
35815
  return dirs;
35258
35816
  }
@@ -35274,22 +35832,22 @@ function parseVersionName(value) {
35274
35832
  return value.replace(/^v/i, "").split(".").map((part) => Number.parseInt(part, 10)).filter((part) => Number.isFinite(part));
35275
35833
  }
35276
35834
  function splitPath(value) {
35277
- return value?.split(path15.delimiter).filter(Boolean) ?? [];
35835
+ return value?.split(path17.delimiter).filter(Boolean) ?? [];
35278
35836
  }
35279
35837
  function mergePath(prependDirs, existing) {
35280
- return unique([...prependDirs, ...splitPath(existing)]).join(path15.delimiter);
35838
+ return unique([...prependDirs, ...splitPath(existing)]).join(path17.delimiter);
35281
35839
  }
35282
35840
  function anchorResolvedPath(pathValue, resolution) {
35283
- return mergePath([path15.dirname(resolution.binaryPath), ...splitPath(resolution.pathValue)], pathValue);
35841
+ return mergePath([path17.dirname(resolution.binaryPath), ...splitPath(resolution.pathValue)], pathValue);
35284
35842
  }
35285
- function commandCandidates(command, env) {
35286
- if (process.platform !== "win32")
35843
+ function commandCandidates(command, env, platform2 = process.platform) {
35844
+ if (platform2 !== "win32")
35287
35845
  return [command];
35288
35846
  const hasExt = /\.[^\\/]+$/.test(command);
35289
35847
  if (hasExt)
35290
35848
  return [command];
35291
- const exts = (env.PATHEXT || ".EXE;.CMD;.BAT;.COM").split(";").filter(Boolean).map((ext) => ext.toLowerCase());
35292
- return [command, ...exts.map((ext) => `${command}${ext}`)];
35849
+ const exts = (env.PATHEXT || ".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean).map((ext) => ext.toLowerCase());
35850
+ return exts.map((ext) => `${command}${ext}`);
35293
35851
  }
35294
35852
  function getCachedResolution(cacheKey) {
35295
35853
  const entry = resolutionCache.get(cacheKey);
@@ -35368,7 +35926,7 @@ function resolveRuntimeBinary(runtimeType, baseEnv) {
35368
35926
  return binaryPath ? { binaryPath, env } : null;
35369
35927
  }
35370
35928
  function probeVersion(binaryPath, env) {
35371
- return new Promise((resolve8) => {
35929
+ return new Promise((resolve9) => {
35372
35930
  execFile(
35373
35931
  IS_WIN32 ? quoteWin32Arg(binaryPath) : binaryPath,
35374
35932
  ["--version"],
@@ -35377,11 +35935,11 @@ function probeVersion(binaryPath, env) {
35377
35935
  { env, timeout: VERSION_PROBE_TIMEOUT_MS, windowsHide: true, shell: IS_WIN32 },
35378
35936
  (err, stdout) => {
35379
35937
  if (err) {
35380
- resolve8({ ok: false });
35938
+ resolve9({ ok: false });
35381
35939
  return;
35382
35940
  }
35383
35941
  const line = String(stdout).split(/\r?\n/).map((l) => l.trim()).find((l) => l.length > 0) ?? "";
35384
- resolve8(line ? { ok: true, version: line.slice(0, VERSION_MAX_LEN) } : { ok: true });
35942
+ resolve9(line ? { ok: true, version: line.slice(0, VERSION_MAX_LEN) } : { ok: true });
35385
35943
  }
35386
35944
  );
35387
35945
  });
@@ -35435,7 +35993,7 @@ var init_runtime_detector = __esm({
35435
35993
  import { spawn as spawn5 } from "node:child_process";
35436
35994
  import { createHash as createHash3 } from "node:crypto";
35437
35995
  import * as fs12 from "node:fs";
35438
- import * as path16 from "node:path";
35996
+ import * as path18 from "node:path";
35439
35997
  async function prepareWorkspace(opts) {
35440
35998
  const prior = opts.attached.workspace_state;
35441
35999
  const plan = buildWorkspacePlan(opts.attached.daemon_config, opts.defaultWorkspaceDir, prior?.config_hash);
@@ -35580,8 +36138,8 @@ async function ensureWorkspace(plan, log2) {
35580
36138
  assertSafeCustomWorkspacePath(plan);
35581
36139
  }
35582
36140
  if (!fs12.existsSync(plan.workspaceDir)) {
35583
- fs12.mkdirSync(path16.dirname(plan.workspaceDir), { recursive: true });
35584
- assertWritableWorkspaceDir(path16.dirname(plan.workspaceDir));
36141
+ fs12.mkdirSync(path18.dirname(plan.workspaceDir), { recursive: true });
36142
+ assertWritableWorkspaceDir(path18.dirname(plan.workspaceDir));
35585
36143
  await runCommand("git", ["clone", remote, plan.workspaceDir], process.cwd());
35586
36144
  } else {
35587
36145
  const st = fs12.statSync(plan.workspaceDir);
@@ -35712,7 +36270,7 @@ async function tryGitOutput(cmd, args, cwd) {
35712
36270
  }
35713
36271
  }
35714
36272
  function runCommand(cmd, args, cwd, timeoutMs = 12e4, env = process.env) {
35715
- return new Promise((resolve8, reject) => {
36273
+ return new Promise((resolve9, reject) => {
35716
36274
  let tail = "";
35717
36275
  let timedOut = false;
35718
36276
  let settled = false;
@@ -35754,7 +36312,7 @@ ${tail}`)));
35754
36312
  return;
35755
36313
  }
35756
36314
  if (code === 0) {
35757
- settle(() => resolve8(tail));
36315
+ settle(() => resolve9(tail));
35758
36316
  } else {
35759
36317
  settle(() => reject(new Error(`command failed (${code ?? signal}): ${cmd} ${args.join(" ")}
35760
36318
  ${tail}`)));
@@ -35763,10 +36321,10 @@ ${tail}`)));
35763
36321
  });
35764
36322
  }
35765
36323
  function requireAbsolute(value, field) {
35766
- if (!value || !path16.isAbsolute(value)) {
36324
+ if (!value || !path18.isAbsolute(value)) {
35767
36325
  throw new Error(`${field} must be an absolute path`);
35768
36326
  }
35769
- return path16.resolve(value);
36327
+ return path18.resolve(value);
35770
36328
  }
35771
36329
  function assertSafeCustomWorkspacePath(plan, candidate = plan.workspaceDir) {
35772
36330
  if (!plan.customWorkspaceField)
@@ -35776,14 +36334,14 @@ function assertSafeCustomWorkspacePath(plan, candidate = plan.workspaceDir) {
35776
36334
  if (reason) {
35777
36335
  throw new Error(`${plan.customWorkspaceField} must point to a project folder, not ${reason}: ${normalized}`);
35778
36336
  }
35779
- const defaultWorkspace = path16.resolve(plan.defaultWorkspaceDir);
36337
+ const defaultWorkspace = path18.resolve(plan.defaultWorkspaceDir);
35780
36338
  if (isAncestorPath(normalized, defaultWorkspace) || normalized === defaultWorkspace) {
35781
36339
  throw new Error(`${plan.customWorkspaceField} must not point at daemon state directories: ${normalized}`);
35782
36340
  }
35783
36341
  }
35784
36342
  function assertWritableWorkspaceDir(dir) {
35785
36343
  fs12.accessSync(dir, fs12.constants.R_OK | fs12.constants.W_OK | fs12.constants.X_OK);
35786
- const probe = path16.join(dir, `.parall-workspace-check-${process.pid}-${Date.now()}`);
36344
+ const probe = path18.join(dir, `.parall-workspace-check-${process.pid}-${Date.now()}`);
35787
36345
  const fd = fs12.openSync(probe, "wx", 384);
35788
36346
  fs12.closeSync(fd);
35789
36347
  fs12.unlinkSync(probe);
@@ -35847,11 +36405,11 @@ function workspacePathDenyReason(value) {
35847
36405
  return "";
35848
36406
  }
35849
36407
  function isAncestorPath(parent, child) {
35850
- const relative2 = path16.relative(parent, child);
35851
- return relative2 !== "" && !relative2.startsWith("..") && !path16.isAbsolute(relative2);
36408
+ const relative2 = path18.relative(parent, child);
36409
+ return relative2 !== "" && !relative2.startsWith("..") && !path18.isAbsolute(relative2);
35852
36410
  }
35853
36411
  function toPolicyPath(value) {
35854
- return path16.resolve(value).split(path16.sep).join("/");
36412
+ return path18.resolve(value).split(path18.sep).join("/");
35855
36413
  }
35856
36414
  function isNodeError(err) {
35857
36415
  return err instanceof Error && "code" in err;
@@ -35870,18 +36428,18 @@ var init_workspace = __esm({
35870
36428
  import { spawn as spawn6 } from "node:child_process";
35871
36429
  import * as fs13 from "node:fs";
35872
36430
  import * as os7 from "node:os";
35873
- import * as path17 from "node:path";
36431
+ import * as path19 from "node:path";
35874
36432
  function sleepCancellable(ms, signal) {
35875
36433
  if (signal.aborted)
35876
36434
  return Promise.resolve(false);
35877
- return new Promise((resolve8) => {
36435
+ return new Promise((resolve9) => {
35878
36436
  const timer = setTimeout(() => {
35879
36437
  signal.removeEventListener("abort", onAbort);
35880
- resolve8(true);
36438
+ resolve9(true);
35881
36439
  }, ms);
35882
36440
  const onAbort = () => {
35883
36441
  clearTimeout(timer);
35884
- resolve8(false);
36442
+ resolve9(false);
35885
36443
  };
35886
36444
  signal.addEventListener("abort", onAbort, { once: true });
35887
36445
  });
@@ -36021,7 +36579,7 @@ var init_supervisor = __esm({
36021
36579
  this.migrateFlatLayout();
36022
36580
  if (process.env.PRLL_CLIP_RUNTIME_ENABLED === "true") {
36023
36581
  this.browserProfilePool = new BrowserProfilePool({
36024
- baseHomeDir: path17.join(this.config.rootStateDir, "bb-browser"),
36582
+ baseHomeDir: path19.join(this.config.rootStateDir, "bb-browser"),
36025
36583
  log: this.log,
36026
36584
  reportStatus: (profileId, status, errorMsg, generation) => {
36027
36585
  this.client.reportBrowserProfileStatus(profileId, status, errorMsg, generation).catch((err) => this.log.warn(`browser profile status report failed: ${String(err)}`));
@@ -36029,8 +36587,8 @@ var init_supervisor = __esm({
36029
36587
  resolveProxy: (profileId) => this.resolveBrowserProfileProxy(profileId)
36030
36588
  });
36031
36589
  this.clipManager = new ClipProcessManager({
36032
- clipsDir: path17.join(this.config.rootStateDir, "clips"),
36033
- dataDir: path17.join(this.config.rootStateDir, "clip-data"),
36590
+ clipsDir: path19.join(this.config.rootStateDir, "clips"),
36591
+ dataDir: path19.join(this.config.rootStateDir, "clip-data"),
36034
36592
  browserProfileManager: this.browserProfilePool,
36035
36593
  // Execution side: nested browser dependency invokes resolve their
36036
36594
  // binding and route through the hub (no local shortcut).
@@ -36138,8 +36696,8 @@ var init_supervisor = __esm({
36138
36696
  }
36139
36697
  });
36140
36698
  await this.ws.connect();
36141
- await new Promise((resolve8) => {
36142
- this.stopResolve = resolve8;
36699
+ await new Promise((resolve9) => {
36700
+ this.stopResolve = resolve9;
36143
36701
  });
36144
36702
  signal.removeEventListener("abort", onAbort);
36145
36703
  }
@@ -36435,12 +36993,12 @@ var init_supervisor = __esm({
36435
36993
  */
36436
36994
  migrateFlatLayout() {
36437
36995
  const root = this.config.rootStateDir;
36438
- const agentsDir = path17.join(root, "agents");
36439
- const flatWorkspace = path17.join(root, "workspace");
36996
+ const agentsDir = path19.join(root, "agents");
36997
+ const flatWorkspace = path19.join(root, "workspace");
36440
36998
  if (!fs13.existsSync(flatWorkspace) || fs13.existsSync(agentsDir))
36441
36999
  return;
36442
37000
  let ownerAgentId;
36443
- const sessionsDir = path17.join(root, "sessions");
37001
+ const sessionsDir = path19.join(root, "sessions");
36444
37002
  if (fs13.existsSync(sessionsDir)) {
36445
37003
  try {
36446
37004
  for (const file of fs13.readdirSync(sessionsDir)) {
@@ -36457,13 +37015,13 @@ var init_supervisor = __esm({
36457
37015
  }
36458
37016
  }
36459
37017
  const targetId = ownerAgentId ?? "_orphan";
36460
- const targetDir = path17.join(agentsDir, targetId);
37018
+ const targetDir = path19.join(agentsDir, targetId);
36461
37019
  try {
36462
37020
  fs13.mkdirSync(targetDir, { recursive: true });
36463
37021
  for (const sub of ["workspace", "sessions", "dispatch-context"]) {
36464
- const src = path17.join(root, sub);
37022
+ const src = path19.join(root, sub);
36465
37023
  if (fs13.existsSync(src)) {
36466
- fs13.renameSync(src, path17.join(targetDir, sub));
37024
+ fs13.renameSync(src, path19.join(targetDir, sub));
36467
37025
  }
36468
37026
  }
36469
37027
  this.log.info(`migrated legacy flat state \u2192 agents/${targetId}/`);
@@ -36754,7 +37312,7 @@ var init_supervisor = __esm({
36754
37312
  return this.runtimeDetectInFlight;
36755
37313
  }
36756
37314
  machineClipToConfig(clip) {
36757
- const clipPath = path17.join(this.config.rootStateDir, "clips", clip.alias);
37315
+ const clipPath = path19.join(this.config.rootStateDir, "clips", clip.alias);
36758
37316
  return {
36759
37317
  clipId: clip.clip_id,
36760
37318
  name: clip.alias,
@@ -36820,7 +37378,7 @@ var init_supervisor = __esm({
36820
37378
  if (!sourceRef) {
36821
37379
  throw new Error(`registry clip "${config.name}" is missing source_ref`);
36822
37380
  }
36823
- const expectedPath = path17.join(this.config.rootStateDir, "clips", config.name);
37381
+ const expectedPath = path19.join(this.config.rootStateDir, "clips", config.name);
36824
37382
  const localVersion = this.readInstalledClipVersion(expectedPath);
36825
37383
  if (localVersion && (!config.version || localVersion === config.version)) {
36826
37384
  return { ...config, path: expectedPath, source: expectedPath };
@@ -36838,7 +37396,7 @@ var init_supervisor = __esm({
36838
37396
  const result = await installClip({
36839
37397
  source,
36840
37398
  alias: config.name,
36841
- clipsDir: path17.join(this.config.rootStateDir, "clips"),
37399
+ clipsDir: path19.join(this.config.rootStateDir, "clips"),
36842
37400
  registryUrl: process.env.PRLL_PINIX_REGISTRY_URL?.trim() || void 0
36843
37401
  });
36844
37402
  this.log.info(`clip ensured: ${result.alias} v${result.version} at ${result.path}`);
@@ -36853,7 +37411,7 @@ var init_supervisor = __esm({
36853
37411
  readInstalledClipVersion(dir) {
36854
37412
  for (const file of ["clip.json", "package.json"]) {
36855
37413
  try {
36856
- const raw = fs13.readFileSync(path17.join(dir, file), "utf-8");
37414
+ const raw = fs13.readFileSync(path19.join(dir, file), "utf-8");
36857
37415
  const parsed = JSON.parse(raw);
36858
37416
  if (typeof parsed.version === "string" && parsed.version.trim()) {
36859
37417
  return parsed.version.trim();
@@ -37323,7 +37881,7 @@ var init_supervisor = __esm({
37323
37881
  child.once("error", (err) => {
37324
37882
  if (err.code === "ENOENT") {
37325
37883
  if (adapter.args.length > 0) {
37326
- this.log.error(`Node runtime "${adapter.bin}" not found \u2014 is the Desktop app installed?`);
37884
+ this.log.error(`Node runtime "${adapter.bin}" not found while launching ${adapter.args[0]} \u2014 reinstall the daemon (npm install -g @parall/daemon) or the Desktop app`);
37327
37885
  } else {
37328
37886
  const pkg = RUNTIME_PACKAGES[state.runtimeType] ?? `@parall/${state.runtimeType}-agent`;
37329
37887
  this.log.error(`Runtime binary "${adapter.bin}" not found in PATH. Install: npm install -g ${pkg}`);
@@ -37349,15 +37907,15 @@ var init_supervisor = __esm({
37349
37907
  const child = state.child;
37350
37908
  if (!child)
37351
37909
  return;
37352
- return new Promise((resolve8) => {
37353
- const onExit = () => resolve8();
37910
+ return new Promise((resolve9) => {
37911
+ const onExit = () => resolve9();
37354
37912
  child.once("exit", onExit);
37355
37913
  try {
37356
37914
  child.kill("SIGTERM");
37357
37915
  } catch (err) {
37358
37916
  this.log.warn(`SIGTERM ${state.agentId} threw: ${String(err)}`);
37359
37917
  child.off("exit", onExit);
37360
- resolve8();
37918
+ resolve9();
37361
37919
  return;
37362
37920
  }
37363
37921
  const hardKill = setTimeout(() => {
@@ -37575,7 +38133,7 @@ var init_daemon_main = __esm({
37575
38133
  init_daemon_paths();
37576
38134
  init_daemon_update_mode();
37577
38135
  import * as fs14 from "node:fs";
37578
- import * as path18 from "node:path";
38136
+ import * as path20 from "node:path";
37579
38137
  var UPDATE_EXIT_CODE2 = 42;
37580
38138
  function formatError2(reason) {
37581
38139
  if (reason instanceof Error) {
@@ -37600,7 +38158,7 @@ function clearRunningMarker(markerPath) {
37600
38158
  }
37601
38159
  function prepareDaemonBootstrap(env = process.env, args = process.argv.slice(2)) {
37602
38160
  const bundleDir = resolveBundleDir(env);
37603
- const runningMarker = path18.join(bundleDir, "daemon-running");
38161
+ const runningMarker = path20.join(bundleDir, "daemon-running");
37604
38162
  const lifecycleMarkerEnabled = args.length === 0 && !isSelfUpdateDisabledByEnv(env) && isSelfUpdateManaged(bundleDir, env);
37605
38163
  if (!lifecycleMarkerEnabled) {
37606
38164
  return { lifecycleMarkerEnabled: false, runningMarker, uncleanPrevExit: false };