@zixt/host 0.0.122 → 0.0.124

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.
Files changed (2) hide show
  1. package/dist/index.js +367 -269
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -28,7 +28,7 @@ import { homedir as homedir4 } from "node:os";
28
28
  // package.json
29
29
  var package_default = {
30
30
  name: "@zixt/host",
31
- version: "0.0.122",
31
+ version: "0.0.124",
32
32
  type: "module",
33
33
  exports: {
34
34
  ".": "./src/client.ts",
@@ -22448,6 +22448,17 @@ function sanitizedInstallerEnv(inherited) {
22448
22448
  }
22449
22449
 
22450
22450
  // src/runners/runner-install.ts
22451
+ var INSTALLABLE_RUNNERS = ["claude-code", "codex"];
22452
+ function parseRunnerAutoinstallSelection(value) {
22453
+ const trimmed = value?.trim() ?? "";
22454
+ if (trimmed === "" || trimmed === "on") return new Set(INSTALLABLE_RUNNERS);
22455
+ if (trimmed === "off") return /* @__PURE__ */ new Set();
22456
+ return new Set(
22457
+ trimmed.split(",").map((token2) => token2.trim()).filter(
22458
+ (token2) => INSTALLABLE_RUNNERS.includes(token2)
22459
+ )
22460
+ );
22461
+ }
22451
22462
  var CLAUDE_INSTALLER_URL_POSIX = "https://claude.ai/install.sh";
22452
22463
  var CLAUDE_INSTALLER_URL_WINDOWS = "https://claude.ai/install.ps1";
22453
22464
  var CODEX_PACKAGE = "@openai/codex";
@@ -22464,7 +22475,7 @@ function runnerCommandCandidates(type, options = {}) {
22464
22475
  return platform === "win32" ? [join3(toolsRoot, "codex")] : [join3(toolsRoot, "bin", "codex")];
22465
22476
  }
22466
22477
  async function commandRuns(path) {
22467
- return new Promise((resolve18) => {
22478
+ return new Promise((resolve19) => {
22468
22479
  let child;
22469
22480
  try {
22470
22481
  child = spawnCli(path, ["--version"], {
@@ -22472,21 +22483,21 @@ async function commandRuns(path) {
22472
22483
  windowsHide: true
22473
22484
  });
22474
22485
  } catch {
22475
- resolve18(false);
22486
+ resolve19(false);
22476
22487
  return;
22477
22488
  }
22478
22489
  const timer = setTimeout(() => {
22479
22490
  child.kill();
22480
- resolve18(false);
22491
+ resolve19(false);
22481
22492
  }, 1e4);
22482
22493
  timer.unref?.();
22483
22494
  child.once("error", () => {
22484
22495
  clearTimeout(timer);
22485
- resolve18(false);
22496
+ resolve19(false);
22486
22497
  });
22487
22498
  child.once("exit", (code) => {
22488
22499
  clearTimeout(timer);
22489
- resolve18(code === 0);
22500
+ resolve19(code === 0);
22490
22501
  });
22491
22502
  });
22492
22503
  }
@@ -22626,10 +22637,12 @@ function createRunnerAutoInstaller(options) {
22626
22637
  };
22627
22638
  const install = options.install ?? ((type) => type === "claude-code" ? installClaude() : installCodex());
22628
22639
  return {
22629
- ensureInstalled(type) {
22640
+ ensureInstalled(type, ensureOptions) {
22630
22641
  if (inFlight.has(type)) return;
22631
22642
  const lastFailure = failedAt.get(type);
22632
- if (lastFailure !== void 0 && now() - lastFailure < FAILURE_COOLDOWN_MS) return;
22643
+ if (!ensureOptions?.force && lastFailure !== void 0 && now() - lastFailure < FAILURE_COOLDOWN_MS) {
22644
+ return;
22645
+ }
22633
22646
  options.onEvent({ runner: type, state: "started" });
22634
22647
  const attempt = (async () => {
22635
22648
  try {
@@ -22663,6 +22676,9 @@ function createRunnerAutoInstaller(options) {
22663
22676
  })();
22664
22677
  inFlight.set(type, attempt);
22665
22678
  },
22679
+ isInstalling(type) {
22680
+ return inFlight.has(type);
22681
+ },
22666
22682
  async settled() {
22667
22683
  while (inFlight.size > 0) await Promise.allSettled([...inFlight.values()]);
22668
22684
  }
@@ -22687,7 +22703,7 @@ async function generateTaskTitle(instructions, runner) {
22687
22703
  instructions.slice(0, INSTRUCTIONS_BUDGET),
22688
22704
  "</task_request>"
22689
22705
  ].join("\n");
22690
- return new Promise((resolve18) => {
22706
+ return new Promise((resolve19) => {
22691
22707
  const child = spawnCli(
22692
22708
  command,
22693
22709
  [
@@ -22710,7 +22726,7 @@ async function generateTaskTitle(instructions, runner) {
22710
22726
  if (settled) return;
22711
22727
  settled = true;
22712
22728
  clearTimeout(timer);
22713
- resolve18(value);
22729
+ resolve19(value);
22714
22730
  };
22715
22731
  const timer = setTimeout(() => {
22716
22732
  child.kill();
@@ -23039,11 +23055,11 @@ function createWorkerWatchdogSendDrain() {
23039
23055
  if (completed) return;
23040
23056
  completed = true;
23041
23057
  pending--;
23042
- if (pending === 0) drained.splice(0).forEach((resolve18) => resolve18());
23058
+ if (pending === 0) drained.splice(0).forEach((resolve19) => resolve19());
23043
23059
  };
23044
23060
  },
23045
23061
  drain: async () => {
23046
- if (pending > 0) await new Promise((resolve18) => drained.push(resolve18));
23062
+ if (pending > 0) await new Promise((resolve19) => drained.push(resolve19));
23047
23063
  }
23048
23064
  };
23049
23065
  }
@@ -23560,7 +23576,7 @@ async function waitForOperationGrantRetry(retryAt, signal) {
23560
23576
  const deadline = Date.parse(retryAt);
23561
23577
  if (!Number.isFinite(deadline) || signal.aborted) return false;
23562
23578
  if (deadline <= Date.now()) return true;
23563
- return await new Promise((resolve18) => {
23579
+ return await new Promise((resolve19) => {
23564
23580
  let settled = false;
23565
23581
  let timer;
23566
23582
  const finish = (ready) => {
@@ -23568,7 +23584,7 @@ async function waitForOperationGrantRetry(retryAt, signal) {
23568
23584
  settled = true;
23569
23585
  if (timer) clearTimeout(timer);
23570
23586
  signal.removeEventListener("abort", onAbort);
23571
- resolve18(ready);
23587
+ resolve19(ready);
23572
23588
  };
23573
23589
  const onAbort = () => finish(false);
23574
23590
  const schedule = () => {
@@ -23849,27 +23865,27 @@ var HostClient = class _HostClient {
23849
23865
  const unwindingAssignments = [...this.activeAssignments.values()];
23850
23866
  for (const cancel of this.cancels.values()) cancel(stopReason);
23851
23867
  for (const entry of this.secretGrants.values()) {
23852
- for (const resolve18 of entry.resolvers) resolve18({});
23868
+ for (const resolve19 of entry.resolvers) resolve19({});
23853
23869
  entry.resolvers = [];
23854
23870
  delete entry.value;
23855
23871
  }
23856
23872
  for (const entry of this.connectionGrants.values()) {
23857
- for (const resolve18 of entry.resolvers) resolve18([]);
23873
+ for (const resolve19 of entry.resolvers) resolve19([]);
23858
23874
  entry.resolvers = [];
23859
23875
  delete entry.value;
23860
23876
  }
23861
23877
  for (const entry of this.providerGrants.values()) {
23862
- for (const resolve18 of entry.resolvers) resolve18([]);
23878
+ for (const resolve19 of entry.resolvers) resolve19([]);
23863
23879
  entry.resolvers = [];
23864
23880
  delete entry.value;
23865
23881
  }
23866
23882
  for (const entry of this.integrationToolServerGrants.values()) {
23867
- for (const resolve18 of entry.resolvers) resolve18([]);
23883
+ for (const resolve19 of entry.resolvers) resolve19([]);
23868
23884
  entry.resolvers = [];
23869
23885
  delete entry.value;
23870
23886
  }
23871
23887
  for (const waiters of this.approvalWaiters.values()) {
23872
- for (const resolve18 of waiters.values()) resolve18({ approved: false, guidance: reason });
23888
+ for (const resolve19 of waiters.values()) resolve19({ approved: false, guidance: reason });
23873
23889
  }
23874
23890
  for (const waiters of this.agentOpWaiters.values()) {
23875
23891
  for (const waiter of waiters.values()) {
@@ -23896,9 +23912,9 @@ var HostClient = class _HostClient {
23896
23912
  let drainTimer;
23897
23913
  const drained = await Promise.race([
23898
23914
  Promise.allSettled(runs).then(() => true),
23899
- new Promise((resolve18) => {
23915
+ new Promise((resolve19) => {
23900
23916
  drainTimer = setTimeout(
23901
- () => resolve18(false),
23917
+ () => resolve19(false),
23902
23918
  this.opts.unwindTimeoutMs ?? _HostClient.DEFAULT_UNWIND_TIMEOUT_MS
23903
23919
  );
23904
23920
  drainTimer.unref?.();
@@ -24046,9 +24062,9 @@ var HostClient = class _HostClient {
24046
24062
  let frameDrainTimer;
24047
24063
  const framesDrained = await Promise.race([
24048
24064
  frameTail.then(() => true),
24049
- new Promise((resolve18) => {
24065
+ new Promise((resolve19) => {
24050
24066
  frameDrainTimer = setTimeout(
24051
- () => resolve18(false),
24067
+ () => resolve19(false),
24052
24068
  this.opts.unwindTimeoutMs ?? _HostClient.DEFAULT_UNWIND_TIMEOUT_MS
24053
24069
  );
24054
24070
  frameDrainTimer.unref?.();
@@ -24624,7 +24640,7 @@ var HostClient = class _HostClient {
24624
24640
  const entry = this.secretGrants.get(key) ?? { resolvers: [] };
24625
24641
  entry.value = message.secrets;
24626
24642
  entry.expiresAt = expiresAt;
24627
- for (const resolve18 of entry.resolvers) resolve18(message.secrets);
24643
+ for (const resolve19 of entry.resolvers) resolve19(message.secrets);
24628
24644
  entry.resolvers = [];
24629
24645
  this.secretGrants.set(key, entry);
24630
24646
  return;
@@ -24655,19 +24671,19 @@ var HostClient = class _HostClient {
24655
24671
  const entry = this.connectionGrants.get(key) ?? { resolvers: [] };
24656
24672
  entry.value = message.connections;
24657
24673
  entry.expiresAt = expiresAt;
24658
- for (const resolve18 of entry.resolvers) resolve18(message.connections);
24674
+ for (const resolve19 of entry.resolvers) resolve19(message.connections);
24659
24675
  entry.resolvers = [];
24660
24676
  this.connectionGrants.set(key, entry);
24661
24677
  const providerEntry = this.providerGrants.get(key) ?? { resolvers: [] };
24662
24678
  providerEntry.value = providers;
24663
24679
  providerEntry.expiresAt = authorityExpiresAt;
24664
- for (const resolve18 of providerEntry.resolvers) resolve18(providers);
24680
+ for (const resolve19 of providerEntry.resolvers) resolve19(providers);
24665
24681
  providerEntry.resolvers = [];
24666
24682
  this.providerGrants.set(key, providerEntry);
24667
24683
  const toolServerEntry = this.integrationToolServerGrants.get(key) ?? { resolvers: [] };
24668
24684
  const toolServers = [...message.toolServers ?? []];
24669
24685
  toolServerEntry.value = toolServers;
24670
- for (const resolve18 of toolServerEntry.resolvers) resolve18(toolServers);
24686
+ for (const resolve19 of toolServerEntry.resolvers) resolve19(toolServers);
24671
24687
  toolServerEntry.resolvers = [];
24672
24688
  this.integrationToolServerGrants.set(key, toolServerEntry);
24673
24689
  return;
@@ -24806,8 +24822,8 @@ var HostClient = class _HostClient {
24806
24822
  return redactCredentialText(text, sensitiveSnapshot()).slice(0, maxLength);
24807
24823
  };
24808
24824
  let resolveCancelled;
24809
- const cancelledPromise = new Promise((resolve18) => {
24810
- resolveCancelled = resolve18;
24825
+ const cancelledPromise = new Promise((resolve19) => {
24826
+ resolveCancelled = resolve19;
24811
24827
  });
24812
24828
  const endAuthority = (reason = "cloud_cancel") => {
24813
24829
  if (stopReason) return;
@@ -24816,28 +24832,28 @@ var HostClient = class _HostClient {
24816
24832
  authorityController.abort(reason);
24817
24833
  const secretEntry = this.secretGrants.get(cancelKey);
24818
24834
  if (secretEntry) {
24819
- for (const resolve18 of secretEntry.resolvers) resolve18({});
24835
+ for (const resolve19 of secretEntry.resolvers) resolve19({});
24820
24836
  secretEntry.resolvers = [];
24821
24837
  delete secretEntry.value;
24822
24838
  }
24823
24839
  this.secretGrants.delete(cancelKey);
24824
24840
  const connectionEntry = this.connectionGrants.get(cancelKey);
24825
24841
  if (connectionEntry) {
24826
- for (const resolve18 of connectionEntry.resolvers) resolve18([]);
24842
+ for (const resolve19 of connectionEntry.resolvers) resolve19([]);
24827
24843
  connectionEntry.resolvers = [];
24828
24844
  delete connectionEntry.value;
24829
24845
  }
24830
24846
  this.connectionGrants.delete(cancelKey);
24831
24847
  const providerEntry = this.providerGrants.get(cancelKey);
24832
24848
  if (providerEntry) {
24833
- for (const resolve18 of providerEntry.resolvers) resolve18([]);
24849
+ for (const resolve19 of providerEntry.resolvers) resolve19([]);
24834
24850
  providerEntry.resolvers = [];
24835
24851
  delete providerEntry.value;
24836
24852
  }
24837
24853
  this.providerGrants.delete(cancelKey);
24838
24854
  const toolServerEntry = this.integrationToolServerGrants.get(cancelKey);
24839
24855
  if (toolServerEntry) {
24840
- for (const resolve18 of toolServerEntry.resolvers) resolve18([]);
24856
+ for (const resolve19 of toolServerEntry.resolvers) resolve19([]);
24841
24857
  toolServerEntry.resolvers = [];
24842
24858
  delete toolServerEntry.value;
24843
24859
  }
@@ -24845,8 +24861,8 @@ var HostClient = class _HostClient {
24845
24861
  this.clearAuthorityExpiry(cancelKey);
24846
24862
  const approvalWaiters = this.approvalWaiters.get(cancelKey);
24847
24863
  if (approvalWaiters) {
24848
- for (const resolve18 of approvalWaiters.values()) {
24849
- resolve18({ approved: false, guidance: "task was cancelled" });
24864
+ for (const resolve19 of approvalWaiters.values()) {
24865
+ resolve19({ approved: false, guidance: "task was cancelled" });
24850
24866
  }
24851
24867
  approvalWaiters.clear();
24852
24868
  }
@@ -24972,9 +24988,9 @@ var HostClient = class _HostClient {
24972
24988
  return value;
24973
24989
  };
24974
24990
  if (entry.value) return Promise.resolve(capture(entry.value));
24975
- return new Promise((resolve18) => {
24976
- entry.resolvers.push((value) => resolve18(capture(value)));
24977
- setTimeout(() => resolve18(capture(entry.value ?? {})), _HostClient.SECRETS_WAIT_MS);
24991
+ return new Promise((resolve19) => {
24992
+ entry.resolvers.push((value) => resolve19(capture(value)));
24993
+ setTimeout(() => resolve19(capture(entry.value ?? {})), _HostClient.SECRETS_WAIT_MS);
24978
24994
  });
24979
24995
  };
24980
24996
  const connections = () => {
@@ -24991,9 +25007,9 @@ var HostClient = class _HostClient {
24991
25007
  return value;
24992
25008
  };
24993
25009
  if (entry.value) return Promise.resolve(capture(entry.value));
24994
- return new Promise((resolve18) => {
24995
- entry.resolvers.push((value) => resolve18(capture(value)));
24996
- setTimeout(() => resolve18(capture(entry.value ?? [])), _HostClient.SECRETS_WAIT_MS);
25010
+ return new Promise((resolve19) => {
25011
+ entry.resolvers.push((value) => resolve19(capture(value)));
25012
+ setTimeout(() => resolve19(capture(entry.value ?? [])), _HostClient.SECRETS_WAIT_MS);
24997
25013
  });
24998
25014
  };
24999
25015
  const providers = () => {
@@ -25010,9 +25026,9 @@ var HostClient = class _HostClient {
25010
25026
  return value;
25011
25027
  };
25012
25028
  if (entry.value !== void 0) return Promise.resolve(capture(entry.value));
25013
- return new Promise((resolve18) => {
25014
- entry.resolvers.push((value) => resolve18(capture(value)));
25015
- setTimeout(() => resolve18(capture(entry.value ?? [])), _HostClient.SECRETS_WAIT_MS);
25029
+ return new Promise((resolve19) => {
25030
+ entry.resolvers.push((value) => resolve19(capture(value)));
25031
+ setTimeout(() => resolve19(capture(entry.value ?? [])), _HostClient.SECRETS_WAIT_MS);
25016
25032
  });
25017
25033
  };
25018
25034
  const integrationToolServers = () => {
@@ -25021,9 +25037,9 @@ var HostClient = class _HostClient {
25021
25037
  this.integrationToolServerGrants.set(cancelKey, entry);
25022
25038
  const capture = (value) => authorityController.signal.aborted ? [] : value;
25023
25039
  if (entry.value !== void 0) return Promise.resolve(capture(entry.value));
25024
- return new Promise((resolve18) => {
25025
- entry.resolvers.push((value) => resolve18(capture(value)));
25026
- setTimeout(() => resolve18(capture(entry.value ?? [])), _HostClient.SECRETS_WAIT_MS);
25040
+ return new Promise((resolve19) => {
25041
+ entry.resolvers.push((value) => resolve19(capture(value)));
25042
+ setTimeout(() => resolve19(capture(entry.value ?? [])), _HostClient.SECRETS_WAIT_MS);
25027
25043
  });
25028
25044
  };
25029
25045
  const linear = async () => {
@@ -25050,13 +25066,13 @@ var HostClient = class _HostClient {
25050
25066
  ...questionChoices ? { questionChoices: [...questionChoices] } : {},
25051
25067
  ...questionnaire ? { questionnaire } : {}
25052
25068
  });
25053
- return new Promise((resolve18) => {
25069
+ return new Promise((resolve19) => {
25054
25070
  const waiters = this.approvalWaiters.get(cancelKey) ?? /* @__PURE__ */ new Map();
25055
25071
  this.approvalWaiters.set(cancelKey, waiters);
25056
- waiters.set(requestId, resolve18);
25072
+ waiters.set(requestId, resolve19);
25057
25073
  void cancelledPromise.then(() => {
25058
25074
  if (waiters.delete(requestId)) {
25059
- resolve18({ approved: false, guidance: "task was cancelled" });
25075
+ resolve19({ approved: false, guidance: "task was cancelled" });
25060
25076
  }
25061
25077
  });
25062
25078
  });
@@ -25102,11 +25118,11 @@ var HostClient = class _HostClient {
25102
25118
  if (existing) message = existing;
25103
25119
  else terminalMessages.set(requestId, message);
25104
25120
  }
25105
- return new Promise((resolve18) => {
25121
+ return new Promise((resolve19) => {
25106
25122
  const waiters = this.agentOpWaiters.get(cancelKey) ?? /* @__PURE__ */ new Map();
25107
25123
  this.agentOpWaiters.set(cancelKey, waiters);
25108
25124
  if (waiters.has(requestId)) {
25109
- resolve18({ ok: false, error: "provider settlement request is already in flight" });
25125
+ resolve19({ ok: false, error: "provider settlement request is already in flight" });
25110
25126
  return;
25111
25127
  }
25112
25128
  const timer = setTimeout(() => {
@@ -25117,7 +25133,7 @@ var HostClient = class _HostClient {
25117
25133
  (pending) => !(pending.type === "agent.op" && pending.requestId === requestId)
25118
25134
  );
25119
25135
  }
25120
- resolve18({
25136
+ resolve19({
25121
25137
  ok: false,
25122
25138
  error: terminal ? "The provider call completed, but Zixt could not record its outcome. Do not retry; wait for reconciliation." : "the platform did not answer in time; verify with a list_* tool before retrying a mutating call"
25123
25139
  });
@@ -25125,7 +25141,7 @@ var HostClient = class _HostClient {
25125
25141
  }, _HostClient.AGENT_OP_TIMEOUT_MS);
25126
25142
  timer.unref?.();
25127
25143
  waiters.set(requestId, {
25128
- resolve: resolve18,
25144
+ resolve: resolve19,
25129
25145
  timer,
25130
25146
  ...terminal ? { terminalMessage: message } : {}
25131
25147
  });
@@ -25171,12 +25187,12 @@ var HostClient = class _HostClient {
25171
25187
  "No GitHub change was attempted; the authority grant request was invalid."
25172
25188
  );
25173
25189
  }
25174
- const outcome = await new Promise((resolve18) => {
25190
+ const outcome = await new Promise((resolve19) => {
25175
25191
  const timer = setTimeout(() => {
25176
25192
  const waiter = this.operationGrantWaiters.get(requestId);
25177
25193
  if (!waiter) return;
25178
25194
  this.operationGrantWaiters.delete(requestId);
25179
- resolve18({ grant: null, retryable: true, reason: "no_reply_from_zixt" });
25195
+ resolve19({ grant: null, retryable: true, reason: "no_reply_from_zixt" });
25180
25196
  }, this.operationGrantTimeoutMs);
25181
25197
  timer.unref?.();
25182
25198
  this.operationGrantWaiters.set(requestId, {
@@ -25189,9 +25205,9 @@ var HostClient = class _HostClient {
25189
25205
  timer,
25190
25206
  accept: (grant) => {
25191
25207
  addSensitiveValues(providerGrantSensitiveValues(grant));
25192
- resolve18({ grant });
25208
+ resolve19({ grant });
25193
25209
  },
25194
- deny: (retryable, reason, detail, retryAt, retryCode) => resolve18({
25210
+ deny: (retryable, reason, detail, retryAt, retryCode) => resolve19({
25195
25211
  grant: null,
25196
25212
  retryable,
25197
25213
  reason,
@@ -25205,7 +25221,7 @@ var HostClient = class _HostClient {
25205
25221
  } catch {
25206
25222
  clearTimeout(timer);
25207
25223
  this.operationGrantWaiters.delete(requestId);
25208
- resolve18({ grant: null, retryable: false, reason: "connection_unavailable" });
25224
+ resolve19({ grant: null, retryable: false, reason: "connection_unavailable" });
25209
25225
  }
25210
25226
  });
25211
25227
  if (outcome.grant) {
@@ -25261,7 +25277,7 @@ var HostClient = class _HostClient {
25261
25277
  )
25262
25278
  );
25263
25279
  }
25264
- return new Promise((resolve18, reject3) => {
25280
+ return new Promise((resolve19, reject3) => {
25265
25281
  const timer = setTimeout(() => {
25266
25282
  if (this.browserCredentialWaiters.delete(requestId)) {
25267
25283
  reject3(
@@ -25280,7 +25296,7 @@ var HostClient = class _HostClient {
25280
25296
  timer,
25281
25297
  accept: (credential) => {
25282
25298
  addSensitiveValues(webLoginSensitiveValues(credential));
25283
- resolve18(credential);
25299
+ resolve19(credential);
25284
25300
  },
25285
25301
  deny: (reason) => reject3(new Error(reason))
25286
25302
  });
@@ -25603,14 +25619,14 @@ async function observeWindowsGuardianNonce(pid, nonce) {
25603
25619
  "Windows runner identity could not be observed"
25604
25620
  );
25605
25621
  }
25606
- return new Promise((resolve18, reject3) => {
25622
+ return new Promise((resolve19, reject3) => {
25607
25623
  let done = false;
25608
25624
  const finish = (result) => {
25609
25625
  if (done) return;
25610
25626
  done = true;
25611
25627
  clearTimeout(timeout);
25612
25628
  if (result instanceof Error) reject3(result);
25613
- else resolve18(result);
25629
+ else resolve19(result);
25614
25630
  };
25615
25631
  const timeout = setTimeout(
25616
25632
  () => finish(
@@ -25655,7 +25671,7 @@ async function observePosixGuardianNonce(pid, nonce) {
25655
25671
  );
25656
25672
  }
25657
25673
  }
25658
- return new Promise((resolve18, reject3) => {
25674
+ return new Promise((resolve19, reject3) => {
25659
25675
  const observer = spawn3("/bin/ps", ["-ww", "-o", "command=", "-p", String(pid)], {
25660
25676
  stdio: ["ignore", "pipe", "ignore"]
25661
25677
  });
@@ -25666,7 +25682,7 @@ async function observePosixGuardianNonce(pid, nonce) {
25666
25682
  done = true;
25667
25683
  clearTimeout(timeout);
25668
25684
  if (result instanceof Error) reject3(result);
25669
- else resolve18(result);
25685
+ else resolve19(result);
25670
25686
  };
25671
25687
  const timeout = setTimeout(() => {
25672
25688
  observer.kill("SIGKILL");
@@ -25713,7 +25729,7 @@ async function observeGuardianIdentity(pid, identity) {
25713
25729
  return process.platform === "win32" ? observeWindowsGuardianNonce(pid, identity.nonce) : observePosixGuardianNonce(pid, identity.nonce);
25714
25730
  }
25715
25731
  function delay(ms) {
25716
- return new Promise((resolve18) => setTimeout(resolve18, ms));
25732
+ return new Promise((resolve19) => setTimeout(resolve19, ms));
25717
25733
  }
25718
25734
  function posixProcessRecordsFromPs(output) {
25719
25735
  const records = [];
@@ -25746,7 +25762,7 @@ function posixProcessRecordsFromPs(output) {
25746
25762
  return records;
25747
25763
  }
25748
25764
  async function snapshotPosixProcesses() {
25749
- return new Promise((resolve18, reject3) => {
25765
+ return new Promise((resolve19, reject3) => {
25750
25766
  const observer = spawn3("/bin/ps", ["-axo", "uid=,pid=,ppid=,pgid=,stat="], {
25751
25767
  stdio: ["ignore", "pipe", "ignore"]
25752
25768
  });
@@ -25759,7 +25775,7 @@ async function snapshotPosixProcesses() {
25759
25775
  if (error52) reject3(error52);
25760
25776
  else {
25761
25777
  try {
25762
- resolve18(posixProcessRecordsFromPs(output));
25778
+ resolve19(posixProcessRecordsFromPs(output));
25763
25779
  } catch (caught) {
25764
25780
  reject3(caught);
25765
25781
  }
@@ -26094,7 +26110,7 @@ async function snapshotWindowsDescendants(rootPid) {
26094
26110
  "Windows process-tree observation could not start"
26095
26111
  );
26096
26112
  }
26097
- return new Promise((resolve18, reject3) => {
26113
+ return new Promise((resolve19, reject3) => {
26098
26114
  let done = false;
26099
26115
  const timeout = setTimeout(() => {
26100
26116
  if (done) return;
@@ -26121,7 +26137,7 @@ async function snapshotWindowsDescendants(rootPid) {
26121
26137
  return;
26122
26138
  }
26123
26139
  try {
26124
- resolve18(completeWindowsDescendantPids(rootPid, processes));
26140
+ resolve19(completeWindowsDescendantPids(rootPid, processes));
26125
26141
  } catch (caught) {
26126
26142
  reject3(caught);
26127
26143
  }
@@ -26168,7 +26184,7 @@ async function waitForProcessesExit(pids, timeoutMs) {
26168
26184
  }
26169
26185
  async function runTaskkill(pid, command, timeoutMs = TASKKILL_TIMEOUT_MS, independentlyTrackedPids = []) {
26170
26186
  const trustedCommand = command ?? defaultTaskkillCommand();
26171
- const result = await new Promise((resolve18, reject3) => {
26187
+ const result = await new Promise((resolve19, reject3) => {
26172
26188
  const killer = spawn3(trustedCommand, ["/PID", String(pid), "/T", "/F"], {
26173
26189
  stdio: ["ignore", "pipe", "pipe"],
26174
26190
  windowsHide: true
@@ -26203,7 +26219,7 @@ async function runTaskkill(pid, command, timeoutMs = TASKKILL_TIMEOUT_MS, indepe
26203
26219
  done = true;
26204
26220
  clearTimeout(timeout);
26205
26221
  if (error52) reject3(error52);
26206
- else resolve18({ code: killer.exitCode, output, outputTruncated });
26222
+ else resolve19({ code: killer.exitCode, output, outputTruncated });
26207
26223
  };
26208
26224
  killer.once(
26209
26225
  "error",
@@ -27005,12 +27021,12 @@ async function createWindowsJobContainment(pid, options) {
27005
27021
  stderr = `${stderr}${String(chunk)}`.slice(-HELPER_OUTPUT_LIMIT);
27006
27022
  });
27007
27023
  const helperEvents = helper;
27008
- const exited = new Promise((resolve18) => {
27024
+ const exited = new Promise((resolve19) => {
27009
27025
  let completed = false;
27010
27026
  const complete = (code, signal) => {
27011
27027
  if (completed) return;
27012
27028
  completed = true;
27013
- resolve18({ code, signal });
27029
+ resolve19({ code, signal });
27014
27030
  };
27015
27031
  helperEvents.once("error", () => {
27016
27032
  failProtocol(new Error("Windows Job Object helper could not start"));
@@ -27023,7 +27039,7 @@ async function createWindowsJobContainment(pid, options) {
27023
27039
  });
27024
27040
  const nextLine = async (expected) => {
27025
27041
  if (protocolFailure) throw protocolFailure;
27026
- const line = lines.shift() ?? await new Promise((resolve18, reject3) => {
27042
+ const line = lines.shift() ?? await new Promise((resolve19, reject3) => {
27027
27043
  const timer = setTimeout(
27028
27044
  () => reject3(timeoutError("Windows Job Object helper did not answer in time")),
27029
27045
  timeoutMs
@@ -27031,7 +27047,7 @@ async function createWindowsJobContainment(pid, options) {
27031
27047
  timer.unref?.();
27032
27048
  lineWaiters.push((value) => {
27033
27049
  clearTimeout(timer);
27034
- resolve18(value);
27050
+ resolve19(value);
27035
27051
  });
27036
27052
  });
27037
27053
  if (protocolFailure) throw protocolFailure;
@@ -27044,8 +27060,8 @@ async function createWindowsJobContainment(pid, options) {
27044
27060
  }
27045
27061
  const stopped = await Promise.race([
27046
27062
  exited.then(() => true),
27047
- new Promise((resolve18) => {
27048
- const timer = setTimeout(() => resolve18(false), timeoutMs);
27063
+ new Promise((resolve19) => {
27064
+ const timer = setTimeout(() => resolve19(false), timeoutMs);
27049
27065
  timer.unref?.();
27050
27066
  })
27051
27067
  ]);
@@ -27104,7 +27120,7 @@ async function awaitWindowsContainmentGate(env = process.env, input = process.st
27104
27120
  if (nonce === void 0) return true;
27105
27121
  if (!SAFE_NONCE2.test(nonce)) return false;
27106
27122
  const expected = windowsContainmentGate(nonce).trimEnd();
27107
- return new Promise((resolve18) => {
27123
+ return new Promise((resolve19) => {
27108
27124
  let pending = Buffer.alloc(0);
27109
27125
  let settled = false;
27110
27126
  const finish = (result) => {
@@ -27115,7 +27131,7 @@ async function awaitWindowsContainmentGate(env = process.env, input = process.st
27115
27131
  input.off("end", onEnd);
27116
27132
  input.off("error", onEnd);
27117
27133
  if (result) input.pause();
27118
- resolve18(result);
27134
+ resolve19(result);
27119
27135
  };
27120
27136
  const onData = (chunk) => {
27121
27137
  pending = Buffer.concat([pending, chunk]);
@@ -28220,7 +28236,7 @@ async function installRelease(version2, options = {}) {
28220
28236
  }) : Promise.resolve(null);
28221
28237
  const timeoutMs = options.timeoutMs ?? INSTALL_TIMEOUT_MS2;
28222
28238
  const outcome = { code: null, signal: null, timedOut: false, spawnError: null };
28223
- const installed = await new Promise((resolve18, reject3) => {
28239
+ const installed = await new Promise((resolve19, reject3) => {
28224
28240
  let finished = false;
28225
28241
  let cleanupStarted = false;
28226
28242
  let exitObserved = false;
@@ -28236,7 +28252,7 @@ async function installRelease(version2, options = {}) {
28236
28252
  finished = true;
28237
28253
  clearTimeout(timer);
28238
28254
  options.signal?.removeEventListener("abort", requestCleanup);
28239
- resolve18(result);
28255
+ resolve19(result);
28240
28256
  };
28241
28257
  const requestCleanup = () => {
28242
28258
  if (cleanupStarted || finished) return;
@@ -28601,11 +28617,11 @@ async function runWorkerCompatibilityProxy(env = process.env, argv = process.arg
28601
28617
  child.stdin?.on("error", () => {
28602
28618
  });
28603
28619
  process.stdin.pipe(child.stdin);
28604
- return new Promise((resolve18) => {
28605
- child.once("error", () => resolve18(1));
28620
+ return new Promise((resolve19) => {
28621
+ child.once("error", () => resolve19(1));
28606
28622
  child.once("exit", (code) => {
28607
28623
  process.stdin.unpipe(child.stdin);
28608
- resolve18(code ?? 1);
28624
+ resolve19(code ?? 1);
28609
28625
  });
28610
28626
  });
28611
28627
  }
@@ -28685,11 +28701,11 @@ async function launchHostSupervisor(options = {}) {
28685
28701
  const waitOrStop = async (ms) => {
28686
28702
  if (stopping) return false;
28687
28703
  if (!customDelay) {
28688
- await new Promise((resolve18) => {
28704
+ await new Promise((resolve19) => {
28689
28705
  const finish = () => {
28690
28706
  clearTimeout(timer);
28691
28707
  stopController.signal.removeEventListener("abort", finish);
28692
- resolve18();
28708
+ resolve19();
28693
28709
  };
28694
28710
  const timer = setTimeout(finish, ms);
28695
28711
  stopController.signal.addEventListener("abort", finish, { once: true });
@@ -28697,8 +28713,8 @@ async function launchHostSupervisor(options = {}) {
28697
28713
  return !stopping;
28698
28714
  }
28699
28715
  let finishStop;
28700
- const stopped = new Promise((resolve18) => {
28701
- finishStop = () => resolve18();
28716
+ const stopped = new Promise((resolve19) => {
28717
+ finishStop = () => resolve19();
28702
28718
  stopController.signal.addEventListener("abort", finishStop, { once: true });
28703
28719
  });
28704
28720
  await Promise.race([customDelay(ms), stopped]);
@@ -28828,19 +28844,19 @@ async function launchHostSupervisor(options = {}) {
28828
28844
  child = spawnSupervisor(entry, version2, ownershipDirectory, containmentGateNonce);
28829
28845
  const launchedSupervisor = child;
28830
28846
  let resolveChildExited;
28831
- const childExited = new Promise((resolve18) => {
28832
- resolveChildExited = resolve18;
28847
+ const childExited = new Promise((resolve19) => {
28848
+ resolveChildExited = resolve19;
28833
28849
  });
28834
28850
  const supervisorContainmentAbort = new AbortController();
28835
28851
  void childExited.then(() => supervisorContainmentAbort.abort());
28836
28852
  const outcomePromise = new Promise(
28837
- (resolve18) => {
28853
+ (resolve19) => {
28838
28854
  let observed = false;
28839
28855
  const finish = (code, signal) => {
28840
28856
  if (observed) return;
28841
28857
  observed = true;
28842
28858
  resolveChildExited();
28843
- resolve18({ code, signal });
28859
+ resolve19({ code, signal });
28844
28860
  };
28845
28861
  child.once("error", () => finish(1, null));
28846
28862
  child.once("exit", finish);
@@ -28861,12 +28877,12 @@ async function launchHostSupervisor(options = {}) {
28861
28877
  if (!supervisorContainment || !launchedSupervisor.stdin) {
28862
28878
  throw new Error("supervisor Job Object gate is unavailable");
28863
28879
  }
28864
- await new Promise((resolve18, reject3) => {
28880
+ await new Promise((resolve19, reject3) => {
28865
28881
  launchedSupervisor.stdin.write(
28866
28882
  windowsContainmentGate(containmentGateNonce),
28867
28883
  (error52) => {
28868
28884
  if (error52) reject3(error52);
28869
- else resolve18();
28885
+ else resolve19();
28870
28886
  }
28871
28887
  );
28872
28888
  });
@@ -29014,19 +29030,19 @@ async function superviseHost(options = {}) {
29014
29030
  }
29015
29031
  }
29016
29032
  let announceShutdown;
29017
- const shutdownAnnounced = new Promise((resolve18) => {
29018
- announceShutdown = resolve18;
29033
+ const shutdownAnnounced = new Promise((resolve19) => {
29034
+ announceShutdown = resolve19;
29019
29035
  });
29020
29036
  const attempted = /* @__PURE__ */ new Set();
29021
29037
  let unsatisfiableUpdates = 0;
29022
29038
  const waitOrShutdown = async (ms) => {
29023
29039
  if (shuttingDown2) return false;
29024
29040
  if (!customDelay) {
29025
- await new Promise((resolve18) => {
29041
+ await new Promise((resolve19) => {
29026
29042
  const finish = () => {
29027
29043
  clearTimeout(timer);
29028
29044
  shutdownController.signal.removeEventListener("abort", finish);
29029
- resolve18();
29045
+ resolve19();
29030
29046
  };
29031
29047
  const timer = setTimeout(finish, ms);
29032
29048
  shutdownController.signal.addEventListener("abort", finish, { once: true });
@@ -29176,19 +29192,19 @@ async function superviseHost(options = {}) {
29176
29192
  const watchedChild = child;
29177
29193
  const workerStderr = captureWorkerStderr(watchedChild);
29178
29194
  let resolveChildExited;
29179
- const childExited = new Promise((resolve18) => {
29180
- resolveChildExited = resolve18;
29195
+ const childExited = new Promise((resolve19) => {
29196
+ resolveChildExited = resolve19;
29181
29197
  });
29182
29198
  const workerContainmentAbort = new AbortController();
29183
29199
  void childExited.then(() => workerContainmentAbort.abort());
29184
29200
  const outcomePromise = new Promise(
29185
- (resolve18) => {
29201
+ (resolve19) => {
29186
29202
  let observed = false;
29187
29203
  const finish = (result) => {
29188
29204
  if (observed) return;
29189
29205
  observed = true;
29190
29206
  resolveChildExited();
29191
- resolve18(result);
29207
+ resolve19(result);
29192
29208
  };
29193
29209
  watchedChild.once("error", () => finish({ code: 1, signal: null }));
29194
29210
  watchedChild.once(
@@ -29210,10 +29226,10 @@ async function superviseHost(options = {}) {
29210
29226
  if (!workerContainment || !watchedChild.stdin) {
29211
29227
  throw new Error("worker Job Object gate is unavailable");
29212
29228
  }
29213
- await new Promise((resolve18, reject3) => {
29229
+ await new Promise((resolve19, reject3) => {
29214
29230
  watchedChild.stdin.write(windowsContainmentGate(containmentGateNonce), (error52) => {
29215
29231
  if (error52) reject3(error52);
29216
- else resolve18();
29232
+ else resolve19();
29217
29233
  });
29218
29234
  });
29219
29235
  }
@@ -29620,7 +29636,7 @@ function watchParentPipe(pipe2, onStop) {
29620
29636
  }
29621
29637
 
29622
29638
  // src/index.ts
29623
- import { homedir as homedir16, hostname as hostname3 } from "node:os";
29639
+ import { homedir as homedir17, hostname as hostname3 } from "node:os";
29624
29640
 
29625
29641
  // src/hardware.ts
29626
29642
  import { existsSync } from "node:fs";
@@ -30391,7 +30407,7 @@ async function loadPlaywright() {
30391
30407
  }
30392
30408
  async function installChromium() {
30393
30409
  const cliPath = join12(playwrightCoreRoot, "cli.js");
30394
- await new Promise((resolve18, reject3) => {
30410
+ await new Promise((resolve19, reject3) => {
30395
30411
  const child = spawn7(process.execPath, [cliPath, "install", "chromium"], {
30396
30412
  env: process.env,
30397
30413
  stdio: ["ignore", "inherit", "inherit"],
@@ -30406,7 +30422,7 @@ async function installChromium() {
30406
30422
  settled = true;
30407
30423
  clearTimeout(timeout);
30408
30424
  if (error52) reject3(error52);
30409
- else resolve18();
30425
+ else resolve19();
30410
30426
  };
30411
30427
  const timeout = setTimeout(() => {
30412
30428
  child.kill();
@@ -34210,8 +34226,8 @@ async function runGit(input, args, env) {
34210
34226
  let settled = false;
34211
34227
  let stopping = false;
34212
34228
  let resolveExited;
34213
- const exited = new Promise((resolve18) => {
34214
- resolveExited = resolve18;
34229
+ const exited = new Promise((resolve19) => {
34230
+ resolveExited = resolve19;
34215
34231
  });
34216
34232
  child.once("exit", resolveExited);
34217
34233
  const cleanup = () => {
@@ -37021,8 +37037,8 @@ var linearToolPackFactory = {
37021
37037
  async create(grant, context) {
37022
37038
  let resolveCancelled;
37023
37039
  let closed = false;
37024
- const cancelled = new Promise((resolve18) => {
37025
- resolveCancelled = resolve18;
37040
+ const cancelled = new Promise((resolve19) => {
37041
+ resolveCancelled = resolve19;
37026
37042
  });
37027
37043
  const cancel = () => {
37028
37044
  if (closed) return;
@@ -38058,7 +38074,7 @@ function createAskUserServer() {
38058
38074
  let server;
38059
38075
  let listening;
38060
38076
  function ensureListening() {
38061
- listening ??= new Promise((resolve18, reject3) => {
38077
+ listening ??= new Promise((resolve19, reject3) => {
38062
38078
  server = createServer2((req, res) => {
38063
38079
  res.on("error", () => {
38064
38080
  });
@@ -38074,7 +38090,7 @@ function createAskUserServer() {
38074
38090
  server.on("error", reject3);
38075
38091
  server.listen(0, "127.0.0.1", () => {
38076
38092
  const address = server.address();
38077
- if (address && typeof address === "object") resolve18(address.port);
38093
+ if (address && typeof address === "object") resolve19(address.port);
38078
38094
  else reject3(new Error("ask_user server failed to bind"));
38079
38095
  });
38080
38096
  server.unref();
@@ -40630,7 +40646,7 @@ function runCliProcess(options) {
40630
40646
  usage: { inputTokens: 0, outputTokens: 0 }
40631
40647
  });
40632
40648
  }
40633
- return new Promise((resolve18) => {
40649
+ return new Promise((resolve19) => {
40634
40650
  const platform = options.platform ?? process.platform;
40635
40651
  const containmentGateNonce = options.guardian && platform === "win32" ? randomUUID11() : void 0;
40636
40652
  const child = options.guardian ? spawn10(
@@ -40692,7 +40708,7 @@ function runCliProcess(options) {
40692
40708
  clearInterval(timer);
40693
40709
  unregisterFollowUps?.();
40694
40710
  parser.stop?.();
40695
- resolve18(result);
40711
+ resolve19(result);
40696
40712
  };
40697
40713
  const terminate = (result) => {
40698
40714
  if (settled || forcedResult) return;
@@ -41038,7 +41054,7 @@ async function readCodexSessionRuntime(input) {
41038
41054
  }
41039
41055
  var codexCatalogCache = /* @__PURE__ */ new Map();
41040
41056
  async function loadCodexModelCatalog(command, prefixArgs, env) {
41041
- const output = await new Promise((resolve18) => {
41057
+ const output = await new Promise((resolve19) => {
41042
41058
  const child = spawnCli(command, [...prefixArgs, "debug", "models"], {
41043
41059
  stdio: ["ignore", "pipe", "ignore"],
41044
41060
  windowsHide: true,
@@ -41053,7 +41069,7 @@ async function loadCodexModelCatalog(command, prefixArgs, env) {
41053
41069
  if (settled) return;
41054
41070
  settled = true;
41055
41071
  clearTimeout(timer);
41056
- resolve18(value);
41072
+ resolve19(value);
41057
41073
  };
41058
41074
  const timer = setTimeout(() => {
41059
41075
  child.kill();
@@ -41158,8 +41174,8 @@ function createRuntimeReporter(input, sessionId) {
41158
41174
  var EFFORT_READ_ATTEMPTS = 5;
41159
41175
  var EFFORT_READ_INTERVAL_MS = 3e3;
41160
41176
  function delay2(ms) {
41161
- return new Promise((resolve18) => {
41162
- const timer = setTimeout(resolve18, ms);
41177
+ return new Promise((resolve19) => {
41178
+ const timer = setTimeout(resolve19, ms);
41163
41179
  timer.unref?.();
41164
41180
  });
41165
41181
  }
@@ -41246,10 +41262,10 @@ function createClaudeLiveParser(onStream, onSessionModel) {
41246
41262
  },
41247
41263
  async steer(followUp) {
41248
41264
  if (!write) return false;
41249
- return await new Promise((resolve18) => {
41250
- acknowledgements.set(followUp.inputId, resolve18);
41265
+ return await new Promise((resolve19) => {
41266
+ acknowledgements.set(followUp.inputId, resolve19);
41251
41267
  void write(input(followUp.inputId, followUp.text)).catch(() => {
41252
- if (acknowledgements.delete(followUp.inputId)) resolve18(false);
41268
+ if (acknowledgements.delete(followUp.inputId)) resolve19(false);
41253
41269
  });
41254
41270
  });
41255
41271
  },
@@ -41565,8 +41581,8 @@ ${value}` : value;
41565
41581
  var RUNTIME_READ_ATTEMPTS = 5;
41566
41582
  var RUNTIME_READ_INTERVAL_MS = 2e3;
41567
41583
  function delay3(ms) {
41568
- return new Promise((resolve18) => {
41569
- const timer = setTimeout(resolve18, ms);
41584
+ return new Promise((resolve19) => {
41585
+ const timer = setTimeout(resolve19, ms);
41570
41586
  timer.unref?.();
41571
41587
  });
41572
41588
  }
@@ -41605,7 +41621,7 @@ function createCodexAppServerParser(onStream, options) {
41605
41621
  const turnReadyWaiters = /* @__PURE__ */ new Set();
41606
41622
  const usage = () => ({ inputTokens, outputTokens });
41607
41623
  const settleTurnReadiness = (ready) => {
41608
- for (const resolve18 of turnReadyWaiters) resolve18(ready);
41624
+ for (const resolve19 of turnReadyWaiters) resolve19(ready);
41609
41625
  turnReadyWaiters.clear();
41610
41626
  };
41611
41627
  const send = async (message) => {
@@ -41786,12 +41802,12 @@ function createCodexAppServerParser(onStream, options) {
41786
41802
  async steer(input) {
41787
41803
  if (stopped) return false;
41788
41804
  if (!activeTurnId) {
41789
- const ready = await new Promise((resolve18) => turnReadyWaiters.add(resolve18));
41805
+ const ready = await new Promise((resolve19) => turnReadyWaiters.add(resolve19));
41790
41806
  if (!ready || stopped) return false;
41791
41807
  }
41792
41808
  if (!threadId || !activeTurnId) return false;
41793
- return await new Promise((resolve18) => {
41794
- steerWaiters.set(input.inputId, resolve18);
41809
+ return await new Promise((resolve19) => {
41810
+ steerWaiters.set(input.inputId, resolve19);
41795
41811
  void send({
41796
41812
  id: `steer:${input.inputId}`,
41797
41813
  method: "turn/steer",
@@ -41802,7 +41818,7 @@ function createCodexAppServerParser(onStream, options) {
41802
41818
  clientUserMessageId: input.inputId
41803
41819
  }
41804
41820
  }).catch(() => {
41805
- if (steerWaiters.delete(input.inputId)) resolve18(false);
41821
+ if (steerWaiters.delete(input.inputId)) resolve19(false);
41806
41822
  });
41807
41823
  });
41808
41824
  },
@@ -41810,7 +41826,7 @@ function createCodexAppServerParser(onStream, options) {
41810
41826
  stopped = true;
41811
41827
  write = null;
41812
41828
  settleTurnReadiness(false);
41813
- for (const resolve18 of steerWaiters.values()) resolve18(false);
41829
+ for (const resolve19 of steerWaiters.values()) resolve19(false);
41814
41830
  steerWaiters.clear();
41815
41831
  },
41816
41832
  push(chunk) {
@@ -42230,7 +42246,7 @@ function parseAuth(result) {
42230
42246
  return "unknown";
42231
42247
  }
42232
42248
  function run2(command, args) {
42233
- return new Promise((resolve18) => {
42249
+ return new Promise((resolve19) => {
42234
42250
  const child = spawnCli(command, args, {
42235
42251
  stdio: ["ignore", "pipe", "pipe"],
42236
42252
  windowsHide: true
@@ -42246,7 +42262,7 @@ function run2(command, args) {
42246
42262
  if (settled) return;
42247
42263
  settled = true;
42248
42264
  clearTimeout(timeout);
42249
- resolve18(result);
42265
+ resolve19(result);
42250
42266
  };
42251
42267
  const timeout = setTimeout(() => {
42252
42268
  child.kill();
@@ -42260,9 +42276,46 @@ function run2(command, args) {
42260
42276
  // src/linux-service.ts
42261
42277
  import { spawn as spawn12 } from "node:child_process";
42262
42278
  import { constants as constants2 } from "node:fs";
42263
- import { access as access4, chmod as chmod7, mkdir as mkdir14, open as open7, rename as rename6, rm as rm10 } from "node:fs/promises";
42264
- import { homedir as homedir10, userInfo } from "node:os";
42265
- import { basename as basename4, dirname as dirname11, join as join21, relative as relative9, resolve as resolve12, sep as sep5 } from "node:path";
42279
+ import { access as access5, chmod as chmod8, mkdir as mkdir15, open as open7, rename as rename7, rm as rm11 } from "node:fs/promises";
42280
+ import { homedir as homedir11, userInfo } from "node:os";
42281
+ import { basename as basename4, dirname as dirname11, join as join22, relative as relative9, resolve as resolve13, sep as sep6 } from "node:path";
42282
+
42283
+ // src/service-runtime.ts
42284
+ import { access as access4, chmod as chmod7, copyFile, mkdir as mkdir14, rename as rename6, rm as rm10 } from "node:fs/promises";
42285
+ import { homedir as homedir10 } from "node:os";
42286
+ import { join as join21, resolve as resolve12, sep as sep5 } from "node:path";
42287
+ async function ensureDurableServiceNode(options = {}) {
42288
+ const execPath = resolve12(options.execPath ?? process.execPath);
42289
+ const home = options.home ?? homedir10();
42290
+ const platform = options.platform ?? process.platform;
42291
+ const version2 = options.nodeVersion ?? process.version;
42292
+ if (!/^v?[0-9A-Za-z.-]+$/.test(version2)) {
42293
+ throw new Error("the Node runtime version is not a safe directory name");
42294
+ }
42295
+ const zixtRoot = resolve12(home, ".zixt");
42296
+ if (execPath === zixtRoot || execPath.startsWith(zixtRoot + sep5)) return execPath;
42297
+ const directory = join21(zixtRoot, "runtime", `node-${version2}`);
42298
+ const destination = join21(directory, platform === "win32" ? "node.exe" : "node");
42299
+ const alreadyCopied = await access4(destination).then(
42300
+ () => true,
42301
+ () => false
42302
+ );
42303
+ if (alreadyCopied) return destination;
42304
+ await mkdir14(directory, { recursive: true, mode: 448 });
42305
+ const temporary = `${destination}.${process.pid}.${crypto.randomUUID()}.tmp`;
42306
+ try {
42307
+ await copyFile(execPath, temporary);
42308
+ await chmod7(temporary, 493);
42309
+ await rename6(temporary, destination);
42310
+ } catch (error52) {
42311
+ await rm10(temporary, { force: true }).catch(() => void 0);
42312
+ throw error52;
42313
+ }
42314
+ await options.syncDirectory?.(directory);
42315
+ return destination;
42316
+ }
42317
+
42318
+ // src/linux-service.ts
42266
42319
  var SERVICE_NAME = "zixt-host.service";
42267
42320
  var SYSTEM_SERVICE_COMMAND_TIMEOUT_MS = 7e4;
42268
42321
  var SERVICE_STABILITY_DELAY_MS = 2e3;
@@ -42290,7 +42343,7 @@ function boundedAppend(current, chunk) {
42290
42343
  }
42291
42344
  async function defaultRunCommand(command, args) {
42292
42345
  const commandEnvironment3 = systemServiceCommandEnvironment();
42293
- return new Promise((resolve18) => {
42346
+ return new Promise((resolve19) => {
42294
42347
  const child = spawn12(command, [...args], {
42295
42348
  stdio: ["ignore", "pipe", "pipe"],
42296
42349
  env: commandEnvironment3,
@@ -42304,7 +42357,7 @@ async function defaultRunCommand(command, args) {
42304
42357
  if (settled) return;
42305
42358
  settled = true;
42306
42359
  if (timer) clearTimeout(timer);
42307
- resolve18(result);
42360
+ resolve19(result);
42308
42361
  };
42309
42362
  child.stdout?.on("data", (chunk) => {
42310
42363
  stdout = boundedAppend(stdout, chunk);
@@ -42324,7 +42377,7 @@ async function defaultRunCommand(command, args) {
42324
42377
  }
42325
42378
  async function defaultResolveCommand(name) {
42326
42379
  for (const candidate of [`/usr/bin/${name}`, `/bin/${name}`]) {
42327
- if (await access4(candidate, constants2.X_OK).then(
42380
+ if (await access5(candidate, constants2.X_OK).then(
42328
42381
  () => true,
42329
42382
  () => false
42330
42383
  )) {
@@ -42363,33 +42416,33 @@ async function defaultSyncDirectory(path) {
42363
42416
  }
42364
42417
  }
42365
42418
  async function ensureDirectory(path, mode, syncDirectory8) {
42366
- const firstCreated = await mkdir14(path, { recursive: true, mode });
42419
+ const firstCreated = await mkdir15(path, { recursive: true, mode });
42367
42420
  if (!firstCreated) return;
42368
- const first = resolve12(firstCreated);
42369
- const target = resolve12(path);
42421
+ const first = resolve13(firstCreated);
42422
+ const target = resolve13(path);
42370
42423
  await syncDirectory8(dirname11(first));
42371
42424
  let current = first;
42372
42425
  const descendants = relative9(first, target);
42373
- for (const part of descendants ? descendants.split(sep5) : []) {
42426
+ for (const part of descendants ? descendants.split(sep6) : []) {
42374
42427
  await syncDirectory8(current);
42375
- current = join21(current, part);
42428
+ current = join22(current, part);
42376
42429
  }
42377
42430
  }
42378
42431
  async function replacePrivateFile(path, contents, mode, syncDirectory8) {
42379
42432
  const parent = dirname11(path);
42380
42433
  await ensureDirectory(parent, 448, syncDirectory8);
42381
- const temporary = join21(parent, `.${basename4(path)}.${process.pid}.${crypto.randomUUID()}.tmp`);
42434
+ const temporary = join22(parent, `.${basename4(path)}.${process.pid}.${crypto.randomUUID()}.tmp`);
42382
42435
  const handle = await open7(temporary, "wx", mode);
42383
42436
  try {
42384
42437
  await handle.writeFile(contents, "utf8");
42385
42438
  await handle.sync();
42386
42439
  await handle.close();
42387
- await rename6(temporary, path);
42388
- await chmod7(path, mode);
42440
+ await rename7(temporary, path);
42441
+ await chmod8(path, mode);
42389
42442
  await syncDirectory8(parent);
42390
42443
  } catch (error52) {
42391
42444
  await handle.close().catch(() => void 0);
42392
- await rm10(temporary, { force: true }).catch(() => void 0);
42445
+ await rm11(temporary, { force: true }).catch(() => void 0);
42393
42446
  throw error52;
42394
42447
  }
42395
42448
  }
@@ -42422,7 +42475,7 @@ async function installLinuxService(options) {
42422
42475
  throw new Error("Linux automatic startup is available only on Linux.");
42423
42476
  }
42424
42477
  const env = options.env ?? process.env;
42425
- const home = options.home ?? homedir10();
42478
+ const home = options.home ?? homedir11();
42426
42479
  const username = oneLine(options.username ?? userInfo().username, "user name");
42427
42480
  const token2 = oneLine(options.token, "pairing code");
42428
42481
  const path = oneLine(
@@ -42430,17 +42483,17 @@ async function installLinuxService(options) {
42430
42483
  "command search path"
42431
42484
  );
42432
42485
  const cloudUrl = options.cloudUrl ? oneLine(options.cloudUrl, "Zixt Cloud address") : void 0;
42433
- const xdgConfigHome = env.XDG_CONFIG_HOME ? oneLine(env.XDG_CONFIG_HOME, "Linux configuration path") : join21(home, ".config");
42434
- const configRoot = options.serviceConfigRoot ?? join21(xdgConfigHome, "zixt");
42435
- const unitRoot = options.userUnitRoot ?? join21(xdgConfigHome, "systemd", "user");
42436
- const environmentPath = join21(configRoot, "host.env");
42437
- const unitPath = join21(unitRoot, SERVICE_NAME);
42486
+ const xdgConfigHome = env.XDG_CONFIG_HOME ? oneLine(env.XDG_CONFIG_HOME, "Linux configuration path") : join22(home, ".config");
42487
+ const configRoot = options.serviceConfigRoot ?? join22(xdgConfigHome, "zixt");
42488
+ const unitRoot = options.userUnitRoot ?? join22(xdgConfigHome, "systemd", "user");
42489
+ const environmentPath = join22(configRoot, "host.env");
42490
+ const unitPath = join22(unitRoot, SERVICE_NAME);
42438
42491
  const installVersion = options.installVersion ?? ((version2, onFailure) => installRelease(version2, onFailure ? { onFailure } : {}));
42439
42492
  const activateVersion = options.activateVersion ?? (options.installVersion ? async (entry) => entry : activateInstalledRelease);
42440
42493
  const resolveCommand = options.resolveCommand ?? defaultResolveCommand;
42441
42494
  const run3 = options.runCommand ?? defaultRunCommand;
42442
42495
  const syncDirectory8 = options.syncDirectory ?? defaultSyncDirectory;
42443
- const stabilityDelay = options.delay ?? ((ms) => new Promise((resolve18) => setTimeout(resolve18, ms)));
42496
+ const stabilityDelay = options.delay ?? ((ms) => new Promise((resolve19) => setTimeout(resolve19, ms)));
42444
42497
  const [systemctl, loginctl] = await Promise.all([
42445
42498
  resolveCommand("systemctl"),
42446
42499
  resolveCommand("loginctl")
@@ -42474,7 +42527,7 @@ async function installLinuxService(options) {
42474
42527
  }
42475
42528
  }
42476
42529
  await ensureDirectory(configRoot, 448, syncDirectory8);
42477
- await chmod7(configRoot, 448);
42530
+ await chmod8(configRoot, 448);
42478
42531
  const serviceEnvironment = [
42479
42532
  `ZIXT_HOST_TOKEN=${systemdEnvironmentValue(token2)}`,
42480
42533
  ...cloudUrl ? [`ZIXT_CLOUD_URL=${systemdEnvironmentValue(cloudUrl)}`] : [],
@@ -42489,6 +42542,7 @@ async function installLinuxService(options) {
42489
42542
  ""
42490
42543
  ].join("\n");
42491
42544
  await replacePrivateFile(environmentPath, serviceEnvironment, 384, syncDirectory8);
42545
+ const serviceNode = options.serviceNode ?? await ensureDurableServiceNode({ home, syncDirectory: syncDirectory8 });
42492
42546
  const unit = [
42493
42547
  "[Unit]",
42494
42548
  "Description=Zixt Host",
@@ -42498,7 +42552,7 @@ async function installLinuxService(options) {
42498
42552
  // Node, so a missing/corrupt release cannot masquerade as an active Host.
42499
42553
  "Type=exec",
42500
42554
  `EnvironmentFile=${systemdDirectivePath(environmentPath)}`,
42501
- `ExecStart=${systemdUnitValue(process.execPath)} ${systemdUnitValue(currentEntry)}`,
42555
+ `ExecStart=${systemdUnitValue(serviceNode)} ${systemdUnitValue(currentEntry)}`,
42502
42556
  "Restart=on-failure",
42503
42557
  "RestartPreventExitStatus=64",
42504
42558
  "RestartSec=5s",
@@ -42563,9 +42617,9 @@ async function installLinuxService(options) {
42563
42617
  // src/macos-service.ts
42564
42618
  import { spawn as spawn13 } from "node:child_process";
42565
42619
  import { constants as constants3 } from "node:fs";
42566
- import { access as access5, chmod as chmod8, mkdir as mkdir15, open as open8, rename as rename7, rm as rm11 } from "node:fs/promises";
42567
- import { homedir as homedir11, userInfo as userInfo2 } from "node:os";
42568
- import { basename as basename5, dirname as dirname12, join as join22, relative as relative10, resolve as resolve13, sep as sep6 } from "node:path";
42620
+ import { access as access6, chmod as chmod9, mkdir as mkdir16, open as open8, rename as rename8, rm as rm12 } from "node:fs/promises";
42621
+ import { homedir as homedir12, userInfo as userInfo2 } from "node:os";
42622
+ import { basename as basename5, dirname as dirname12, join as join23, relative as relative10, resolve as resolve14, sep as sep7 } from "node:path";
42569
42623
  var LAUNCH_AGENT_LABEL = "ai.zixt.host";
42570
42624
  var SERVICE_STABILITY_DELAY_MS2 = 2e3;
42571
42625
  var COMMAND_TIMEOUT_MS2 = 7e4;
@@ -42589,32 +42643,32 @@ async function syncDirectory4(path) {
42589
42643
  }
42590
42644
  }
42591
42645
  async function ensureDirectory2(path, sync) {
42592
- const firstCreated = await mkdir15(path, { recursive: true, mode: 448 });
42646
+ const firstCreated = await mkdir16(path, { recursive: true, mode: 448 });
42593
42647
  if (!firstCreated) return;
42594
- const first = resolve13(firstCreated);
42595
- const target = resolve13(path);
42648
+ const first = resolve14(firstCreated);
42649
+ const target = resolve14(path);
42596
42650
  await sync(dirname12(first));
42597
42651
  let current = first;
42598
- for (const part of relative10(first, target).split(sep6).filter(Boolean)) {
42652
+ for (const part of relative10(first, target).split(sep7).filter(Boolean)) {
42599
42653
  await sync(current);
42600
- current = join22(current, part);
42654
+ current = join23(current, part);
42601
42655
  }
42602
42656
  }
42603
42657
  async function replacePrivateFile2(path, contents, mode, sync) {
42604
42658
  const parent = dirname12(path);
42605
42659
  await ensureDirectory2(parent, sync);
42606
- const temporary = join22(parent, `.${basename5(path)}.${process.pid}.${crypto.randomUUID()}.tmp`);
42660
+ const temporary = join23(parent, `.${basename5(path)}.${process.pid}.${crypto.randomUUID()}.tmp`);
42607
42661
  const handle = await open8(temporary, "wx", mode);
42608
42662
  try {
42609
42663
  await handle.writeFile(contents, "utf8");
42610
42664
  await handle.sync();
42611
42665
  await handle.close();
42612
- await rename7(temporary, path);
42613
- await chmod8(path, mode);
42666
+ await rename8(temporary, path);
42667
+ await chmod9(path, mode);
42614
42668
  await sync(parent);
42615
42669
  } catch (error52) {
42616
42670
  await handle.close().catch(() => void 0);
42617
- await rm11(temporary, { force: true }).catch(() => void 0);
42671
+ await rm12(temporary, { force: true }).catch(() => void 0);
42618
42672
  throw error52;
42619
42673
  }
42620
42674
  }
@@ -42657,7 +42711,7 @@ async function defaultRunCommand2(command, args, env) {
42657
42711
  }
42658
42712
  async function defaultResolveCommand2() {
42659
42713
  for (const candidate of ["/bin/launchctl", "/usr/bin/launchctl"]) {
42660
- if (await access5(candidate, constants3.X_OK).then(
42714
+ if (await access6(candidate, constants3.X_OK).then(
42661
42715
  () => true,
42662
42716
  () => false
42663
42717
  ))
@@ -42669,13 +42723,13 @@ function commandFailure2(label, result) {
42669
42723
  const detail = (result.stderr || result.stdout).trim().slice(-240);
42670
42724
  return new Error(`${label} failed${detail ? `: ${detail}` : ""}`);
42671
42725
  }
42672
- function launcherSource(configPath, home, entry) {
42726
+ function launcherSource(configPath, home, node, entry) {
42673
42727
  return `#!/bin/sh
42674
42728
  set -a
42675
42729
  . ${shellValue(configPath)}
42676
42730
  set +a
42677
42731
  cd ${shellValue(home)} || exit 64
42678
- exec ${shellValue(process.execPath)} ${shellValue(entry)}
42732
+ exec ${shellValue(node)} ${shellValue(entry)}
42679
42733
  `;
42680
42734
  }
42681
42735
  function parseLaunchdStatus(output) {
@@ -42691,7 +42745,7 @@ async function installMacosService(options) {
42691
42745
  throw new Error("macOS automatic startup is available only on macOS.");
42692
42746
  }
42693
42747
  const env = options.env ?? process.env;
42694
- const home = options.home ?? homedir11();
42748
+ const home = options.home ?? homedir12();
42695
42749
  const uid = options.uid ?? userInfo2().uid;
42696
42750
  if (!Number.isSafeInteger(uid) || uid < 0) throw new Error("macOS user id is invalid.");
42697
42751
  const token2 = oneLine2(options.token, "pairing code");
@@ -42700,14 +42754,14 @@ async function installMacosService(options) {
42700
42754
  options.path ?? env.PATH ?? "/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin",
42701
42755
  "command search path"
42702
42756
  );
42703
- const configRoot = options.configRoot ?? join22(home, "Library", "Application Support", "Zixt");
42704
- const launchAgentsRoot = options.launchAgentsRoot ?? join22(home, "Library", "LaunchAgents");
42705
- const logRoot = options.logRoot ?? join22(home, "Library", "Logs", "Zixt");
42706
- const configPath = join22(configRoot, "host.env");
42707
- const launcherPath = join22(configRoot, "host-launcher.sh");
42708
- const plistPath = join22(launchAgentsRoot, `${LAUNCH_AGENT_LABEL}.plist`);
42709
- const stdoutPath = join22(logRoot, "host.log");
42710
- const stderrPath = join22(logRoot, "host-error.log");
42757
+ const configRoot = options.configRoot ?? join23(home, "Library", "Application Support", "Zixt");
42758
+ const launchAgentsRoot = options.launchAgentsRoot ?? join23(home, "Library", "LaunchAgents");
42759
+ const logRoot = options.logRoot ?? join23(home, "Library", "Logs", "Zixt");
42760
+ const configPath = join23(configRoot, "host.env");
42761
+ const launcherPath = join23(configRoot, "host-launcher.sh");
42762
+ const plistPath = join23(launchAgentsRoot, `${LAUNCH_AGENT_LABEL}.plist`);
42763
+ const stdoutPath = join23(logRoot, "host.log");
42764
+ const stderrPath = join23(logRoot, "host-error.log");
42711
42765
  const installVersion = options.installVersion ?? ((version2, onFailure) => installRelease(version2, onFailure ? { onFailure } : {}));
42712
42766
  const activateVersion = options.activateVersion ?? (options.installVersion ? async (entry) => entry : (entry) => activateInstalledRelease(entry));
42713
42767
  const resolveCommand = options.resolveCommand ?? (async () => defaultResolveCommand2());
@@ -42730,7 +42784,7 @@ async function installMacosService(options) {
42730
42784
  await ensureDirectory2(configRoot, sync);
42731
42785
  await ensureDirectory2(launchAgentsRoot, sync);
42732
42786
  await ensureDirectory2(logRoot, sync);
42733
- await chmod8(configRoot, 448);
42787
+ await chmod9(configRoot, 448);
42734
42788
  const serviceEnvironment = [
42735
42789
  `ZIXT_HOST_TOKEN=${shellValue(token2)}`,
42736
42790
  ...cloudUrl ? [`ZIXT_CLOUD_URL=${shellValue(cloudUrl)}`] : [],
@@ -42746,9 +42800,10 @@ async function installMacosService(options) {
42746
42800
  ""
42747
42801
  ].join("\n");
42748
42802
  await replacePrivateFile2(configPath, serviceEnvironment, 384, sync);
42803
+ const serviceNode = options.serviceNode ?? await ensureDurableServiceNode({ home, syncDirectory: sync });
42749
42804
  await replacePrivateFile2(
42750
42805
  launcherPath,
42751
- launcherSource(configPath, home, currentEntry),
42806
+ launcherSource(configPath, home, serviceNode, currentEntry),
42752
42807
  448,
42753
42808
  sync
42754
42809
  );
@@ -42804,9 +42859,9 @@ async function installMacosService(options) {
42804
42859
  // src/windows-service.ts
42805
42860
  import { spawn as spawn14 } from "node:child_process";
42806
42861
  import { constants as constants4 } from "node:fs";
42807
- import { access as access6, mkdir as mkdir16, open as open9, readFile as readFile11, rename as rename8, rm as rm12 } from "node:fs/promises";
42808
- import { homedir as homedir12 } from "node:os";
42809
- import { basename as basename6, dirname as dirname13, isAbsolute as isAbsolute18, join as join23, relative as relative11, resolve as resolve14, sep as sep7 } from "node:path";
42862
+ import { access as access7, mkdir as mkdir17, open as open9, readFile as readFile11, rename as rename9, rm as rm13 } from "node:fs/promises";
42863
+ import { homedir as homedir13 } from "node:os";
42864
+ import { basename as basename6, dirname as dirname13, isAbsolute as isAbsolute18, join as join24, relative as relative11, resolve as resolve15, sep as sep8 } from "node:path";
42810
42865
  var TASK_NAME = "Zixt Host";
42811
42866
  var COMMAND_TIMEOUT_MS3 = 7e4;
42812
42867
  var SERVICE_STABILITY_DELAY_MS3 = 2e3;
@@ -42832,31 +42887,31 @@ async function syncDirectory5(path) {
42832
42887
  }
42833
42888
  }
42834
42889
  async function ensureDirectory3(path, sync) {
42835
- const firstCreated = await mkdir16(path, { recursive: true, mode: 448 });
42890
+ const firstCreated = await mkdir17(path, { recursive: true, mode: 448 });
42836
42891
  if (!firstCreated) return;
42837
- const first = resolve14(firstCreated);
42838
- const target = resolve14(path);
42892
+ const first = resolve15(firstCreated);
42893
+ const target = resolve15(path);
42839
42894
  await sync(dirname13(first));
42840
42895
  let current = first;
42841
- for (const part of relative11(first, target).split(sep7).filter(Boolean)) {
42896
+ for (const part of relative11(first, target).split(sep8).filter(Boolean)) {
42842
42897
  await sync(current);
42843
- current = join23(current, part);
42898
+ current = join24(current, part);
42844
42899
  }
42845
42900
  }
42846
42901
  async function replacePrivateFile3(path, contents, sync, encoding = "utf8") {
42847
42902
  const parent = dirname13(path);
42848
42903
  await ensureDirectory3(parent, sync);
42849
- const temporary = join23(parent, `.${basename6(path)}.${process.pid}.${crypto.randomUUID()}.tmp`);
42904
+ const temporary = join24(parent, `.${basename6(path)}.${process.pid}.${crypto.randomUUID()}.tmp`);
42850
42905
  const handle = await open9(temporary, "wx", 384);
42851
42906
  try {
42852
42907
  await handle.writeFile(encoding === "utf16le" ? `\uFEFF${contents}` : contents, encoding);
42853
42908
  await handle.sync();
42854
42909
  await handle.close();
42855
- await rename8(temporary, path);
42910
+ await rename9(temporary, path);
42856
42911
  await sync(parent);
42857
42912
  } catch (error52) {
42858
42913
  await handle.close().catch(() => void 0);
42859
- await rm12(temporary, { force: true }).catch(() => void 0);
42914
+ await rm13(temporary, { force: true }).catch(() => void 0);
42860
42915
  throw error52;
42861
42916
  }
42862
42917
  }
@@ -42901,8 +42956,8 @@ async function runChild(command, args, env, input) {
42901
42956
  async function defaultResolveCommand3(name, env) {
42902
42957
  const root = env.SYSTEMROOT ?? env.WINDIR;
42903
42958
  if (!root || !isAbsolute18(root)) return null;
42904
- const candidate = name === "powershell" ? join23(root, "System32", "WindowsPowerShell", "v1.0", "powershell.exe") : join23(root, "System32", `${name}.exe`);
42905
- return access6(candidate, constants4.X_OK).then(
42959
+ const candidate = name === "powershell" ? join24(root, "System32", "WindowsPowerShell", "v1.0", "powershell.exe") : join24(root, "System32", `${name}.exe`);
42960
+ return access7(candidate, constants4.X_OK).then(
42906
42961
  () => candidate,
42907
42962
  () => null
42908
42963
  );
@@ -43044,7 +43099,7 @@ async function installWindowsService(options) {
43044
43099
  throw new Error("Windows automatic startup is available only on Windows.");
43045
43100
  }
43046
43101
  const env = options.env ?? process.env;
43047
- const home = options.home ?? homedir12();
43102
+ const home = options.home ?? homedir13();
43048
43103
  const localAppData = options.localAppData ?? env.LOCALAPPDATA;
43049
43104
  if (!localAppData || !isAbsolute18(localAppData)) {
43050
43105
  throw new Error("Windows local application data path is unavailable.");
@@ -43052,12 +43107,12 @@ async function installWindowsService(options) {
43052
43107
  const token2 = oneLine3(options.token, "pairing code");
43053
43108
  const cloudUrl = options.cloudUrl ? oneLine3(options.cloudUrl, "Zixt Cloud address") : void 0;
43054
43109
  const path = oneLine3(options.path ?? env.PATH ?? "", "command search path");
43055
- const configRoot = options.configRoot ?? join23(localAppData, "Zixt", "Host");
43056
- const configPath = join23(configRoot, "host.json");
43057
- const launcherPath = join23(configRoot, "host-launcher.ps1");
43058
- const launchShimPath = join23(configRoot, "host-launch.vbs");
43059
- const taskXmlPath = join23(configRoot, "host-task.xml");
43060
- const statusPath = join23(configRoot, "host-status.json");
43110
+ const configRoot = options.configRoot ?? join24(localAppData, "Zixt", "Host");
43111
+ const configPath = join24(configRoot, "host.json");
43112
+ const launcherPath = join24(configRoot, "host-launcher.ps1");
43113
+ const launchShimPath = join24(configRoot, "host-launch.vbs");
43114
+ const taskXmlPath = join24(configRoot, "host-task.xml");
43115
+ const statusPath = join24(configRoot, "host-status.json");
43061
43116
  const installVersion = options.installVersion ?? ((version2, onFailure) => installRelease(version2, onFailure ? { onFailure } : {}));
43062
43117
  const activateVersion = options.activateVersion ?? (options.installVersion ? async (entry) => entry : (entry) => activateInstalledRelease(entry));
43063
43118
  const resolveCommand = options.resolveCommand ?? ((name) => defaultResolveCommand3(name, env));
@@ -43092,13 +43147,14 @@ async function installWindowsService(options) {
43092
43147
  throw new Error("Windows did not return a protected Machine pairing credential.");
43093
43148
  }
43094
43149
  const generation = crypto.randomUUID();
43150
+ const serviceNode = options.serviceNode ?? await ensureDurableServiceNode({ home, syncDirectory: sync });
43095
43151
  await ensureDirectory3(configRoot, sync);
43096
43152
  await replacePrivateFile3(
43097
43153
  configPath,
43098
43154
  `${JSON.stringify({
43099
43155
  schema: 1,
43100
43156
  generation,
43101
- node: process.execPath,
43157
+ node: serviceNode,
43102
43158
  entry: currentEntry,
43103
43159
  cwd: home,
43104
43160
  protectedToken,
@@ -43123,7 +43179,7 @@ async function installWindowsService(options) {
43123
43179
  sync,
43124
43180
  "utf16le"
43125
43181
  );
43126
- await rm12(statusPath, { force: true });
43182
+ await rm13(statusPath, { force: true });
43127
43183
  const acl = await run3(icacls, [
43128
43184
  configRoot,
43129
43185
  "/inheritance:r",
@@ -43183,23 +43239,23 @@ async function installSystemService(options) {
43183
43239
  }
43184
43240
 
43185
43241
  // src/terminal-outcomes.ts
43186
- import { chmod as chmod9, lstat as lstat12, mkdir as mkdir17, open as open10, readdir as readdir6, readFile as readFile12, rename as rename9, rm as rm13 } from "node:fs/promises";
43187
- import { homedir as homedir13 } from "node:os";
43188
- import { dirname as dirname14, join as join24, relative as relative12, resolve as resolve15, sep as sep8 } from "node:path";
43242
+ import { chmod as chmod10, lstat as lstat12, mkdir as mkdir18, open as open10, readdir as readdir6, readFile as readFile12, rename as rename10, rm as rm14 } from "node:fs/promises";
43243
+ import { homedir as homedir14 } from "node:os";
43244
+ import { dirname as dirname14, join as join25, relative as relative12, resolve as resolve16, sep as sep9 } from "node:path";
43189
43245
  var DIRECTORY_MODE5 = 448;
43190
43246
  var FILE_MODE4 = 384;
43191
43247
  var MAX_OUTCOME_BYTES = 4 * 1024 * 1024;
43192
43248
  var HOST_DIRECTORY = /^hst_[0-9a-f]{32}$/;
43193
43249
  var OUTCOME_FILE = /^(tsk_[0-9a-f]{32})\.([1-9][0-9]*)\.json$/;
43194
43250
  function defaultTerminalOutcomeRoot() {
43195
- return join24(homedir13(), ".zixt", "terminal-outcomes");
43251
+ return join25(homedir14(), ".zixt", "terminal-outcomes");
43196
43252
  }
43197
43253
  function hostOutcomeRoot(root, hostId) {
43198
43254
  if (!HOST_DIRECTORY.test(hostId)) throw new Error("terminal outcome Host identity is malformed");
43199
- return join24(root, hostId);
43255
+ return join25(root, hostId);
43200
43256
  }
43201
43257
  function outcomePath(root, hostId, taskId, epoch) {
43202
- return join24(hostOutcomeRoot(root, hostId), `${taskId}.${epoch}.json`);
43258
+ return join25(hostOutcomeRoot(root, hostId), `${taskId}.${epoch}.json`);
43203
43259
  }
43204
43260
  async function syncDirectory6(root) {
43205
43261
  if (process.platform === "win32") return;
@@ -43211,22 +43267,22 @@ async function syncDirectory6(root) {
43211
43267
  }
43212
43268
  }
43213
43269
  async function requirePrivateRoot(root, sync = syncDirectory6) {
43214
- const firstCreated = await mkdir17(root, { recursive: true, mode: DIRECTORY_MODE5 });
43270
+ const firstCreated = await mkdir18(root, { recursive: true, mode: DIRECTORY_MODE5 });
43215
43271
  if (firstCreated) {
43216
- const first = resolve15(firstCreated);
43217
- const target = resolve15(root);
43272
+ const first = resolve16(firstCreated);
43273
+ const target = resolve16(root);
43218
43274
  await sync(dirname14(first));
43219
43275
  let current = first;
43220
- for (const part of relative12(first, target).split(sep8).filter(Boolean)) {
43276
+ for (const part of relative12(first, target).split(sep9).filter(Boolean)) {
43221
43277
  await sync(current);
43222
- current = join24(current, part);
43278
+ current = join25(current, part);
43223
43279
  }
43224
43280
  }
43225
43281
  const stat4 = await lstat12(root);
43226
43282
  if (stat4.isSymbolicLink() || !stat4.isDirectory()) {
43227
43283
  throw new Error("terminal outcome journal root is not a trusted directory");
43228
43284
  }
43229
- await chmod9(root, DIRECTORY_MODE5);
43285
+ await chmod10(root, DIRECTORY_MODE5);
43230
43286
  }
43231
43287
  function parseCommittedOutcome(text, taskId, epoch) {
43232
43288
  let json2;
@@ -43259,7 +43315,7 @@ async function recordTerminalOutcome(hostId, input, root = defaultTerminalOutcom
43259
43315
  } catch (error52) {
43260
43316
  if (error52.code !== "ENOENT") throw error52;
43261
43317
  }
43262
- const temporary = join24(
43318
+ const temporary = join25(
43263
43319
  scopedRoot,
43264
43320
  `.${outcome.taskId}.${outcome.epoch}.${process.pid}.${Date.now()}.${outcome.resultId}.tmp`
43265
43321
  );
@@ -43270,13 +43326,13 @@ async function recordTerminalOutcome(hostId, input, root = defaultTerminalOutcom
43270
43326
  await handle.sync();
43271
43327
  await handle.close();
43272
43328
  handle = void 0;
43273
- await rename9(temporary, destination);
43329
+ await rename10(temporary, destination);
43274
43330
  await sync(scopedRoot);
43275
43331
  await sync(root);
43276
43332
  } finally {
43277
43333
  await handle?.close().catch(() => {
43278
43334
  });
43279
- await rm13(temporary, { force: true }).catch(() => {
43335
+ await rm14(temporary, { force: true }).catch(() => {
43280
43336
  });
43281
43337
  }
43282
43338
  }
@@ -43291,7 +43347,7 @@ async function readTerminalOutcomesStrict(root = defaultTerminalOutcomeRoot()) {
43291
43347
  if (rootStat.isSymbolicLink() || !rootStat.isDirectory()) {
43292
43348
  throw new Error("terminal outcome journal root is not a trusted directory");
43293
43349
  }
43294
- await chmod9(root, DIRECTORY_MODE5);
43350
+ await chmod10(root, DIRECTORY_MODE5);
43295
43351
  const hostEntries = await readdir6(root, { withFileTypes: true });
43296
43352
  const outcomes = [];
43297
43353
  const resultIds = /* @__PURE__ */ new Set();
@@ -43304,7 +43360,7 @@ async function readTerminalOutcomesStrict(root = defaultTerminalOutcomeRoot()) {
43304
43360
  if (scopedStat.isSymbolicLink() || !scopedStat.isDirectory()) {
43305
43361
  throw new Error("terminal outcome Host scope is not a trusted directory");
43306
43362
  }
43307
- await chmod9(scopedRoot, DIRECTORY_MODE5);
43363
+ await chmod10(scopedRoot, DIRECTORY_MODE5);
43308
43364
  const entries = await readdir6(scopedRoot, { withFileTypes: true });
43309
43365
  for (const entry of entries) {
43310
43366
  if (!entry.name.endsWith(".json")) continue;
@@ -43312,7 +43368,7 @@ async function readTerminalOutcomesStrict(root = defaultTerminalOutcomeRoot()) {
43312
43368
  if (!match || !entry.isFile() || entry.isSymbolicLink()) {
43313
43369
  throw new Error("committed terminal outcome is not a trusted regular file");
43314
43370
  }
43315
- const path = join24(scopedRoot, entry.name);
43371
+ const path = join25(scopedRoot, entry.name);
43316
43372
  const stat4 = await lstat12(path);
43317
43373
  if (!stat4.isFile() || stat4.isSymbolicLink() || stat4.size > MAX_OUTCOME_BYTES) {
43318
43374
  throw new Error("committed terminal outcome is not a trusted regular file");
@@ -43345,7 +43401,7 @@ async function forgetAcknowledgedTerminalOutcomes(refs, root = defaultTerminalOu
43345
43401
  if (acknowledged.get(`${hostId}:${outcome.taskId}:${outcome.epoch}`) !== outcome.resultId) {
43346
43402
  continue;
43347
43403
  }
43348
- await rm13(outcomePath(root, hostId, outcome.taskId, outcome.epoch), { force: true });
43404
+ await rm14(outcomePath(root, hostId, outcome.taskId, outcome.epoch), { force: true });
43349
43405
  changedHostRoots.add(hostOutcomeRoot(root, hostId));
43350
43406
  }
43351
43407
  for (const scopedRoot of changedHostRoots) await syncDirectory6(scopedRoot);
@@ -43357,22 +43413,22 @@ async function forgetSupersededTerminalOutcomes(hostId, taskId, epoch, root = de
43357
43413
  if (scoped.hostId !== hostId) continue;
43358
43414
  const { outcome } = scoped;
43359
43415
  if (outcome.taskId !== taskId || outcome.epoch >= epoch) continue;
43360
- await rm13(outcomePath(root, hostId, outcome.taskId, outcome.epoch), { force: true });
43416
+ await rm14(outcomePath(root, hostId, outcome.taskId, outcome.epoch), { force: true });
43361
43417
  removed = true;
43362
43418
  }
43363
43419
  if (removed) await syncDirectory6(hostOutcomeRoot(root, hostId));
43364
43420
  }
43365
43421
 
43366
43422
  // src/accepted-assignments.ts
43367
- import { chmod as chmod10, lstat as lstat13, mkdir as mkdir18, open as open11, readdir as readdir7, rename as rename10, rm as rm14 } from "node:fs/promises";
43368
- import { homedir as homedir14 } from "node:os";
43369
- import { dirname as dirname15, join as join25, relative as relative13, resolve as resolve16, sep as sep9 } from "node:path";
43423
+ import { chmod as chmod11, lstat as lstat13, mkdir as mkdir19, open as open11, readdir as readdir7, rename as rename11, rm as rm15 } from "node:fs/promises";
43424
+ import { homedir as homedir15 } from "node:os";
43425
+ import { dirname as dirname15, join as join26, relative as relative13, resolve as resolve17, sep as sep10 } from "node:path";
43370
43426
  var DIRECTORY_MODE6 = 448;
43371
43427
  var FILE_MODE5 = 384;
43372
43428
  var CLAIM_FILE = /^(tsk_[0-9a-f]{32})\.([1-9][0-9]*)\.json$/;
43373
43429
  var TASK_ID = /^tsk_[0-9a-f]{32}$/;
43374
43430
  function defaultAcceptedAssignmentRoot() {
43375
- return join25(homedir14(), ".zixt", "accepted-assignments");
43431
+ return join26(homedir15(), ".zixt", "accepted-assignments");
43376
43432
  }
43377
43433
  async function syncDirectory7(root) {
43378
43434
  if (process.platform === "win32") return;
@@ -43384,29 +43440,29 @@ async function syncDirectory7(root) {
43384
43440
  }
43385
43441
  }
43386
43442
  async function requirePrivateRoot2(root, sync = syncDirectory7) {
43387
- const firstCreated = await mkdir18(root, { recursive: true, mode: DIRECTORY_MODE6 });
43443
+ const firstCreated = await mkdir19(root, { recursive: true, mode: DIRECTORY_MODE6 });
43388
43444
  if (firstCreated) {
43389
- const first = resolve16(firstCreated);
43390
- const target = resolve16(root);
43445
+ const first = resolve17(firstCreated);
43446
+ const target = resolve17(root);
43391
43447
  await sync(dirname15(first));
43392
43448
  let current = first;
43393
- for (const part of relative13(first, target).split(sep9).filter(Boolean)) {
43449
+ for (const part of relative13(first, target).split(sep10).filter(Boolean)) {
43394
43450
  await sync(current);
43395
- current = join25(current, part);
43451
+ current = join26(current, part);
43396
43452
  }
43397
43453
  }
43398
43454
  const stat4 = await lstat13(root);
43399
43455
  if (stat4.isSymbolicLink() || !stat4.isDirectory()) {
43400
43456
  throw new Error("accepted assignment journal root is not a trusted directory");
43401
43457
  }
43402
- await chmod10(root, DIRECTORY_MODE6);
43458
+ await chmod11(root, DIRECTORY_MODE6);
43403
43459
  }
43404
43460
  function claimPath(root, taskId, epoch) {
43405
43461
  if (!TASK_ID.test(taskId)) throw new Error("accepted assignment Task identity is malformed");
43406
43462
  if (!Number.isSafeInteger(epoch) || epoch < 1) {
43407
43463
  throw new Error("accepted assignment epoch is malformed");
43408
43464
  }
43409
- return join25(root, `${taskId}.${epoch}.json`);
43465
+ return join26(root, `${taskId}.${epoch}.json`);
43410
43466
  }
43411
43467
  async function recordAcceptedAssignment(assignment, root = defaultAcceptedAssignmentRoot(), options = {}) {
43412
43468
  const sync = options.syncDirectory ?? syncDirectory7;
@@ -43416,7 +43472,7 @@ async function recordAcceptedAssignment(assignment, root = defaultAcceptedAssign
43416
43472
  } catch {
43417
43473
  return false;
43418
43474
  }
43419
- const temporary = join25(
43475
+ const temporary = join26(
43420
43476
  root,
43421
43477
  `.${assignment.taskId}.${assignment.epoch}.${process.pid}.${Date.now()}.tmp`
43422
43478
  );
@@ -43428,7 +43484,7 @@ async function recordAcceptedAssignment(assignment, root = defaultAcceptedAssign
43428
43484
  await handle.sync();
43429
43485
  await handle.close();
43430
43486
  handle = void 0;
43431
- await rename10(temporary, destination);
43487
+ await rename11(temporary, destination);
43432
43488
  if (process.platform !== "win32") await sync(root);
43433
43489
  return true;
43434
43490
  } catch {
@@ -43436,7 +43492,7 @@ async function recordAcceptedAssignment(assignment, root = defaultAcceptedAssign
43436
43492
  } finally {
43437
43493
  await handle?.close().catch(() => {
43438
43494
  });
43439
- await rm14(temporary, { force: true }).catch(() => {
43495
+ await rm15(temporary, { force: true }).catch(() => {
43440
43496
  });
43441
43497
  }
43442
43498
  }
@@ -43451,7 +43507,7 @@ async function recoverAcceptedAssignments(root = defaultAcceptedAssignmentRoot()
43451
43507
  if (rootStat.isSymbolicLink() || !rootStat.isDirectory()) {
43452
43508
  throw new Error("accepted assignment journal root is not a trusted directory");
43453
43509
  }
43454
- await chmod10(root, DIRECTORY_MODE6);
43510
+ await chmod11(root, DIRECTORY_MODE6);
43455
43511
  const claims = [];
43456
43512
  for (const entry of await readdir7(root, { withFileTypes: true })) {
43457
43513
  if (!entry.isFile()) continue;
@@ -43470,7 +43526,7 @@ async function forgetAcceptedAssignment(assignment, root = defaultAcceptedAssign
43470
43526
  } catch {
43471
43527
  return;
43472
43528
  }
43473
- await rm14(path, { force: true }).catch(() => {
43529
+ await rm15(path, { force: true }).catch(() => {
43474
43530
  });
43475
43531
  }
43476
43532
  async function forgetAcknowledgedAcceptedAssignments(assignments, root = defaultAcceptedAssignmentRoot()) {
@@ -43478,9 +43534,9 @@ async function forgetAcknowledgedAcceptedAssignments(assignments, root = default
43478
43534
  }
43479
43535
 
43480
43536
  // src/local-observability.ts
43481
- import { appendFile, mkdir as mkdir19, open as open12, rename as rename11, rm as rm15, stat as stat3 } from "node:fs/promises";
43482
- import { homedir as homedir15 } from "node:os";
43483
- import { basename as basename7, dirname as dirname16, join as join26 } from "node:path";
43537
+ import { appendFile, mkdir as mkdir20, open as open12, readdir as readdir8, rename as rename12, rm as rm16, stat as stat3 } from "node:fs/promises";
43538
+ import { homedir as homedir16 } from "node:os";
43539
+ import { basename as basename7, dirname as dirname16, join as join27 } from "node:path";
43484
43540
 
43485
43541
  // src/logger.ts
43486
43542
  var ANSI = {
@@ -43589,13 +43645,14 @@ function createHostLogger(options = {}) {
43589
43645
  var LOCAL_CONSOLE_FILE = "console.jsonl";
43590
43646
  var LOCAL_CONSOLE_PREVIOUS_FILE = "console.prev.jsonl";
43591
43647
  var LOCAL_STATUS_FILE = "status.json";
43648
+ var LOCAL_REQUESTS_DIR = "requests";
43592
43649
  var DEFAULT_CONSOLE_ROTATE_BYTES = 2 * 1024 * 1024;
43593
43650
  function defaultLocalObservabilityRoot() {
43594
- return join26(homedir15(), ".zixt", "observability");
43651
+ return join27(homedir16(), ".zixt", "observability");
43595
43652
  }
43596
43653
  function createLocalConsoleSink(options = {}) {
43597
43654
  const root = options.root ?? defaultLocalObservabilityRoot();
43598
- const consolePath = join26(root, LOCAL_CONSOLE_FILE);
43655
+ const consolePath = join27(root, LOCAL_CONSOLE_FILE);
43599
43656
  const rotateBytes = options.rotateBytes ?? DEFAULT_CONSOLE_ROTATE_BYTES;
43600
43657
  let disabled = false;
43601
43658
  let prepared = false;
@@ -43605,7 +43662,7 @@ function createLocalConsoleSink(options = {}) {
43605
43662
  if (disabled) return;
43606
43663
  try {
43607
43664
  if (!prepared) {
43608
- await mkdir19(root, { recursive: true, mode: 448 });
43665
+ await mkdir20(root, { recursive: true, mode: 448 });
43609
43666
  approximateBytes = await stat3(consolePath).then(
43610
43667
  (existing) => existing.size,
43611
43668
  () => 0
@@ -43613,8 +43670,8 @@ function createLocalConsoleSink(options = {}) {
43613
43670
  prepared = true;
43614
43671
  }
43615
43672
  if (approximateBytes >= rotateBytes) {
43616
- await rm15(join26(root, LOCAL_CONSOLE_PREVIOUS_FILE), { force: true });
43617
- await rename11(consolePath, join26(root, LOCAL_CONSOLE_PREVIOUS_FILE)).catch(
43673
+ await rm16(join27(root, LOCAL_CONSOLE_PREVIOUS_FILE), { force: true });
43674
+ await rename12(consolePath, join27(root, LOCAL_CONSOLE_PREVIOUS_FILE)).catch(
43618
43675
  (error52) => {
43619
43676
  if (error52.code !== "ENOENT") throw error52;
43620
43677
  }
@@ -43644,14 +43701,34 @@ function createLocalConsoleSink(options = {}) {
43644
43701
  settled: () => queue
43645
43702
  };
43646
43703
  }
43704
+ async function consumeRunnerInstallRequests(root = defaultLocalObservabilityRoot()) {
43705
+ const directory = join27(root, LOCAL_REQUESTS_DIR);
43706
+ const requested = /* @__PURE__ */ new Set();
43707
+ let names;
43708
+ try {
43709
+ names = await readdir8(directory);
43710
+ } catch {
43711
+ return requested;
43712
+ }
43713
+ for (const type of INSTALLABLE_RUNNERS) {
43714
+ const name = `install-runner-${type}.json`;
43715
+ if (!names.includes(name)) continue;
43716
+ try {
43717
+ await rm16(join27(directory, name), { force: true });
43718
+ requested.add(type);
43719
+ } catch {
43720
+ }
43721
+ }
43722
+ return requested;
43723
+ }
43647
43724
  async function writeLocalStatus(status, root = defaultLocalObservabilityRoot()) {
43648
- const destination = join26(root, LOCAL_STATUS_FILE);
43649
- const temporary = join26(
43725
+ const destination = join27(root, LOCAL_STATUS_FILE);
43726
+ const temporary = join27(
43650
43727
  dirname16(destination),
43651
43728
  `.${basename7(destination)}.${process.pid}.${crypto.randomUUID()}.tmp`
43652
43729
  );
43653
43730
  try {
43654
- await mkdir19(root, { recursive: true, mode: 448 });
43731
+ await mkdir20(root, { recursive: true, mode: 448 });
43655
43732
  const handle = await open12(temporary, "wx", 384);
43656
43733
  try {
43657
43734
  await handle.writeFile(`${JSON.stringify(status)}
@@ -43659,31 +43736,31 @@ async function writeLocalStatus(status, root = defaultLocalObservabilityRoot())
43659
43736
  } finally {
43660
43737
  await handle.close();
43661
43738
  }
43662
- await rename11(temporary, destination);
43739
+ await rename12(temporary, destination);
43663
43740
  } catch {
43664
- await rm15(temporary, { force: true }).catch(() => void 0);
43741
+ await rm16(temporary, { force: true }).catch(() => void 0);
43665
43742
  }
43666
43743
  }
43667
43744
 
43668
43745
  // src/demo-state.ts
43669
- import { isAbsolute as isAbsolute19, join as join27, parse as parse3, resolve as resolve17 } from "node:path";
43746
+ import { isAbsolute as isAbsolute19, join as join28, parse as parse3, resolve as resolve18 } from "node:path";
43670
43747
  var DEMO_STATE_ROOT_ENV = "ZIXT_DEMO_STATE_ROOT";
43671
43748
  function resolveDemoHostStatePaths(env = process.env) {
43672
43749
  const configured = env.ZIXT_RUNNER === "demo" ? env[DEMO_STATE_ROOT_ENV] : void 0;
43673
43750
  if (!configured) return null;
43674
- const root = resolve17(configured);
43751
+ const root = resolve18(configured);
43675
43752
  if (!isAbsolute19(configured) || root === parse3(root).root) {
43676
43753
  throw new Error(`${DEMO_STATE_ROOT_ENV} must be a dedicated absolute directory`);
43677
43754
  }
43678
43755
  return {
43679
- runRegistryRoot: join27(root, "run-registry"),
43680
- terminalOutcomeRoot: join27(root, "terminal-outcomes"),
43681
- acceptedAssignmentRoot: join27(root, "accepted-assignments"),
43682
- runArtifactRoot: join27(root, "run-artifacts"),
43683
- browserProfileRoot: join27(root, "browser-profiles"),
43684
- runnerWorkspaceRoot: join27(root, "workspaces"),
43685
- codexThreadIndexRoot: join27(root, "codex-threads"),
43686
- localObservabilityRoot: join27(root, "local-observability")
43756
+ runRegistryRoot: join28(root, "run-registry"),
43757
+ terminalOutcomeRoot: join28(root, "terminal-outcomes"),
43758
+ acceptedAssignmentRoot: join28(root, "accepted-assignments"),
43759
+ runArtifactRoot: join28(root, "run-artifacts"),
43760
+ browserProfileRoot: join28(root, "browser-profiles"),
43761
+ runnerWorkspaceRoot: join28(root, "workspaces"),
43762
+ codexThreadIndexRoot: join28(root, "codex-threads"),
43763
+ localObservabilityRoot: join28(root, "local-observability")
43687
43764
  };
43688
43765
  }
43689
43766
 
@@ -43994,7 +44071,10 @@ if (!token) {
43994
44071
  process.exit(DO_NOT_RESTART_EXIT_CODE);
43995
44072
  }
43996
44073
  var demoPreflightScript = forceDemo ? process.env.ZIXT_DEMO_PREFLIGHT_SCRIPT : void 0;
43997
- var runnerAutoInstaller = forceDemo || process.env.ZIXT_RUNNER_AUTOINSTALL === "off" ? null : createRunnerAutoInstaller({
44074
+ var runnerAutoinstallSelection = parseRunnerAutoinstallSelection(
44075
+ process.env.ZIXT_RUNNER_AUTOINSTALL
44076
+ );
44077
+ var runnerAutoInstaller = forceDemo ? null : createRunnerAutoInstaller({
43998
44078
  onEvent: (event) => {
43999
44079
  const name = event.runner === "claude-code" ? "Claude Code" : "Codex";
44000
44080
  if (event.state === "started") {
@@ -44144,7 +44224,8 @@ async function currentBrowserCapability() {
44144
44224
  return measured;
44145
44225
  }
44146
44226
  async function telemetry() {
44147
- if (!cachedRunners || Date.now() - cachedRunnersAt > 4 * 6e4) {
44227
+ const requestedInstalls = runnerAutoInstaller ? await consumeRunnerInstallRequests(localObservabilityRoot) : /* @__PURE__ */ new Set();
44228
+ if (!cachedRunners || Date.now() - cachedRunnersAt > 4 * 6e4 || requestedInstalls.size > 0) {
44148
44229
  cachedRunners = await Promise.all([
44149
44230
  preflightClaudeCode(
44150
44231
  demoPreflightScript ? { command: process.execPath, commandPrefixArgs: [demoPreflightScript] } : {}
@@ -44156,7 +44237,22 @@ async function telemetry() {
44156
44237
  cachedRunnersAt = Date.now();
44157
44238
  for (const runner of cachedRunners) {
44158
44239
  reportRunnerReadiness(runner);
44159
- if (!runner.installed && (runner.type === "claude-code" || runner.type === "codex") && runnerAutoInstaller) {
44240
+ if (!runnerAutoInstaller || runner.type !== "claude-code" && runner.type !== "codex") {
44241
+ continue;
44242
+ }
44243
+ const requested = requestedInstalls.has(runner.type);
44244
+ if (runner.installed) {
44245
+ if (requested) {
44246
+ log.info(
44247
+ `${runner.type === "claude-code" ? "Claude Code" : "Codex"} is already installed on this Machine`,
44248
+ { machine }
44249
+ );
44250
+ }
44251
+ continue;
44252
+ }
44253
+ if (requested) {
44254
+ runnerAutoInstaller.ensureInstalled(runner.type, { force: true });
44255
+ } else if (runnerAutoinstallSelection.has(runner.type)) {
44160
44256
  runnerAutoInstaller.ensureInstalled(runner.type);
44161
44257
  }
44162
44258
  }
@@ -44192,7 +44288,7 @@ async function telemetry() {
44192
44288
  // Measured per heartbeat: free memory and free disk are only useful while
44193
44289
  // they are current, and a demo Host reports its own private root so the
44194
44290
  // number describes the filesystem its Tasks would really write to.
44195
- hardware: await machineHardware(runnerWorkspaceRoot ?? homedir16()),
44291
+ hardware: await machineHardware(runnerWorkspaceRoot ?? homedir17()),
44196
44292
  capabilities: {
44197
44293
  linearToolPack: providerToolPacks.some(
44198
44294
  (pack) => pack.provider === "linear" && pack.health === "ready"
@@ -44272,7 +44368,9 @@ function publishLocalStatus() {
44272
44368
  ...localCloudConnectedAt ? { connectedAt: localCloudConnectedAt } : {}
44273
44369
  },
44274
44370
  activeSessions,
44275
- runners: cachedRunners ?? [],
44371
+ runners: (cachedRunners ?? []).map(
44372
+ (runner) => (runner.type === "claude-code" || runner.type === "codex") && runnerAutoInstaller?.isInstalling(runner.type) ? { ...runner, installing: true } : runner
44373
+ ),
44276
44374
  browser: cachedBrowserCapability ?? { status: "unavailable" }
44277
44375
  },
44278
44376
  ...localObservabilityRoot ? [localObservabilityRoot] : []