@zixt/host 0.0.121 → 0.0.123

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 +85 -8
  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.121",
31
+ version: "0.0.123",
32
32
  type: "module",
33
33
  exports: {
34
34
  ".": "./src/client.ts",
@@ -14605,6 +14605,8 @@ var ID_PREFIXES = {
14605
14605
  /** One bounded image owned by an AI teammate profile. */
14606
14606
  agentAvatar: "aav",
14607
14607
  host: "hst",
14608
+ /** One-use browser-approved desktop-app pairing session. */
14609
+ hostPairingSession: "hps",
14608
14610
  task: "tsk",
14609
14611
  attempt: "att",
14610
14612
  review: "rvw",
@@ -20454,6 +20456,23 @@ var CreateHostRequest = external_exports.object({
20454
20456
  /** Optional only for rolling compatibility; the current UI always asks. */
20455
20457
  operatingSystem: HostOperatingSystem.optional()
20456
20458
  });
20459
+ var HostPairingCode = external_exports.string().regex(/^zxp_[0-9a-f]{64}$/, "pairing code shape is zxp_<64 hex>");
20460
+ var Sha256Hex = external_exports.string().regex(/^[0-9a-f]{64}$/, "expected 64 lowercase hex characters");
20461
+ var CreateHostPairingSessionRequest = external_exports.object({
20462
+ name: Host.shape.name,
20463
+ operatingSystem: HostOperatingSystem.optional(),
20464
+ /** SHA-256 hex of the verifier the desktop app keeps (PKCE-style). */
20465
+ challenge: Sha256Hex
20466
+ });
20467
+ var CreateHostPairingSessionResponse = external_exports.object({
20468
+ code: HostPairingCode,
20469
+ expiresAt: external_exports.iso.datetime()
20470
+ });
20471
+ var RedeemHostPairingRequest = external_exports.object({
20472
+ code: HostPairingCode,
20473
+ /** Preimage of the session's challenge; possession proves the initiator. */
20474
+ verifier: Sha256Hex
20475
+ });
20457
20476
  var RenameHostRequest = external_exports.object({
20458
20477
  name: Host.shape.name
20459
20478
  });
@@ -22429,6 +22448,17 @@ function sanitizedInstallerEnv(inherited) {
22429
22448
  }
22430
22449
 
22431
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
+ }
22432
22462
  var CLAUDE_INSTALLER_URL_POSIX = "https://claude.ai/install.sh";
22433
22463
  var CLAUDE_INSTALLER_URL_WINDOWS = "https://claude.ai/install.ps1";
22434
22464
  var CODEX_PACKAGE = "@openai/codex";
@@ -22607,10 +22637,12 @@ function createRunnerAutoInstaller(options) {
22607
22637
  };
22608
22638
  const install = options.install ?? ((type) => type === "claude-code" ? installClaude() : installCodex());
22609
22639
  return {
22610
- ensureInstalled(type) {
22640
+ ensureInstalled(type, ensureOptions) {
22611
22641
  if (inFlight.has(type)) return;
22612
22642
  const lastFailure = failedAt.get(type);
22613
- 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
+ }
22614
22646
  options.onEvent({ runner: type, state: "started" });
22615
22647
  const attempt = (async () => {
22616
22648
  try {
@@ -22644,6 +22676,9 @@ function createRunnerAutoInstaller(options) {
22644
22676
  })();
22645
22677
  inFlight.set(type, attempt);
22646
22678
  },
22679
+ isInstalling(type) {
22680
+ return inFlight.has(type);
22681
+ },
22647
22682
  async settled() {
22648
22683
  while (inFlight.size > 0) await Promise.allSettled([...inFlight.values()]);
22649
22684
  }
@@ -43459,7 +43494,7 @@ async function forgetAcknowledgedAcceptedAssignments(assignments, root = default
43459
43494
  }
43460
43495
 
43461
43496
  // src/local-observability.ts
43462
- import { appendFile, mkdir as mkdir19, open as open12, rename as rename11, rm as rm15, stat as stat3 } from "node:fs/promises";
43497
+ import { appendFile, mkdir as mkdir19, open as open12, readdir as readdir8, rename as rename11, rm as rm15, stat as stat3 } from "node:fs/promises";
43463
43498
  import { homedir as homedir15 } from "node:os";
43464
43499
  import { basename as basename7, dirname as dirname16, join as join26 } from "node:path";
43465
43500
 
@@ -43570,6 +43605,7 @@ function createHostLogger(options = {}) {
43570
43605
  var LOCAL_CONSOLE_FILE = "console.jsonl";
43571
43606
  var LOCAL_CONSOLE_PREVIOUS_FILE = "console.prev.jsonl";
43572
43607
  var LOCAL_STATUS_FILE = "status.json";
43608
+ var LOCAL_REQUESTS_DIR = "requests";
43573
43609
  var DEFAULT_CONSOLE_ROTATE_BYTES = 2 * 1024 * 1024;
43574
43610
  function defaultLocalObservabilityRoot() {
43575
43611
  return join26(homedir15(), ".zixt", "observability");
@@ -43625,6 +43661,26 @@ function createLocalConsoleSink(options = {}) {
43625
43661
  settled: () => queue
43626
43662
  };
43627
43663
  }
43664
+ async function consumeRunnerInstallRequests(root = defaultLocalObservabilityRoot()) {
43665
+ const directory = join26(root, LOCAL_REQUESTS_DIR);
43666
+ const requested = /* @__PURE__ */ new Set();
43667
+ let names;
43668
+ try {
43669
+ names = await readdir8(directory);
43670
+ } catch {
43671
+ return requested;
43672
+ }
43673
+ for (const type of INSTALLABLE_RUNNERS) {
43674
+ const name = `install-runner-${type}.json`;
43675
+ if (!names.includes(name)) continue;
43676
+ try {
43677
+ await rm15(join26(directory, name), { force: true });
43678
+ requested.add(type);
43679
+ } catch {
43680
+ }
43681
+ }
43682
+ return requested;
43683
+ }
43628
43684
  async function writeLocalStatus(status, root = defaultLocalObservabilityRoot()) {
43629
43685
  const destination = join26(root, LOCAL_STATUS_FILE);
43630
43686
  const temporary = join26(
@@ -43975,7 +44031,10 @@ if (!token) {
43975
44031
  process.exit(DO_NOT_RESTART_EXIT_CODE);
43976
44032
  }
43977
44033
  var demoPreflightScript = forceDemo ? process.env.ZIXT_DEMO_PREFLIGHT_SCRIPT : void 0;
43978
- var runnerAutoInstaller = forceDemo || process.env.ZIXT_RUNNER_AUTOINSTALL === "off" ? null : createRunnerAutoInstaller({
44034
+ var runnerAutoinstallSelection = parseRunnerAutoinstallSelection(
44035
+ process.env.ZIXT_RUNNER_AUTOINSTALL
44036
+ );
44037
+ var runnerAutoInstaller = forceDemo ? null : createRunnerAutoInstaller({
43979
44038
  onEvent: (event) => {
43980
44039
  const name = event.runner === "claude-code" ? "Claude Code" : "Codex";
43981
44040
  if (event.state === "started") {
@@ -44125,7 +44184,8 @@ async function currentBrowserCapability() {
44125
44184
  return measured;
44126
44185
  }
44127
44186
  async function telemetry() {
44128
- if (!cachedRunners || Date.now() - cachedRunnersAt > 4 * 6e4) {
44187
+ const requestedInstalls = runnerAutoInstaller ? await consumeRunnerInstallRequests(localObservabilityRoot) : /* @__PURE__ */ new Set();
44188
+ if (!cachedRunners || Date.now() - cachedRunnersAt > 4 * 6e4 || requestedInstalls.size > 0) {
44129
44189
  cachedRunners = await Promise.all([
44130
44190
  preflightClaudeCode(
44131
44191
  demoPreflightScript ? { command: process.execPath, commandPrefixArgs: [demoPreflightScript] } : {}
@@ -44137,7 +44197,22 @@ async function telemetry() {
44137
44197
  cachedRunnersAt = Date.now();
44138
44198
  for (const runner of cachedRunners) {
44139
44199
  reportRunnerReadiness(runner);
44140
- if (!runner.installed && (runner.type === "claude-code" || runner.type === "codex") && runnerAutoInstaller) {
44200
+ if (!runnerAutoInstaller || runner.type !== "claude-code" && runner.type !== "codex") {
44201
+ continue;
44202
+ }
44203
+ const requested = requestedInstalls.has(runner.type);
44204
+ if (runner.installed) {
44205
+ if (requested) {
44206
+ log.info(
44207
+ `${runner.type === "claude-code" ? "Claude Code" : "Codex"} is already installed on this Machine`,
44208
+ { machine }
44209
+ );
44210
+ }
44211
+ continue;
44212
+ }
44213
+ if (requested) {
44214
+ runnerAutoInstaller.ensureInstalled(runner.type, { force: true });
44215
+ } else if (runnerAutoinstallSelection.has(runner.type)) {
44141
44216
  runnerAutoInstaller.ensureInstalled(runner.type);
44142
44217
  }
44143
44218
  }
@@ -44253,7 +44328,9 @@ function publishLocalStatus() {
44253
44328
  ...localCloudConnectedAt ? { connectedAt: localCloudConnectedAt } : {}
44254
44329
  },
44255
44330
  activeSessions,
44256
- runners: cachedRunners ?? [],
44331
+ runners: (cachedRunners ?? []).map(
44332
+ (runner) => (runner.type === "claude-code" || runner.type === "codex") && runnerAutoInstaller?.isInstalling(runner.type) ? { ...runner, installing: true } : runner
44333
+ ),
44257
44334
  browser: cachedBrowserCapability ?? { status: "unavailable" }
44258
44335
  },
44259
44336
  ...localObservabilityRoot ? [localObservabilityRoot] : []
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zixt/host",
3
- "version": "0.0.121",
3
+ "version": "0.0.123",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./src/client.ts",