@zixt/host 0.0.109 → 0.0.111

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 (3) hide show
  1. package/README.md +7 -2
  2. package/dist/index.js +238 -122
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -86,8 +86,13 @@ Run `zixt-host --help` for logging flags.
86
86
 
87
87
  ## Teammate browsing
88
88
 
89
- If your teammates use the live browser, install the pinned Chromium once:
89
+ On first start, Zixt checks for its exact Chromium revision and downloads it
90
+ automatically when needed. If that download fails, run the matching installer
91
+ as the same OS user that runs Zixt:
90
92
 
91
93
  ```bash
92
- npx playwright-core install chromium
94
+ npx -y playwright-core@1.61.1 install chromium
93
95
  ```
96
+
97
+ On Windows, use `npx.cmd` instead of `npx`; this works from Command Prompt and
98
+ from PowerShell even when its execution policy blocks npm's `.ps1` shim.
package/dist/index.js CHANGED
@@ -28,7 +28,7 @@ import { homedir as homedir3 } from "node:os";
28
28
  // package.json
29
29
  var package_default = {
30
30
  name: "@zixt/host",
31
- version: "0.0.109",
31
+ version: "0.0.111",
32
32
  type: "module",
33
33
  exports: {
34
34
  ".": "./src/client.ts",
@@ -14602,6 +14602,8 @@ var ID_PREFIXES = {
14602
14602
  org: "org",
14603
14603
  member: "mem",
14604
14604
  agent: "agt",
14605
+ /** One bounded image owned by an AI teammate profile. */
14606
+ agentAvatar: "aav",
14605
14607
  host: "hst",
14606
14608
  task: "tsk",
14607
14609
  attempt: "att",
@@ -14705,6 +14707,7 @@ var idSchema = (prefix, name) => external_exports.string().regex(idPattern(prefi
14705
14707
  var OrgId = idSchema(ID_PREFIXES.org, "org id");
14706
14708
  var MemberId = idSchema(ID_PREFIXES.member, "member id");
14707
14709
  var AgentId = idSchema(ID_PREFIXES.agent, "agent id");
14710
+ var AgentAvatarId = idSchema(ID_PREFIXES.agentAvatar, "agent avatar id");
14708
14711
  var HostId = idSchema(ID_PREFIXES.host, "host id");
14709
14712
  var TaskId = idSchema(ID_PREFIXES.task, "task id");
14710
14713
  var TaskAttemptId = idSchema(ID_PREFIXES.attempt, "task attempt id");
@@ -15480,6 +15483,8 @@ var Agent = external_exports.object({
15480
15483
  id: AgentId,
15481
15484
  orgId: OrgId,
15482
15485
  name: external_exports.string().min(1).max(120),
15486
+ /** Authenticated profile artwork. Null keeps the deterministic initials fallback. */
15487
+ avatarAssetId: AgentAvatarId.nullable().default(null),
15483
15488
  status: AgentStatus,
15484
15489
  /**
15485
15490
  * Archive has fenced new work but is still waiting for one or more exact
@@ -20411,6 +20416,21 @@ var GenerateAgentInstructionDraftResponse = external_exports.object({
20411
20416
  /** Evidence of the fixed product route; ordinary UI copy does not expose it. */
20412
20417
  model: external_exports.literal(MANAGER_DEFAULT_MODEL)
20413
20418
  }).strict();
20419
+ var GenerateManagerInstructionDraftRequest = external_exports.object({
20420
+ existingText: external_exports.string().max(5e4),
20421
+ organizationContext: external_exports.string().max(4e3)
20422
+ }).strict();
20423
+ var GenerateManagerInstructionDraftResponse = external_exports.object({
20424
+ text: external_exports.string().min(1).max(5e4),
20425
+ model: external_exports.literal(MANAGER_DEFAULT_MODEL)
20426
+ }).strict();
20427
+ var AGENT_AVATAR_MAX_BYTES = 1024 * 1024;
20428
+ var AgentAvatarMediaType = external_exports.enum(["image/png", "image/jpeg", "image/webp"]);
20429
+ var UploadAgentAvatarRequest = external_exports.object({
20430
+ mediaType: AgentAvatarMediaType,
20431
+ data: external_exports.string().min(4).max(Math.ceil(AGENT_AVATAR_MAX_BYTES * 4 / 3) + 4)
20432
+ }).strict();
20433
+ var UploadAgentAvatarResponse = external_exports.object({ agent: Agent, avatarAssetId: AgentAvatarId }).strict();
20414
20434
  var UpdateAgentRequest = external_exports.object({
20415
20435
  name: Agent.shape.name,
20416
20436
  roleDescription: external_exports.string().max(2e3),
@@ -30025,8 +30045,21 @@ var BrowserManager = class {
30025
30045
  };
30026
30046
 
30027
30047
  // src/browser/playwright-adapter.ts
30048
+ import { spawn as spawn6 } from "node:child_process";
30028
30049
  import { access as access3 } from "node:fs/promises";
30029
- var BROWSER_INSTALL_REMEDY = "Install the browser on this Machine: run bun run browser:install in the Zixt repo root";
30050
+ import { createRequire } from "node:module";
30051
+ import { dirname as dirname7, join as join10 } from "node:path";
30052
+ var nodeRequire = createRequire(import.meta.url);
30053
+ var playwrightCoreManifestPath = nodeRequire.resolve("playwright-core/package.json");
30054
+ var playwrightCoreRoot = dirname7(playwrightCoreManifestPath);
30055
+ var playwrightCoreVersion = nodeRequire(playwrightCoreManifestPath).version;
30056
+ if (typeof playwrightCoreVersion !== "string" || !/^\d+\.\d+\.\d+$/.test(playwrightCoreVersion)) {
30057
+ throw new Error("playwright-core package version is invalid");
30058
+ }
30059
+ var PLAYWRIGHT_CORE_VERSION = playwrightCoreVersion;
30060
+ var BROWSER_INSTALL_COMMAND = `${process.platform === "win32" ? "npx.cmd" : "npx"} -y playwright-core@${PLAYWRIGHT_CORE_VERSION} install chromium`;
30061
+ var BROWSER_INSTALL_REMEDY = `Zixt could not install its browser automatically. Run ${BROWSER_INSTALL_COMMAND} as the same user that runs Zixt, then restart Zixt.`;
30062
+ var BROWSER_INSTALL_TIMEOUT_MS = 10 * 6e4;
30030
30063
  var READ_TEXT_LIMIT = 4e4;
30031
30064
  var NAVIGATE_TIMEOUT_MS = 3e4;
30032
30065
  var ACTION_TIMEOUT_MS = 1e4;
@@ -30034,9 +30067,44 @@ var LOADING_GIVE_UP_MS = 2e4;
30034
30067
  async function loadPlaywright() {
30035
30068
  return import("playwright-core");
30036
30069
  }
30070
+ async function installChromium() {
30071
+ const cliPath = join10(playwrightCoreRoot, "cli.js");
30072
+ await new Promise((resolve18, reject3) => {
30073
+ const child = spawn6(process.execPath, [cliPath, "install", "chromium"], {
30074
+ env: process.env,
30075
+ stdio: ["ignore", "inherit", "inherit"],
30076
+ windowsHide: false
30077
+ });
30078
+ let settled = false;
30079
+ const finish = (error52) => {
30080
+ if (settled) return;
30081
+ settled = true;
30082
+ clearTimeout(timeout);
30083
+ if (error52) reject3(error52);
30084
+ else resolve18();
30085
+ };
30086
+ const timeout = setTimeout(() => {
30087
+ child.kill();
30088
+ finish(new Error("browser download did not finish within 10 minutes"));
30089
+ }, BROWSER_INSTALL_TIMEOUT_MS);
30090
+ child.once("error", (error52) => finish(error52));
30091
+ child.once("exit", (code, signal) => {
30092
+ if (code === 0) finish();
30093
+ else {
30094
+ finish(
30095
+ new Error(
30096
+ signal ? `browser installer stopped with ${signal}` : `browser installer exited with code ${code ?? "unknown"}`
30097
+ )
30098
+ );
30099
+ }
30100
+ });
30101
+ });
30102
+ }
30037
30103
  var KEY_ALIASES = { " ": "Space" };
30038
30104
  function createPlaywrightBrowserAdapterFactory(dependencies = {}) {
30039
30105
  const load = dependencies.loadPlaywright ?? loadPlaywright;
30106
+ const install = dependencies.installChromium ?? installChromium;
30107
+ let installation = null;
30040
30108
  const runtimes = /* @__PURE__ */ new Map();
30041
30109
  const runtimeLocks = /* @__PURE__ */ new Map();
30042
30110
  const withRuntimeLock = (profileDir, work) => {
@@ -30080,15 +30148,48 @@ function createPlaywrightBrowserAdapterFactory(dependencies = {}) {
30080
30148
  throw error52;
30081
30149
  }
30082
30150
  });
30151
+ const measureCapability = async () => {
30152
+ try {
30153
+ const playwright = await load();
30154
+ const executable = playwright.chromium.executablePath();
30155
+ if (!executable) return { status: "unavailable", error: BROWSER_INSTALL_REMEDY };
30156
+ await access3(executable);
30157
+ return { status: "ok" };
30158
+ } catch {
30159
+ return { status: "unavailable", error: BROWSER_INSTALL_REMEDY };
30160
+ }
30161
+ };
30083
30162
  return {
30084
30163
  kind: "playwright",
30085
30164
  async capability() {
30165
+ const measured = await measureCapability();
30166
+ if (measured.status === "ok") return measured;
30167
+ if (!installation) {
30168
+ dependencies.onInstallEvent?.({ state: "started" });
30169
+ const attempt = (async () => {
30170
+ await install();
30171
+ const installed = await measureCapability();
30172
+ if (installed.status !== "ok") {
30173
+ throw new Error("the browser executable is still unavailable after installation");
30174
+ }
30175
+ return installed;
30176
+ })();
30177
+ const tracked = attempt.then((installed) => {
30178
+ dependencies.onInstallEvent?.({ state: "completed" });
30179
+ return installed;
30180
+ }).catch((error52) => {
30181
+ dependencies.onInstallEvent?.({
30182
+ state: "failed",
30183
+ error: error52 instanceof Error ? error52.message : "unknown browser installation error"
30184
+ });
30185
+ throw error52;
30186
+ }).finally(() => {
30187
+ if (installation === tracked) installation = null;
30188
+ });
30189
+ installation = tracked;
30190
+ }
30086
30191
  try {
30087
- const playwright = await load();
30088
- const executable = playwright.chromium.executablePath();
30089
- if (!executable) return { status: "unavailable", error: BROWSER_INSTALL_REMEDY };
30090
- await access3(executable);
30091
- return { status: "ok" };
30192
+ return await installation;
30092
30193
  } catch {
30093
30194
  return { status: "unavailable", error: BROWSER_INSTALL_REMEDY };
30094
30195
  }
@@ -30598,11 +30699,11 @@ function createPlaywrightBrowserAdapterFactory(dependencies = {}) {
30598
30699
  }
30599
30700
 
30600
30701
  // src/runners/cli-runner.ts
30601
- import { spawn as spawn8 } from "node:child_process";
30702
+ import { spawn as spawn9 } from "node:child_process";
30602
30703
  import { randomUUID as randomUUID11 } from "node:crypto";
30603
30704
  import { lstat as lstat11, mkdir as mkdir11, realpath as realpath8 } from "node:fs/promises";
30604
30705
  import { homedir as homedir6 } from "node:os";
30605
- import { dirname as dirname8, isAbsolute as isAbsolute15, join as join15, resolve as resolve10 } from "node:path";
30706
+ import { dirname as dirname9, isAbsolute as isAbsolute15, join as join16, resolve as resolve10 } from "node:path";
30606
30707
 
30607
30708
  // src/tool-packs/browser/authentication-wall.ts
30608
30709
  var AUTH_PATH_SEGMENT = /(?:^|\/)(?:log[-_]?in|sign[-_]?in|sso|saml|auth|authorize|authenticate|oauth2?|session\/new|checkpoint)(?:\/|$)/i;
@@ -33420,16 +33521,16 @@ function createGithubPushOrchestrator(input) {
33420
33521
  }
33421
33522
 
33422
33523
  // src/tool-packs/github/git-bridge.ts
33423
- import { spawn as spawn6 } from "node:child_process";
33524
+ import { spawn as spawn7 } from "node:child_process";
33424
33525
  import { randomUUID as randomUUID8 } from "node:crypto";
33425
33526
  import { chmod as chmod4, lstat as lstat8, mkdir as mkdir7, realpath as realpath5, rm as rm7 } from "node:fs/promises";
33426
- import { dirname as dirname7, isAbsolute as isAbsolute11, join as join11, relative as relative6 } from "node:path";
33527
+ import { dirname as dirname8, isAbsolute as isAbsolute11, join as join12, relative as relative6 } from "node:path";
33427
33528
 
33428
33529
  // src/tool-packs/github/git-credential-broker.ts
33429
33530
  import { createServer } from "node:http";
33430
33531
  import { randomBytes, randomUUID as randomUUID7, timingSafeEqual } from "node:crypto";
33431
33532
  import { chmod as chmod3, lstat as lstat7, realpath as realpath4, writeFile as writeFile3 } from "node:fs/promises";
33432
- import { isAbsolute as isAbsolute10, join as join10, relative as relative5 } from "node:path";
33533
+ import { isAbsolute as isAbsolute10, join as join11, relative as relative5 } from "node:path";
33433
33534
  var MAX_REQUEST_BYTES = 16 * 1024;
33434
33535
  var FILE_MODE2 = 384;
33435
33536
  var HELPER_SOURCE = String.raw`'use strict';
@@ -33558,7 +33659,7 @@ async function createGithubGitCredentialBroker(input) {
33558
33659
  throw new Error("Git credential broker requires a private real run directory");
33559
33660
  }
33560
33661
  const runRoot = await realpath4(input.runArtifactsRoot);
33561
- const helperPath = join10(runRoot, `git-credential-${randomUUID7()}.cjs`);
33662
+ const helperPath = join11(runRoot, `git-credential-${randomUUID7()}.cjs`);
33562
33663
  assertChildPath(runRoot, helperPath);
33563
33664
  await writeFile3(helperPath, HELPER_SOURCE, { flag: "wx", mode: FILE_MODE2 });
33564
33665
  await chmod3(helperPath, FILE_MODE2);
@@ -33674,7 +33775,7 @@ async function requireRealDirectory2(path, label) {
33674
33775
  async function validateTokenlessPaths(command) {
33675
33776
  if (command.kind === "clone-from-bridge") {
33676
33777
  if (!isAbsolute11(command.destination)) throw new GithubGitProcessError("invalid_input");
33677
- const parent = await requireRealDirectory2(dirname7(command.destination), "clone parent");
33778
+ const parent = await requireRealDirectory2(dirname8(command.destination), "clone parent");
33678
33779
  assertBelow2(parent, command.destination, "clone destination");
33679
33780
  const destination = await lstat8(command.destination).catch((error52) => {
33680
33781
  if (error52.code === "ENOENT") return null;
@@ -33770,7 +33871,7 @@ async function runGit(input, args, env) {
33770
33871
  throw new GithubGitProcessError("invalid_input");
33771
33872
  }
33772
33873
  return new Promise((resolvePromise, rejectPromise) => {
33773
- const child = spawn6(input.executablePath, [...input.commandPrefixArgs ?? [], ...args], {
33874
+ const child = spawn7(input.executablePath, [...input.commandPrefixArgs ?? [], ...args], {
33774
33875
  cwd: input.trustedCwd,
33775
33876
  env,
33776
33877
  shell: false,
@@ -33962,7 +34063,7 @@ function createGithubGitBridge(input) {
33962
34063
  async createPrivateBridge() {
33963
34064
  if (closed) throw new GithubGitProcessError("cancelled");
33964
34065
  const current = await roots();
33965
- const path = join11(current.bridges, `${randomUUID8()}.git`);
34066
+ const path = join12(current.bridges, `${randomUUID8()}.git`);
33966
34067
  assertBelow2(current.bridges, path, "git bridge");
33967
34068
  await mkdir7(path, { mode: DIRECTORY_MODE2 });
33968
34069
  await chmod4(path, DIRECTORY_MODE2);
@@ -33980,11 +34081,11 @@ function createGithubGitBridge(input) {
33980
34081
  );
33981
34082
  const real = await requireRealDirectory2(path, "git bridge");
33982
34083
  assertBelow2(current.bridges, real, "git bridge");
33983
- const hooks = join11(real, "hooks");
34084
+ const hooks = join12(real, "hooks");
33984
34085
  await rm7(hooks, { recursive: true, force: true });
33985
34086
  await mkdir7(hooks, { mode: DIRECTORY_MODE2 });
33986
34087
  await chmod4(hooks, DIRECTORY_MODE2);
33987
- const config2 = join11(real, "config");
34088
+ const config2 = join12(real, "config");
33988
34089
  await chmod4(config2, 384);
33989
34090
  active.add(real);
33990
34091
  return real;
@@ -34433,7 +34534,7 @@ function createRepositoryTools(runtime) {
34433
34534
  // src/tool-packs/github/workspace.ts
34434
34535
  import { randomUUID as randomUUID9 } from "node:crypto";
34435
34536
  import { chmod as chmod5, lstat as lstat9, mkdir as mkdir8, readFile as readFile9, realpath as realpath6, rename as rename5, rm as rm8, writeFile as writeFile4 } from "node:fs/promises";
34436
- import { isAbsolute as isAbsolute12, join as join12, relative as relative7, resolve as resolve8 } from "node:path";
34537
+ import { isAbsolute as isAbsolute12, join as join13, relative as relative7, resolve as resolve8 } from "node:path";
34437
34538
  var SAFE_LOCAL_ID = /^[A-Za-z0-9_-]{1,200}$/;
34438
34539
  var FULL_NAME2 = /^[A-Za-z0-9_.-]{1,100}\/[A-Za-z0-9_.-]{1,100}$/;
34439
34540
  var DIRECTORY_MODE3 = 448;
@@ -34470,7 +34571,7 @@ async function requireRealDirectory3(path, label) {
34470
34571
  return real;
34471
34572
  }
34472
34573
  async function createOrRequirePrivateDirectory(parent, name, label) {
34473
- const path = join12(parent, name);
34574
+ const path = join13(parent, name);
34474
34575
  assertBelow3(parent, path, label);
34475
34576
  try {
34476
34577
  await mkdir8(path, { mode: DIRECTORY_MODE3 });
@@ -34553,8 +34654,8 @@ async function createGithubWorkspaceService(input) {
34553
34654
  if (expectedFullName !== void 0 && repository.fullName !== expectedFullName) {
34554
34655
  throw new Error("GitHub repository name does not match this task grant");
34555
34656
  }
34556
- const destination = join12(repositoriesRoot, parsed.data);
34557
- const metadataPath = join12(metadataRoot, `${parsed.data}.json`);
34657
+ const destination = join13(repositoriesRoot, parsed.data);
34658
+ const metadataPath = join13(metadataRoot, `${parsed.data}.json`);
34558
34659
  if (!await pathExists(destination) || !await pathExists(metadataPath)) {
34559
34660
  throw new Error("GitHub repository workspace has not been prepared");
34560
34661
  }
@@ -34571,14 +34672,14 @@ async function createGithubWorkspaceService(input) {
34571
34672
  return real;
34572
34673
  };
34573
34674
  const cloneRepository = async (clone2) => {
34574
- const destination = join12(repositoriesRoot, clone2.repositoryId);
34575
- const metadataPath = join12(metadataRoot, `${clone2.repositoryId}.json`);
34675
+ const destination = join13(repositoriesRoot, clone2.repositoryId);
34676
+ const metadataPath = join13(metadataRoot, `${clone2.repositoryId}.json`);
34576
34677
  assertBelow3(repositoriesRoot, destination, "repository path");
34577
34678
  assertBelow3(metadataRoot, metadataPath, "repository metadata");
34578
34679
  if (await pathExists(destination) || await pathExists(metadataPath)) {
34579
34680
  throw new Error("GitHub repository workspace already exists or is inconsistent");
34580
34681
  }
34581
- const temporary = join12(repositoriesRoot, `.clone-${randomUUID9()}`);
34682
+ const temporary = join13(repositoriesRoot, `.clone-${randomUUID9()}`);
34582
34683
  assertBelow3(repositoriesRoot, temporary, "temporary clone");
34583
34684
  try {
34584
34685
  await input.git.clone({
@@ -34603,7 +34704,7 @@ async function createGithubWorkspaceService(input) {
34603
34704
  path: destination,
34604
34705
  ...clone2.createIntentId === void 0 ? {} : { createIntentId: clone2.createIntentId }
34605
34706
  };
34606
- const metadataTemporary = join12(metadataRoot, `.${clone2.repositoryId}-${randomUUID9()}.tmp`);
34707
+ const metadataTemporary = join13(metadataRoot, `.${clone2.repositoryId}-${randomUUID9()}.tmp`);
34607
34708
  assertBelow3(metadataRoot, metadataTemporary, "temporary repository metadata");
34608
34709
  await writeFile4(metadataTemporary, `${JSON.stringify(metadata)}
34609
34710
  `, {
@@ -34638,8 +34739,8 @@ async function createGithubWorkspaceService(input) {
34638
34739
  };
34639
34740
  const prepareRepository = async (authority) => {
34640
34741
  const { repository } = authority;
34641
- const destination = join12(repositoriesRoot, repository.repositoryId);
34642
- const metadataPath = join12(metadataRoot, `${repository.repositoryId}.json`);
34742
+ const destination = join13(repositoriesRoot, repository.repositoryId);
34743
+ const metadataPath = join13(metadataRoot, `${repository.repositoryId}.json`);
34643
34744
  assertBelow3(repositoriesRoot, destination, "repository path");
34644
34745
  assertBelow3(metadataRoot, metadataPath, "repository metadata");
34645
34746
  return withWorkspaceLock(destination, async () => {
@@ -34804,7 +34905,7 @@ async function createGithubWorkspaceService(input) {
34804
34905
  throw new Error("GitHub created repository is outside this installation");
34805
34906
  }
34806
34907
  parseGitRef(cloneInput.repository.defaultBranch, "default branch");
34807
- return withWorkspaceLock(join12(repositoriesRoot, repositoryId2), async () => {
34908
+ return withWorkspaceLock(join13(repositoriesRoot, repositoryId2), async () => {
34808
34909
  const prepared = await cloneRepository({
34809
34910
  repositoryId: repositoryId2,
34810
34911
  fullName: cloneInput.repository.fullName,
@@ -36929,7 +37030,7 @@ function createCommsToolPacks(grants, context) {
36929
37030
 
36930
37031
  // src/runners/attachments.ts
36931
37032
  import { mkdir as mkdir9, writeFile as writeFile5 } from "node:fs/promises";
36932
- import { join as join13 } from "node:path";
37033
+ import { join as join14 } from "node:path";
36933
37034
  var WINDOWS_RESERVED = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\..*)?$/i;
36934
37035
  function sanitizeAttachmentFileName(name) {
36935
37036
  const base = name.split(/[/\\]/).pop() ?? "";
@@ -36958,9 +37059,9 @@ async function materializeAttachments(task, taskRoot) {
36958
37059
  `attached file "${attachment.name}" arrived incomplete (${bytes.byteLength} of ${attachment.size} bytes)`
36959
37060
  );
36960
37061
  }
36961
- const directory = join13(taskRoot, ".zixt-attachments", task.taskId, attachment.id);
37062
+ const directory = join14(taskRoot, ".zixt-attachments", task.taskId, attachment.id);
36962
37063
  await mkdir9(directory, { recursive: true });
36963
- const path = join13(directory, sanitizeAttachmentFileName(attachment.name));
37064
+ const path = join14(directory, sanitizeAttachmentFileName(attachment.name));
36964
37065
  await writeFile5(path, bytes);
36965
37066
  materialized.push({
36966
37067
  path,
@@ -38119,7 +38220,7 @@ import { execFile } from "node:child_process";
38119
38220
  import { randomBytes as randomBytes2, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
38120
38221
  import { chmod as chmod6, lstat as lstat10, mkdir as mkdir10, realpath as realpath7, writeFile as writeFile6 } from "node:fs/promises";
38121
38222
  import { createServer as createServer3 } from "node:http";
38122
- import { isAbsolute as isAbsolute14, join as join14, relative as relative8 } from "node:path";
38223
+ import { isAbsolute as isAbsolute14, join as join15, relative as relative8 } from "node:path";
38123
38224
  var MAX_REQUEST_BYTES2 = 16 * 1024;
38124
38225
  var DIRECTORY_MODE4 = 448;
38125
38226
  var PRIVATE_FILE_MODE = 384;
@@ -38507,7 +38608,7 @@ async function prepareHelpers(input) {
38507
38608
  throw new Error("GitHub shell authentication requires a private real run directory");
38508
38609
  }
38509
38610
  const runRoot = await realpath7(input.runRoot);
38510
- const helperPath = join14(runRoot, "github-shell-git-credential.cjs");
38611
+ const helperPath = join15(runRoot, "github-shell-git-credential.cjs");
38511
38612
  assertChildPath2(runRoot, helperPath);
38512
38613
  await writePrivate(helperPath, GIT_HELPER_SOURCE);
38513
38614
  if (!input.ghExecutablePath) {
@@ -38518,14 +38619,14 @@ async function prepareHelpers(input) {
38518
38619
  wrapperSourcePath: null
38519
38620
  };
38520
38621
  }
38521
- const shellToolsDirectory = join14(runRoot, "shell-tools");
38622
+ const shellToolsDirectory = join15(runRoot, "shell-tools");
38522
38623
  assertChildPath2(runRoot, shellToolsDirectory);
38523
38624
  await mkdir10(shellToolsDirectory, { mode: DIRECTORY_MODE4 });
38524
38625
  await chmod6(shellToolsDirectory, DIRECTORY_MODE4);
38525
- const wrapperSourcePath = join14(runRoot, "github-shell-gh-wrapper.cjs");
38626
+ const wrapperSourcePath = join15(runRoot, "github-shell-gh-wrapper.cjs");
38526
38627
  assertChildPath2(runRoot, wrapperSourcePath);
38527
38628
  await writePrivate(wrapperSourcePath, GH_WRAPPER_SOURCE);
38528
- const wrapperPath = join14(shellToolsDirectory, process.platform === "win32" ? "gh.cmd" : "gh");
38629
+ const wrapperPath = join15(shellToolsDirectory, process.platform === "win32" ? "gh.cmd" : "gh");
38529
38630
  assertChildPath2(runRoot, wrapperPath);
38530
38631
  const launcher = process.platform === "win32" ? `@"${process.execPath.replaceAll('"', '""')}" "${wrapperSourcePath.replaceAll('"', '""')}" %*\r
38531
38632
  ` : `#!/bin/sh
@@ -38748,7 +38849,7 @@ password=${credential.accessToken}
38748
38849
  }
38749
38850
 
38750
38851
  // src/runners/working-context.ts
38751
- import { spawn as spawn7 } from "node:child_process";
38852
+ import { spawn as spawn8 } from "node:child_process";
38752
38853
  import { resolve as resolve9 } from "node:path";
38753
38854
  var COMMAND_TIMEOUT_MS = 5e3;
38754
38855
  var OUTPUT_LIMIT_BYTES = 128 * 1024;
@@ -38879,7 +38980,7 @@ async function stopWorkingContextCommand(child, childExited, options = {}) {
38879
38980
  function run(command, args, cwd, env, signal) {
38880
38981
  if (signal?.aborted) return Promise.resolve(null);
38881
38982
  return new Promise((resolvePromise) => {
38882
- const child = spawn7(command, [...args], {
38983
+ const child = spawn8(command, [...args], {
38883
38984
  cwd,
38884
38985
  env: { ...env, GIT_OPTIONAL_LOCKS: "0" },
38885
38986
  detached: process.platform !== "win32",
@@ -39319,7 +39420,7 @@ async function settlesWithin(promise2, timeoutMs) {
39319
39420
  }
39320
39421
  }
39321
39422
  function defaultRunnerWorkspaceRoot() {
39322
- return join15(homedir6(), ".zixt", "workspaces");
39423
+ return join16(homedir6(), ".zixt", "workspaces");
39323
39424
  }
39324
39425
  function defaultRunnerArtifactRoot() {
39325
39426
  return defaultRunArtifactRoot();
@@ -39368,7 +39469,7 @@ function createCliRunner(adapter, opts = {}) {
39368
39469
  const prefixArgs = opts.commandPrefixArgs ?? [];
39369
39470
  const maxWallTimeMs = opts.maxWallTimeMs;
39370
39471
  const workspaceRoot = opts.workspaceRoot ?? defaultRunnerWorkspaceRoot();
39371
- const artifactRoot = opts.artifactRoot ?? (opts.workspaceRoot === void 0 ? defaultRunnerArtifactRoot() : join15(dirname8(workspaceRoot), "run-artifacts"));
39472
+ const artifactRoot = opts.artifactRoot ?? (opts.workspaceRoot === void 0 ? defaultRunnerArtifactRoot() : join16(dirname9(workspaceRoot), "run-artifacts"));
39372
39473
  const runRegistryRoot2 = opts.runRegistryRoot ?? defaultRunRegistryRoot();
39373
39474
  const createArtifacts = opts.createArtifacts ?? createRunArtifacts;
39374
39475
  const toolPackRegistry2 = opts.toolPackRegistry ?? createDefaultToolPackRegistry();
@@ -39386,7 +39487,7 @@ function createCliRunner(adapter, opts = {}) {
39386
39487
  };
39387
39488
  const askUserServer = createAskUserServer();
39388
39489
  const windowsRoot = process.env.SystemRoot ?? process.env.WINDIR;
39389
- const windowsComspecCandidate = process.platform === "win32" && windowsRoot ? join15(windowsRoot, "System32", "cmd.exe") : void 0;
39490
+ const windowsComspecCandidate = process.platform === "win32" && windowsRoot ? join16(windowsRoot, "System32", "cmd.exe") : void 0;
39390
39491
  let safetyFailure;
39391
39492
  return async (task) => {
39392
39493
  if (safetyFailure) {
@@ -39426,7 +39527,7 @@ function createCliRunner(adapter, opts = {}) {
39426
39527
  usage: { inputTokens: 0, outputTokens: 0 }
39427
39528
  };
39428
39529
  }
39429
- const taskRoot = join15(workspaceRoot, task.agentId);
39530
+ const taskRoot = join16(workspaceRoot, task.agentId);
39430
39531
  await mkdir11(taskRoot, { recursive: true });
39431
39532
  if (task.cancelledNow()) return cancelledBeforeRun();
39432
39533
  const configuredWorkspace = task.spec.workspace;
@@ -39764,7 +39865,7 @@ ${attachmentSection}` : prompt;
39764
39865
  for (const path of paths) {
39765
39866
  if (!path || path.length > 4096) continue;
39766
39867
  const absolutePath = isAbsolute15(path) ? path : resolve10(cwd, path);
39767
- const directory = dirname8(absolutePath);
39868
+ const directory = dirname9(absolutePath);
39768
39869
  observedWorkingDirectories.delete(directory);
39769
39870
  observedWorkingDirectories.add(directory);
39770
39871
  while (observedWorkingDirectories.size > 19) {
@@ -40199,7 +40300,7 @@ function runCliProcess(options) {
40199
40300
  return new Promise((resolve18) => {
40200
40301
  const platform = options.platform ?? process.platform;
40201
40302
  const containmentGateNonce = options.guardian && platform === "win32" ? randomUUID11() : void 0;
40202
- const child = options.guardian ? spawn8(
40303
+ const child = options.guardian ? spawn9(
40203
40304
  options.guardian.nodeCommand,
40204
40305
  [
40205
40306
  options.guardian.scriptPath,
@@ -40210,7 +40311,7 @@ function runCliProcess(options) {
40210
40311
  // The idle pre-assignment guardian must never load from or depend
40211
40312
  // on an untrusted Task checkout. Only the post-gate target enters
40212
40313
  // the requested working directory from its private release frame.
40213
- cwd: dirname8(options.guardian.scriptPath),
40314
+ cwd: dirname9(options.guardian.scriptPath),
40214
40315
  env: runnerGuardianEnv(process.env, containmentGateNonce),
40215
40316
  stdio: ["pipe", "pipe", "pipe"],
40216
40317
  windowsHide: true,
@@ -40492,7 +40593,7 @@ import { randomUUID as randomUUID12 } from "node:crypto";
40492
40593
  // src/runners/runtime-observation.ts
40493
40594
  import { open as open6, readdir as readdir5, realpath as realpath9 } from "node:fs/promises";
40494
40595
  import { homedir as homedir7 } from "node:os";
40495
- import { join as join16 } from "node:path";
40596
+ import { join as join17 } from "node:path";
40496
40597
  var READ_WINDOW_BYTES = 1024 * 1024;
40497
40598
  var CATALOG_TIMEOUT_MS = 15e3;
40498
40599
  var CATALOG_OUTPUT_LIMIT_BYTES = 4 * 1024 * 1024;
@@ -40552,9 +40653,9 @@ function displayValue(value, maxLength) {
40552
40653
  return trimmed;
40553
40654
  }
40554
40655
  function claudeTranscriptPath(input) {
40555
- const configDir = input.env["CLAUDE_CONFIG_DIR"] || join16(homeFrom(input.env), ".claude");
40656
+ const configDir = input.env["CLAUDE_CONFIG_DIR"] || join17(homeFrom(input.env), ".claude");
40556
40657
  const slug = input.resolvedCwd.replace(/[^a-zA-Z0-9]/g, "-");
40557
- return join16(configDir, "projects", slug, `${input.sessionId}.jsonl`);
40658
+ return join17(configDir, "projects", slug, `${input.sessionId}.jsonl`);
40558
40659
  }
40559
40660
  async function readClaudeSessionEffort(input) {
40560
40661
  const resolvedCwd = await realpath9(input.cwd).catch(() => input.cwd);
@@ -40570,18 +40671,18 @@ async function readClaudeSessionEffort(input) {
40570
40671
  }
40571
40672
  async function newestDirectories(root, limit) {
40572
40673
  const entries = await readdir5(root, { withFileTypes: true }).catch(() => []);
40573
- return entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort((left, right) => right.localeCompare(left)).slice(0, limit).map((name) => join16(root, name));
40674
+ return entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort((left, right) => right.localeCompare(left)).slice(0, limit).map((name) => join17(root, name));
40574
40675
  }
40575
40676
  async function findCodexRolloutPath(input) {
40576
- const codexHome = input.env["CODEX_HOME"] || join16(homeFrom(input.env), ".codex");
40577
- const sessions = join16(codexHome, "sessions");
40677
+ const codexHome = input.env["CODEX_HOME"] || join17(homeFrom(input.env), ".codex");
40678
+ const sessions = join17(codexHome, "sessions");
40578
40679
  const suffix = `-${input.threadId}.jsonl`;
40579
40680
  for (const year of await newestDirectories(sessions, 2)) {
40580
40681
  for (const month of await newestDirectories(year, 2)) {
40581
40682
  for (const day of await newestDirectories(month, 3)) {
40582
40683
  const files = await readdir5(day).catch(() => []);
40583
40684
  const match = files.find((name) => name.endsWith(suffix));
40584
- if (match) return join16(day, match);
40685
+ if (match) return join17(day, match);
40585
40686
  }
40586
40687
  }
40587
40688
  }
@@ -40978,15 +41079,15 @@ function improveErrorMessage(error52) {
40978
41079
  import { mkdir as mkdir12, readFile as readFile10, writeFile as writeFile7 } from "node:fs/promises";
40979
41080
  import { randomUUID as randomUUID13 } from "node:crypto";
40980
41081
  import { homedir as homedir8 } from "node:os";
40981
- import { join as join17 } from "node:path";
41082
+ import { join as join18 } from "node:path";
40982
41083
  var CODEX_NOT_FOUND_MESSAGE = "The `codex` CLI was not found on this Machine. Install it (npm install -g @openai/codex) and sign in with `codex login`, or switch the agent to API-key auth.";
40983
41084
  function defaultCodexThreadIndexRoot() {
40984
- return join17(homedir8(), ".zixt", "codex-threads");
41085
+ return join18(homedir8(), ".zixt", "codex-threads");
40985
41086
  }
40986
41087
  var SAFE_SEGMENT3 = /^[A-Za-z0-9_-]{1,200}$/;
40987
41088
  function threadIndexPath(root, agentId, sessionKey) {
40988
41089
  if (!SAFE_SEGMENT3.test(agentId) || !SAFE_SEGMENT3.test(sessionKey)) return null;
40989
- return join17(root, agentId, `${sessionKey}.json`);
41090
+ return join18(root, agentId, `${sessionKey}.json`);
40990
41091
  }
40991
41092
  async function readThreadId(path) {
40992
41093
  try {
@@ -41090,7 +41191,7 @@ ${value}` : value;
41090
41191
  const recordedThreadId = indexPath ? await readThreadId(indexPath) : null;
41091
41192
  const rememberThread = (threadId) => {
41092
41193
  if (!indexPath) return;
41093
- void mkdir12(join17(threadIndexRoot, task.agentId), { recursive: true }).then(() => writeFile7(indexPath, JSON.stringify({ threadId }), "utf8")).catch(() => {
41194
+ void mkdir12(join18(threadIndexRoot, task.agentId), { recursive: true }).then(() => writeFile7(indexPath, JSON.stringify({ threadId }), "utf8")).catch(() => {
41094
41195
  });
41095
41196
  };
41096
41197
  const observeRuntime = (threadId) => {
@@ -41553,7 +41654,7 @@ function improveCodexErrorMessage(error52) {
41553
41654
  }
41554
41655
 
41555
41656
  // src/runners/git-preflight.ts
41556
- import { spawn as spawn9 } from "node:child_process";
41657
+ import { spawn as spawn10 } from "node:child_process";
41557
41658
  import { realpath as realpath10 } from "node:fs/promises";
41558
41659
  import { isAbsolute as isAbsolute16, resolve as resolve11 } from "node:path";
41559
41660
  var OUTPUT_LIMIT = 8192;
@@ -41602,7 +41703,7 @@ async function preflightGit(options = {}) {
41602
41703
  }
41603
41704
  async function runVersionProbe(input) {
41604
41705
  return new Promise((resolvePromise) => {
41605
- const child = spawn9(input.executablePath, input.args, {
41706
+ const child = spawn10(input.executablePath, input.args, {
41606
41707
  cwd: input.cwd,
41607
41708
  env: {
41608
41709
  ...process.env.SystemRoot ? { SystemRoot: process.env.SystemRoot } : {},
@@ -41824,11 +41925,11 @@ function run2(command, args) {
41824
41925
  }
41825
41926
 
41826
41927
  // src/linux-service.ts
41827
- import { spawn as spawn10 } from "node:child_process";
41928
+ import { spawn as spawn11 } from "node:child_process";
41828
41929
  import { constants as constants2 } from "node:fs";
41829
41930
  import { access as access4, chmod as chmod7, mkdir as mkdir13, open as open7, rename as rename6, rm as rm9 } from "node:fs/promises";
41830
41931
  import { homedir as homedir9, userInfo } from "node:os";
41831
- import { basename as basename4, dirname as dirname9, join as join18, relative as relative9, resolve as resolve12, sep as sep5 } from "node:path";
41932
+ import { basename as basename4, dirname as dirname10, join as join19, relative as relative9, resolve as resolve12, sep as sep5 } from "node:path";
41832
41933
  var SERVICE_NAME = "zixt-host.service";
41833
41934
  var SYSTEM_SERVICE_COMMAND_TIMEOUT_MS = 7e4;
41834
41935
  var SERVICE_STABILITY_DELAY_MS = 2e3;
@@ -41857,7 +41958,7 @@ function boundedAppend(current, chunk) {
41857
41958
  async function defaultRunCommand(command, args) {
41858
41959
  const commandEnvironment3 = systemServiceCommandEnvironment();
41859
41960
  return new Promise((resolve18) => {
41860
- const child = spawn10(command, [...args], {
41961
+ const child = spawn11(command, [...args], {
41861
41962
  stdio: ["ignore", "pipe", "pipe"],
41862
41963
  env: commandEnvironment3,
41863
41964
  windowsHide: true
@@ -41933,18 +42034,18 @@ async function ensureDirectory(path, mode, syncDirectory8) {
41933
42034
  if (!firstCreated) return;
41934
42035
  const first = resolve12(firstCreated);
41935
42036
  const target = resolve12(path);
41936
- await syncDirectory8(dirname9(first));
42037
+ await syncDirectory8(dirname10(first));
41937
42038
  let current = first;
41938
42039
  const descendants = relative9(first, target);
41939
42040
  for (const part of descendants ? descendants.split(sep5) : []) {
41940
42041
  await syncDirectory8(current);
41941
- current = join18(current, part);
42042
+ current = join19(current, part);
41942
42043
  }
41943
42044
  }
41944
42045
  async function replacePrivateFile(path, contents, mode, syncDirectory8) {
41945
- const parent = dirname9(path);
42046
+ const parent = dirname10(path);
41946
42047
  await ensureDirectory(parent, 448, syncDirectory8);
41947
- const temporary = join18(parent, `.${basename4(path)}.${process.pid}.${crypto.randomUUID()}.tmp`);
42048
+ const temporary = join19(parent, `.${basename4(path)}.${process.pid}.${crypto.randomUUID()}.tmp`);
41948
42049
  const handle = await open7(temporary, "wx", mode);
41949
42050
  try {
41950
42051
  await handle.writeFile(contents, "utf8");
@@ -41996,11 +42097,11 @@ async function installLinuxService(options) {
41996
42097
  "command search path"
41997
42098
  );
41998
42099
  const cloudUrl = options.cloudUrl ? oneLine(options.cloudUrl, "Zixt Cloud address") : void 0;
41999
- const xdgConfigHome = env.XDG_CONFIG_HOME ? oneLine(env.XDG_CONFIG_HOME, "Linux configuration path") : join18(home, ".config");
42000
- const configRoot = options.serviceConfigRoot ?? join18(xdgConfigHome, "zixt");
42001
- const unitRoot = options.userUnitRoot ?? join18(xdgConfigHome, "systemd", "user");
42002
- const environmentPath = join18(configRoot, "host.env");
42003
- const unitPath = join18(unitRoot, SERVICE_NAME);
42100
+ const xdgConfigHome = env.XDG_CONFIG_HOME ? oneLine(env.XDG_CONFIG_HOME, "Linux configuration path") : join19(home, ".config");
42101
+ const configRoot = options.serviceConfigRoot ?? join19(xdgConfigHome, "zixt");
42102
+ const unitRoot = options.userUnitRoot ?? join19(xdgConfigHome, "systemd", "user");
42103
+ const environmentPath = join19(configRoot, "host.env");
42104
+ const unitPath = join19(unitRoot, SERVICE_NAME);
42004
42105
  const installVersion = options.installVersion ?? installRelease;
42005
42106
  const activateVersion = options.activateVersion ?? (options.installVersion ? async (entry) => entry : activateInstalledRelease);
42006
42107
  const resolveCommand = options.resolveCommand ?? defaultResolveCommand;
@@ -42117,11 +42218,11 @@ async function installLinuxService(options) {
42117
42218
  }
42118
42219
 
42119
42220
  // src/macos-service.ts
42120
- import { spawn as spawn11 } from "node:child_process";
42221
+ import { spawn as spawn12 } from "node:child_process";
42121
42222
  import { constants as constants3 } from "node:fs";
42122
42223
  import { access as access5, chmod as chmod8, mkdir as mkdir14, open as open8, rename as rename7, rm as rm10 } from "node:fs/promises";
42123
42224
  import { homedir as homedir10, userInfo as userInfo2 } from "node:os";
42124
- import { basename as basename5, dirname as dirname10, join as join19, relative as relative10, resolve as resolve13, sep as sep6 } from "node:path";
42225
+ import { basename as basename5, dirname as dirname11, join as join20, relative as relative10, resolve as resolve13, sep as sep6 } from "node:path";
42125
42226
  var LAUNCH_AGENT_LABEL = "ai.zixt.host";
42126
42227
  var SERVICE_STABILITY_DELAY_MS2 = 2e3;
42127
42228
  var COMMAND_TIMEOUT_MS2 = 7e4;
@@ -42149,17 +42250,17 @@ async function ensureDirectory2(path, sync) {
42149
42250
  if (!firstCreated) return;
42150
42251
  const first = resolve13(firstCreated);
42151
42252
  const target = resolve13(path);
42152
- await sync(dirname10(first));
42253
+ await sync(dirname11(first));
42153
42254
  let current = first;
42154
42255
  for (const part of relative10(first, target).split(sep6).filter(Boolean)) {
42155
42256
  await sync(current);
42156
- current = join19(current, part);
42257
+ current = join20(current, part);
42157
42258
  }
42158
42259
  }
42159
42260
  async function replacePrivateFile2(path, contents, mode, sync) {
42160
- const parent = dirname10(path);
42261
+ const parent = dirname11(path);
42161
42262
  await ensureDirectory2(parent, sync);
42162
- const temporary = join19(parent, `.${basename5(path)}.${process.pid}.${crypto.randomUUID()}.tmp`);
42263
+ const temporary = join20(parent, `.${basename5(path)}.${process.pid}.${crypto.randomUUID()}.tmp`);
42163
42264
  const handle = await open8(temporary, "wx", mode);
42164
42265
  try {
42165
42266
  await handle.writeFile(contents, "utf8");
@@ -42184,7 +42285,7 @@ function commandEnvironment(env) {
42184
42285
  }
42185
42286
  async function defaultRunCommand2(command, args, env) {
42186
42287
  return new Promise((resolveResult) => {
42187
- const child = spawn11(command, [...args], {
42288
+ const child = spawn12(command, [...args], {
42188
42289
  stdio: ["ignore", "pipe", "pipe"],
42189
42290
  env: commandEnvironment(env)
42190
42291
  });
@@ -42256,14 +42357,14 @@ async function installMacosService(options) {
42256
42357
  options.path ?? env.PATH ?? "/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin",
42257
42358
  "command search path"
42258
42359
  );
42259
- const configRoot = options.configRoot ?? join19(home, "Library", "Application Support", "Zixt");
42260
- const launchAgentsRoot = options.launchAgentsRoot ?? join19(home, "Library", "LaunchAgents");
42261
- const logRoot = options.logRoot ?? join19(home, "Library", "Logs", "Zixt");
42262
- const configPath = join19(configRoot, "host.env");
42263
- const launcherPath = join19(configRoot, "host-launcher.sh");
42264
- const plistPath = join19(launchAgentsRoot, `${LAUNCH_AGENT_LABEL}.plist`);
42265
- const stdoutPath = join19(logRoot, "host.log");
42266
- const stderrPath = join19(logRoot, "host-error.log");
42360
+ const configRoot = options.configRoot ?? join20(home, "Library", "Application Support", "Zixt");
42361
+ const launchAgentsRoot = options.launchAgentsRoot ?? join20(home, "Library", "LaunchAgents");
42362
+ const logRoot = options.logRoot ?? join20(home, "Library", "Logs", "Zixt");
42363
+ const configPath = join20(configRoot, "host.env");
42364
+ const launcherPath = join20(configRoot, "host-launcher.sh");
42365
+ const plistPath = join20(launchAgentsRoot, `${LAUNCH_AGENT_LABEL}.plist`);
42366
+ const stdoutPath = join20(logRoot, "host.log");
42367
+ const stderrPath = join20(logRoot, "host-error.log");
42267
42368
  const installVersion = options.installVersion ?? installRelease;
42268
42369
  const activateVersion = options.activateVersion ?? (options.installVersion ? async (entry) => entry : (entry) => activateInstalledRelease(entry));
42269
42370
  const resolveCommand = options.resolveCommand ?? (async () => defaultResolveCommand2());
@@ -42348,11 +42449,11 @@ async function installMacosService(options) {
42348
42449
  }
42349
42450
 
42350
42451
  // src/windows-service.ts
42351
- import { spawn as spawn12 } from "node:child_process";
42452
+ import { spawn as spawn13 } from "node:child_process";
42352
42453
  import { constants as constants4 } from "node:fs";
42353
42454
  import { access as access6, mkdir as mkdir15, open as open9, readFile as readFile11, rename as rename8, rm as rm11 } from "node:fs/promises";
42354
42455
  import { homedir as homedir11 } from "node:os";
42355
- import { basename as basename6, dirname as dirname11, isAbsolute as isAbsolute17, join as join20, relative as relative11, resolve as resolve14, sep as sep7 } from "node:path";
42456
+ import { basename as basename6, dirname as dirname12, isAbsolute as isAbsolute17, join as join21, relative as relative11, resolve as resolve14, sep as sep7 } from "node:path";
42356
42457
  var TASK_NAME = "Zixt Host";
42357
42458
  var COMMAND_TIMEOUT_MS3 = 7e4;
42358
42459
  var SERVICE_STABILITY_DELAY_MS3 = 2e3;
@@ -42382,17 +42483,17 @@ async function ensureDirectory3(path, sync) {
42382
42483
  if (!firstCreated) return;
42383
42484
  const first = resolve14(firstCreated);
42384
42485
  const target = resolve14(path);
42385
- await sync(dirname11(first));
42486
+ await sync(dirname12(first));
42386
42487
  let current = first;
42387
42488
  for (const part of relative11(first, target).split(sep7).filter(Boolean)) {
42388
42489
  await sync(current);
42389
- current = join20(current, part);
42490
+ current = join21(current, part);
42390
42491
  }
42391
42492
  }
42392
42493
  async function replacePrivateFile3(path, contents, sync) {
42393
- const parent = dirname11(path);
42494
+ const parent = dirname12(path);
42394
42495
  await ensureDirectory3(parent, sync);
42395
- const temporary = join20(parent, `.${basename6(path)}.${process.pid}.${crypto.randomUUID()}.tmp`);
42496
+ const temporary = join21(parent, `.${basename6(path)}.${process.pid}.${crypto.randomUUID()}.tmp`);
42396
42497
  const handle = await open9(temporary, "wx", 384);
42397
42498
  try {
42398
42499
  await handle.writeFile(contents, "utf8");
@@ -42413,7 +42514,7 @@ function commandEnvironment2(env) {
42413
42514
  }
42414
42515
  async function runChild(command, args, env, input) {
42415
42516
  return new Promise((resolveResult) => {
42416
- const child = spawn12(command, [...args], {
42517
+ const child = spawn13(command, [...args], {
42417
42518
  stdio: [input === void 0 ? "ignore" : "pipe", "pipe", "pipe"],
42418
42519
  env: commandEnvironment2(env),
42419
42520
  windowsHide: true
@@ -42447,7 +42548,7 @@ async function runChild(command, args, env, input) {
42447
42548
  async function defaultResolveCommand3(name, env) {
42448
42549
  const root = env.SYSTEMROOT ?? env.WINDIR;
42449
42550
  if (!root || !isAbsolute17(root)) return null;
42450
- const candidate = name === "powershell" ? join20(root, "System32", "WindowsPowerShell", "v1.0", "powershell.exe") : join20(root, "System32", `${name}.exe`);
42551
+ const candidate = name === "powershell" ? join21(root, "System32", "WindowsPowerShell", "v1.0", "powershell.exe") : join21(root, "System32", `${name}.exe`);
42451
42552
  return access6(candidate, constants4.X_OK).then(
42452
42553
  () => candidate,
42453
42554
  () => null
@@ -42584,11 +42685,11 @@ async function installWindowsService(options) {
42584
42685
  const token2 = oneLine3(options.token, "pairing code");
42585
42686
  const cloudUrl = options.cloudUrl ? oneLine3(options.cloudUrl, "Zixt Cloud address") : void 0;
42586
42687
  const path = oneLine3(options.path ?? env.PATH ?? "", "command search path");
42587
- const configRoot = options.configRoot ?? join20(localAppData, "Zixt", "Host");
42588
- const configPath = join20(configRoot, "host.json");
42589
- const launcherPath = join20(configRoot, "host-launcher.ps1");
42590
- const taskXmlPath = join20(configRoot, "host-task.xml");
42591
- const statusPath = join20(configRoot, "host-status.json");
42688
+ const configRoot = options.configRoot ?? join21(localAppData, "Zixt", "Host");
42689
+ const configPath = join21(configRoot, "host.json");
42690
+ const launcherPath = join21(configRoot, "host-launcher.ps1");
42691
+ const taskXmlPath = join21(configRoot, "host-task.xml");
42692
+ const statusPath = join21(configRoot, "host-status.json");
42592
42693
  const installVersion = options.installVersion ?? installRelease;
42593
42694
  const activateVersion = options.activateVersion ?? (options.installVersion ? async (entry) => entry : (entry) => activateInstalledRelease(entry));
42594
42695
  const resolveCommand = options.resolveCommand ?? ((name) => defaultResolveCommand3(name, env));
@@ -42691,21 +42792,21 @@ async function installSystemService(options) {
42691
42792
  // src/terminal-outcomes.ts
42692
42793
  import { chmod as chmod9, lstat as lstat12, mkdir as mkdir16, open as open10, readdir as readdir6, readFile as readFile12, rename as rename9, rm as rm12 } from "node:fs/promises";
42693
42794
  import { homedir as homedir12 } from "node:os";
42694
- import { dirname as dirname12, join as join21, relative as relative12, resolve as resolve15, sep as sep8 } from "node:path";
42795
+ import { dirname as dirname13, join as join22, relative as relative12, resolve as resolve15, sep as sep8 } from "node:path";
42695
42796
  var DIRECTORY_MODE5 = 448;
42696
42797
  var FILE_MODE4 = 384;
42697
42798
  var MAX_OUTCOME_BYTES = 4 * 1024 * 1024;
42698
42799
  var HOST_DIRECTORY = /^hst_[0-9a-f]{32}$/;
42699
42800
  var OUTCOME_FILE = /^(tsk_[0-9a-f]{32})\.([1-9][0-9]*)\.json$/;
42700
42801
  function defaultTerminalOutcomeRoot() {
42701
- return join21(homedir12(), ".zixt", "terminal-outcomes");
42802
+ return join22(homedir12(), ".zixt", "terminal-outcomes");
42702
42803
  }
42703
42804
  function hostOutcomeRoot(root, hostId) {
42704
42805
  if (!HOST_DIRECTORY.test(hostId)) throw new Error("terminal outcome Host identity is malformed");
42705
- return join21(root, hostId);
42806
+ return join22(root, hostId);
42706
42807
  }
42707
42808
  function outcomePath(root, hostId, taskId, epoch) {
42708
- return join21(hostOutcomeRoot(root, hostId), `${taskId}.${epoch}.json`);
42809
+ return join22(hostOutcomeRoot(root, hostId), `${taskId}.${epoch}.json`);
42709
42810
  }
42710
42811
  async function syncDirectory6(root) {
42711
42812
  if (process.platform === "win32") return;
@@ -42721,11 +42822,11 @@ async function requirePrivateRoot(root, sync = syncDirectory6) {
42721
42822
  if (firstCreated) {
42722
42823
  const first = resolve15(firstCreated);
42723
42824
  const target = resolve15(root);
42724
- await sync(dirname12(first));
42825
+ await sync(dirname13(first));
42725
42826
  let current = first;
42726
42827
  for (const part of relative12(first, target).split(sep8).filter(Boolean)) {
42727
42828
  await sync(current);
42728
- current = join21(current, part);
42829
+ current = join22(current, part);
42729
42830
  }
42730
42831
  }
42731
42832
  const stat3 = await lstat12(root);
@@ -42765,7 +42866,7 @@ async function recordTerminalOutcome(hostId, input, root = defaultTerminalOutcom
42765
42866
  } catch (error52) {
42766
42867
  if (error52.code !== "ENOENT") throw error52;
42767
42868
  }
42768
- const temporary = join21(
42869
+ const temporary = join22(
42769
42870
  scopedRoot,
42770
42871
  `.${outcome.taskId}.${outcome.epoch}.${process.pid}.${Date.now()}.${outcome.resultId}.tmp`
42771
42872
  );
@@ -42818,7 +42919,7 @@ async function readTerminalOutcomesStrict(root = defaultTerminalOutcomeRoot()) {
42818
42919
  if (!match || !entry.isFile() || entry.isSymbolicLink()) {
42819
42920
  throw new Error("committed terminal outcome is not a trusted regular file");
42820
42921
  }
42821
- const path = join21(scopedRoot, entry.name);
42922
+ const path = join22(scopedRoot, entry.name);
42822
42923
  const stat3 = await lstat12(path);
42823
42924
  if (!stat3.isFile() || stat3.isSymbolicLink() || stat3.size > MAX_OUTCOME_BYTES) {
42824
42925
  throw new Error("committed terminal outcome is not a trusted regular file");
@@ -42872,13 +42973,13 @@ async function forgetSupersededTerminalOutcomes(hostId, taskId, epoch, root = de
42872
42973
  // src/accepted-assignments.ts
42873
42974
  import { chmod as chmod10, lstat as lstat13, mkdir as mkdir17, open as open11, readdir as readdir7, rename as rename10, rm as rm13 } from "node:fs/promises";
42874
42975
  import { homedir as homedir13 } from "node:os";
42875
- import { dirname as dirname13, join as join22, relative as relative13, resolve as resolve16, sep as sep9 } from "node:path";
42976
+ import { dirname as dirname14, join as join23, relative as relative13, resolve as resolve16, sep as sep9 } from "node:path";
42876
42977
  var DIRECTORY_MODE6 = 448;
42877
42978
  var FILE_MODE5 = 384;
42878
42979
  var CLAIM_FILE = /^(tsk_[0-9a-f]{32})\.([1-9][0-9]*)\.json$/;
42879
42980
  var TASK_ID = /^tsk_[0-9a-f]{32}$/;
42880
42981
  function defaultAcceptedAssignmentRoot() {
42881
- return join22(homedir13(), ".zixt", "accepted-assignments");
42982
+ return join23(homedir13(), ".zixt", "accepted-assignments");
42882
42983
  }
42883
42984
  async function syncDirectory7(root) {
42884
42985
  if (process.platform === "win32") return;
@@ -42894,11 +42995,11 @@ async function requirePrivateRoot2(root, sync = syncDirectory7) {
42894
42995
  if (firstCreated) {
42895
42996
  const first = resolve16(firstCreated);
42896
42997
  const target = resolve16(root);
42897
- await sync(dirname13(first));
42998
+ await sync(dirname14(first));
42898
42999
  let current = first;
42899
43000
  for (const part of relative13(first, target).split(sep9).filter(Boolean)) {
42900
43001
  await sync(current);
42901
- current = join22(current, part);
43002
+ current = join23(current, part);
42902
43003
  }
42903
43004
  }
42904
43005
  const stat3 = await lstat13(root);
@@ -42912,7 +43013,7 @@ function claimPath(root, taskId, epoch) {
42912
43013
  if (!Number.isSafeInteger(epoch) || epoch < 1) {
42913
43014
  throw new Error("accepted assignment epoch is malformed");
42914
43015
  }
42915
- return join22(root, `${taskId}.${epoch}.json`);
43016
+ return join23(root, `${taskId}.${epoch}.json`);
42916
43017
  }
42917
43018
  async function recordAcceptedAssignment(assignment, root = defaultAcceptedAssignmentRoot(), options = {}) {
42918
43019
  const sync = options.syncDirectory ?? syncDirectory7;
@@ -42922,7 +43023,7 @@ async function recordAcceptedAssignment(assignment, root = defaultAcceptedAssign
42922
43023
  } catch {
42923
43024
  return false;
42924
43025
  }
42925
- const temporary = join22(
43026
+ const temporary = join23(
42926
43027
  root,
42927
43028
  `.${assignment.taskId}.${assignment.epoch}.${process.pid}.${Date.now()}.tmp`
42928
43029
  );
@@ -43085,7 +43186,7 @@ function createHostLogger(options = {}) {
43085
43186
  }
43086
43187
 
43087
43188
  // src/demo-state.ts
43088
- import { isAbsolute as isAbsolute18, join as join23, parse as parse3, resolve as resolve17 } from "node:path";
43189
+ import { isAbsolute as isAbsolute18, join as join24, parse as parse3, resolve as resolve17 } from "node:path";
43089
43190
  var DEMO_STATE_ROOT_ENV = "ZIXT_DEMO_STATE_ROOT";
43090
43191
  function resolveDemoHostStatePaths(env = process.env) {
43091
43192
  const configured = env.ZIXT_RUNNER === "demo" ? env[DEMO_STATE_ROOT_ENV] : void 0;
@@ -43095,13 +43196,13 @@ function resolveDemoHostStatePaths(env = process.env) {
43095
43196
  throw new Error(`${DEMO_STATE_ROOT_ENV} must be a dedicated absolute directory`);
43096
43197
  }
43097
43198
  return {
43098
- runRegistryRoot: join23(root, "run-registry"),
43099
- terminalOutcomeRoot: join23(root, "terminal-outcomes"),
43100
- acceptedAssignmentRoot: join23(root, "accepted-assignments"),
43101
- runArtifactRoot: join23(root, "run-artifacts"),
43102
- browserProfileRoot: join23(root, "browser-profiles"),
43103
- runnerWorkspaceRoot: join23(root, "workspaces"),
43104
- codexThreadIndexRoot: join23(root, "codex-threads")
43199
+ runRegistryRoot: join24(root, "run-registry"),
43200
+ terminalOutcomeRoot: join24(root, "terminal-outcomes"),
43201
+ acceptedAssignmentRoot: join24(root, "accepted-assignments"),
43202
+ runArtifactRoot: join24(root, "run-artifacts"),
43203
+ browserProfileRoot: join24(root, "browser-profiles"),
43204
+ runnerWorkspaceRoot: join24(root, "workspaces"),
43205
+ codexThreadIndexRoot: join24(root, "codex-threads")
43105
43206
  };
43106
43207
  }
43107
43208
 
@@ -43430,7 +43531,22 @@ var restartAfterUnsafeRunnerCleanup = (reason) => {
43430
43531
  };
43431
43532
  var browserManager = new BrowserManager({
43432
43533
  ...browserProfileRoot ? { profileRoot: browserProfileRoot } : {},
43433
- factory: process.env.ZIXT_BROWSER === "demo" ? createDemoBrowserAdapterFactory() : createPlaywrightBrowserAdapterFactory()
43534
+ factory: process.env.ZIXT_BROWSER === "demo" ? createDemoBrowserAdapterFactory() : createPlaywrightBrowserAdapterFactory({
43535
+ onInstallEvent: (event) => {
43536
+ if (event.state === "started") {
43537
+ log.info("Browser not found; installing Chromium for this Zixt version", {
43538
+ machine
43539
+ });
43540
+ } else if (event.state === "completed") {
43541
+ log.success("Browser installation complete", { machine });
43542
+ } else {
43543
+ log.warn("Browser installation failed", {
43544
+ machine,
43545
+ ...event.error ? { error: event.error } : {}
43546
+ });
43547
+ }
43548
+ }
43549
+ })
43434
43550
  });
43435
43551
  var claudeCode = createClaudeCodeRunner({
43436
43552
  ...runnerWorkspaceRoot ? { workspaceRoot: runnerWorkspaceRoot } : {},
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zixt/host",
3
- "version": "0.0.109",
3
+ "version": "0.0.111",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./src/client.ts",