@zixt/host 0.0.136 → 0.0.138

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 +797 -180
  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.136",
31
+ version: "0.0.138",
32
32
  type: "module",
33
33
  exports: {
34
34
  ".": "./src/client.ts",
@@ -14676,6 +14676,8 @@ var ID_PREFIXES = {
14676
14676
  managerApiAction: "maa",
14677
14677
  /** One Manager-prepared Webhook Automation setup card (MG-21). */
14678
14678
  managerWebhookAction: "mwa",
14679
+ /** One Manager-prepared Email Integration setup card (MG-24). */
14680
+ managerEmailSetup: "mes",
14679
14681
  /** One Manager-authored questionnaire waiting in a Conversation. */
14680
14682
  managerQuestionnaire: "mqu",
14681
14683
  /** One Manager inference call's token-metering row (MG-8). */
@@ -14763,6 +14765,10 @@ var ManagerWebhookActionId = idSchema(
14763
14765
  ID_PREFIXES.managerWebhookAction,
14764
14766
  "Manager webhook action id"
14765
14767
  );
14768
+ var ManagerEmailSetupId = idSchema(
14769
+ ID_PREFIXES.managerEmailSetup,
14770
+ "Manager email setup id"
14771
+ );
14766
14772
  var ManagerQuestionnaireId = idSchema(
14767
14773
  ID_PREFIXES.managerQuestionnaire,
14768
14774
  "Manager questionnaire id"
@@ -19861,7 +19867,9 @@ var ConversationEventProjection = external_exports.discriminatedUnion("kind", [
19861
19867
  /** Present only for a Webhook Automation secure setup card (MG-21). */
19862
19868
  webhookActionId: ManagerWebhookActionId.nullable().optional(),
19863
19869
  /** Present only for a Manager-authored questionnaire (MG-22). */
19864
- questionnaireId: ManagerQuestionnaireId.nullable().optional()
19870
+ questionnaireId: ManagerQuestionnaireId.nullable().optional(),
19871
+ /** Present only for an Email Integration setup card (MG-24). */
19872
+ emailSetupId: ManagerEmailSetupId.nullable().optional()
19865
19873
  }).strict(),
19866
19874
  /** A mirrored child-Task event: what the teammate wrote or became. */
19867
19875
  external_exports.object({
@@ -19934,6 +19942,44 @@ var ManagerIntegrationActionResponse = external_exports.object({
19934
19942
  action: ManagerIntegrationActionProjection,
19935
19943
  oauth: ManagerIntegrationOAuthStart.nullable()
19936
19944
  }).strict();
19945
+ var ManagerEmailSetupPrefill = external_exports.object({
19946
+ /** Connection name as it will appear under Integrations. */
19947
+ name: external_exports.string().min(1).max(120).optional(),
19948
+ provider: EmailProviderPreset.optional(),
19949
+ mode: EmailConnectionMode.optional(),
19950
+ fromName: external_exports.string().max(200).optional(),
19951
+ fromAddress: external_exports.string().max(320).optional(),
19952
+ replyTo: external_exports.string().max(320).optional(),
19953
+ usageNotes: external_exports.string().max(4e3).optional(),
19954
+ /** custom provider only; presets carry their own servers. */
19955
+ smtpHost: external_exports.string().max(255).optional(),
19956
+ smtpPort: external_exports.number().int().min(1).max(65535).optional(),
19957
+ incomingHost: external_exports.string().max(255).optional(),
19958
+ incomingPort: external_exports.number().int().min(1).max(65535).optional(),
19959
+ /** Sign-in name for the mailbox, when the person said it. Never a password. */
19960
+ username: external_exports.string().max(320).optional(),
19961
+ watch: external_exports.object({
19962
+ enabled: external_exports.boolean(),
19963
+ senderContains: external_exports.string().max(200).optional(),
19964
+ recipientContains: external_exports.string().max(200).optional(),
19965
+ subjectContains: external_exports.string().max(200).optional(),
19966
+ instructions: external_exports.string().max(2e4).optional()
19967
+ }).strict().optional()
19968
+ }).strict();
19969
+ var ManagerEmailSetupStatus = external_exports.enum(["open", "completed", "dismissed"]);
19970
+ var ManagerEmailSetupProjection = external_exports.object({
19971
+ id: ManagerEmailSetupId,
19972
+ conversationId: ConversationId,
19973
+ prefill: ManagerEmailSetupPrefill,
19974
+ status: ManagerEmailSetupStatus,
19975
+ /** True when the requesting member is the person this card was prepared for. */
19976
+ mine: external_exports.boolean(),
19977
+ /** The Email connection the card produced; present once completed. */
19978
+ connectionId: external_exports.string().nullable(),
19979
+ connectionName: external_exports.string().max(120).nullable(),
19980
+ createdAt: external_exports.string()
19981
+ }).strict();
19982
+ var CompleteManagerEmailSetupRequest = external_exports.object({ connectionId: external_exports.string().min(1).max(100) }).strict();
19937
19983
  var ManagerCredentialRequestStatus = external_exports.enum([
19938
19984
  "awaiting_entry",
19939
19985
  "storing",
@@ -22562,6 +22608,12 @@ var CompanySetupProgress = external_exports.object({
22562
22608
  /** Every recommended step is done or skipped. */
22563
22609
  recommendedSettled: external_exports.boolean()
22564
22610
  });
22611
+ var COMPANY_SETUP_PLANNING_NOTE_MAX = 200;
22612
+ var COMPANY_SETUP_PLANNING_NOTES_MAX = 20;
22613
+ var CompanySetupPlanningNote = external_exports.object({
22614
+ at: IsoDate,
22615
+ text: external_exports.string().trim().min(1).max(COMPANY_SETUP_PLANNING_NOTE_MAX)
22616
+ });
22565
22617
  var CompanySetupApproval = external_exports.object({
22566
22618
  at: IsoDate,
22567
22619
  by: MemberId.nullable(),
@@ -22614,7 +22666,12 @@ var CompanySetupView = external_exports.object({
22614
22666
  * The plan is being proposed in the background (a planner call can take a
22615
22667
  * minute); the page polls until the plan lands or an error is recorded.
22616
22668
  */
22617
- planning: external_exports.object({ startedAt: IsoDate, error: external_exports.string().max(500).nullable() }).nullable(),
22669
+ planning: external_exports.object({
22670
+ startedAt: IsoDate,
22671
+ error: external_exports.string().max(500).nullable(),
22672
+ /** Oldest first; the planner's visible decisions so far. */
22673
+ notes: external_exports.array(CompanySetupPlanningNote).max(COMPANY_SETUP_PLANNING_NOTES_MAX).default([])
22674
+ }).nullable(),
22618
22675
  approval: CompanySetupApproval.nullable(),
22619
22676
  steps: external_exports.array(CompanySetupStep),
22620
22677
  progress: CompanySetupProgress,
@@ -31705,11 +31762,11 @@ function createPlaywrightBrowserAdapterFactory(dependencies = {}) {
31705
31762
  }
31706
31763
 
31707
31764
  // src/runners/cli-runner.ts
31708
- import { spawn as spawn10 } from "node:child_process";
31709
- import { randomUUID as randomUUID11 } from "node:crypto";
31710
- import { lstat as lstat11, mkdir as mkdir12, realpath as realpath8 } from "node:fs/promises";
31765
+ import { spawn as spawn11 } from "node:child_process";
31766
+ import { randomUUID as randomUUID12 } from "node:crypto";
31767
+ import { lstat as lstat11, mkdir as mkdir13, realpath as realpath8 } from "node:fs/promises";
31711
31768
  import { homedir as homedir7 } from "node:os";
31712
- import { dirname as dirname10, isAbsolute as isAbsolute16, join as join18, resolve as resolve10 } from "node:path";
31769
+ import { dirname as dirname10, isAbsolute as isAbsolute16, join as join19, resolve as resolve10 } from "node:path";
31713
31770
 
31714
31771
  // src/tool-packs/browser/authentication-wall.ts
31715
31772
  var AUTH_PATH_SEGMENT = /(?:^|\/)(?:log[-_]?in|sign[-_]?in|sso|saml|auth|authorize|authenticate|oauth2?|session\/new|checkpoint)(?:\/|$)/i;
@@ -38096,6 +38153,415 @@ function renderAttachmentSection(files) {
38096
38153
 
38097
38154
  // src/runners/ask-user-server.ts
38098
38155
  import { createServer as createServer2 } from "node:http";
38156
+
38157
+ // src/runners/software-install.ts
38158
+ import { spawn as spawn9 } from "node:child_process";
38159
+ import { createHash as createHash6, randomUUID as randomUUID11 } from "node:crypto";
38160
+ import { chmod as chmod6, mkdir as mkdir11, readFile as readFile10, readdir as readdir5, rename as rename6, rm as rm10, symlink as symlink2, writeFile as writeFile7 } from "node:fs/promises";
38161
+ import { join as join17, relative as relative8, resolve as resolvePath, sep as sep5 } from "node:path";
38162
+ var SOFTWARE_INSTALL_METHODS = ["npm", "download"];
38163
+ var SOFTWARE_INSTALL_REFUSAL = "Zixt installs software only into its own folder on this Machine, using npm or a direct download. It never runs a system package manager, never asks for elevation, and never builds from source. Tell the person plainly what is missing, why this work needs it, and the exact command they would run themselves.";
38164
+ var MAX_DOWNLOAD_BYTES = 512 * 1024 * 1024;
38165
+ var PROCESS_TIMEOUT_MS = 10 * 6e4;
38166
+ var DOWNLOAD_TIMEOUT_MS = 10 * 6e4;
38167
+ var FAILURE_COOLDOWN_MS2 = 10 * 6e4;
38168
+ var MAX_ARCHIVE_SEARCH_DEPTH = 5;
38169
+ var MANIFEST_NAME = "installed.json";
38170
+ var COMMAND_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._+-]{0,63}$/;
38171
+ var NPM_SPEC_PATTERN = /^(?:@[a-z0-9~][a-z0-9._~-]*\/)?[a-z0-9~][a-z0-9._~-]*(?:@\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?)?$/;
38172
+ function defaultSoftwareToolsRoot() {
38173
+ return defaultRunnerToolsRoot();
38174
+ }
38175
+ function softwareSearchPathEntries(toolsRoot = defaultSoftwareToolsRoot()) {
38176
+ return [toolsRoot, join17(toolsRoot, "bin")];
38177
+ }
38178
+ function refuseSoftwareRequest(request) {
38179
+ if (!COMMAND_PATTERN.test(request.command)) {
38180
+ return "The command name must be a plain executable name with no path, spaces, or shell characters.";
38181
+ }
38182
+ if (!SOFTWARE_INSTALL_METHODS.includes(request.method)) {
38183
+ return SOFTWARE_INSTALL_REFUSAL;
38184
+ }
38185
+ if (request.method === "npm") {
38186
+ if (!NPM_SPEC_PATTERN.test(request.source)) {
38187
+ return "The npm source must be a package name, optionally with one exact version as name@1.2.3. Ranges, tags, git specs, URLs, and local paths are not installed.";
38188
+ }
38189
+ if (request.sha256 !== void 0) {
38190
+ return "An expected sha256 applies only to downloads; the npm registry names versions, not file digests.";
38191
+ }
38192
+ return null;
38193
+ }
38194
+ let url3;
38195
+ try {
38196
+ url3 = new URL(request.source);
38197
+ } catch {
38198
+ return "The download source must be an absolute HTTPS URL.";
38199
+ }
38200
+ if (url3.protocol !== "https:") return "The download source must use HTTPS.";
38201
+ if (url3.username || url3.password) {
38202
+ return "The download source must not carry credentials in the URL.";
38203
+ }
38204
+ if (request.sha256 !== void 0 && !/^[a-f0-9]{64}$/i.test(request.sha256)) {
38205
+ return "The expected sha256 must be 64 hexadecimal characters.";
38206
+ }
38207
+ return null;
38208
+ }
38209
+ async function runProcess(plan, label) {
38210
+ const env = sanitizedInstallerEnv(process.env);
38211
+ await new Promise((resolveRun, rejectRun) => {
38212
+ const child = plan.shellLine !== void 0 ? spawn9(plan.shellLine, {
38213
+ ...plan.cwd ? { cwd: plan.cwd } : {},
38214
+ env,
38215
+ // stdin stays closed; output reaches the ordinary worker console, so
38216
+ // progress and failure land on the Host console like a runner install.
38217
+ stdio: ["ignore", "inherit", "inherit"],
38218
+ windowsHide: true,
38219
+ shell: true
38220
+ }) : spawn9(plan.command, plan.args, {
38221
+ ...plan.cwd ? { cwd: plan.cwd } : {},
38222
+ env,
38223
+ stdio: ["ignore", "inherit", "inherit"],
38224
+ windowsHide: true
38225
+ });
38226
+ let settled = false;
38227
+ const finish = (error52) => {
38228
+ if (settled) return;
38229
+ settled = true;
38230
+ clearTimeout(timer);
38231
+ if (error52) rejectRun(error52);
38232
+ else resolveRun();
38233
+ };
38234
+ const timer = setTimeout(() => {
38235
+ child.kill();
38236
+ finish(new Error(`${label} did not finish within 10 minutes`));
38237
+ }, PROCESS_TIMEOUT_MS);
38238
+ timer.unref?.();
38239
+ child.once("error", (error52) => finish(error52));
38240
+ child.once("exit", (code, signal) => {
38241
+ if (code === 0) finish();
38242
+ else if (signal) finish(new Error(`${label} stopped with ${signal}`));
38243
+ else finish(new Error(`${label} exited with code ${code ?? "unknown"}`));
38244
+ });
38245
+ });
38246
+ }
38247
+ async function resolveTarCommand(platform) {
38248
+ if (platform !== "win32") return "tar";
38249
+ const root = process.env["SYSTEMROOT"] ?? process.env["WINDIR"];
38250
+ if (!root) return "tar";
38251
+ return await resolveTrustedCliCommand(join17(root, "System32", "tar.exe"), { platform }) ?? "tar";
38252
+ }
38253
+ function archiveKindFor(url3) {
38254
+ let path;
38255
+ try {
38256
+ path = new URL(url3).pathname.toLowerCase();
38257
+ } catch {
38258
+ return "binary";
38259
+ }
38260
+ if (/\.(?:tar\.(?:gz|xz|bz2)|tgz|tbz2|txz|tar)$/.test(path)) return "tar";
38261
+ if (path.endsWith(".zip")) return "zip";
38262
+ return "binary";
38263
+ }
38264
+ async function findExtractedExecutable(root, command, platform = process.platform) {
38265
+ const names = platform === "win32" ? [`${command}.exe`, `${command}.cmd`, `${command}.bat`, command] : [command];
38266
+ let frontier = [root];
38267
+ for (let depth = 0; depth <= MAX_ARCHIVE_SEARCH_DEPTH && frontier.length > 0; depth += 1) {
38268
+ const next = [];
38269
+ for (const directory of frontier) {
38270
+ let entries;
38271
+ try {
38272
+ entries = await readdir5(directory, { withFileTypes: true });
38273
+ } catch {
38274
+ continue;
38275
+ }
38276
+ for (const name of names) {
38277
+ if (entries.some((entry) => entry.name === name && entry.isFile())) {
38278
+ return join17(directory, name);
38279
+ }
38280
+ }
38281
+ for (const entry of entries) {
38282
+ if (entry.isDirectory()) next.push(join17(directory, entry.name));
38283
+ }
38284
+ }
38285
+ frontier = next;
38286
+ }
38287
+ return null;
38288
+ }
38289
+ function withinRoot(root, candidate) {
38290
+ const base = resolvePath(root);
38291
+ const target = resolvePath(candidate);
38292
+ return target === base || target.startsWith(base.endsWith(sep5) ? base : `${base}${sep5}`);
38293
+ }
38294
+ function downloadedBinaryName(command, source, platform = process.platform) {
38295
+ if (platform !== "win32") return command;
38296
+ const extension = /(\.[A-Za-z0-9]{1,8})$/.exec(new URL(source).pathname)?.[1]?.toLowerCase();
38297
+ if (extension !== ".exe" && extension !== ".com") {
38298
+ throw new Error(
38299
+ "a direct Windows download must be a .exe or .com file; use the tool\u2019s .zip release instead"
38300
+ );
38301
+ }
38302
+ return `${command}${extension}`;
38303
+ }
38304
+ async function placeDownloadedPayload(body, request, options) {
38305
+ const platform = options.platform ?? process.platform;
38306
+ const { toolsRoot } = options;
38307
+ const staging = join17(toolsRoot, ".staging", randomUUID11());
38308
+ const stagedPackage = join17(staging, "pkg");
38309
+ const packageRoot = join17(toolsRoot, "pkgs", request.command);
38310
+ const binDirectory = platform === "win32" ? toolsRoot : join17(toolsRoot, "bin");
38311
+ const kind = archiveKindFor(request.source);
38312
+ await mkdir11(stagedPackage, { recursive: true, mode: 448 });
38313
+ try {
38314
+ if (kind === "binary") {
38315
+ await writeFile7(
38316
+ join17(stagedPackage, downloadedBinaryName(request.command, request.source, platform)),
38317
+ body,
38318
+ {
38319
+ mode: 448
38320
+ }
38321
+ );
38322
+ } else {
38323
+ await writeFile7(join17(staging, "archive"), body, { mode: 448 });
38324
+ if (kind === "tar" || platform !== "linux") {
38325
+ await runProcess(
38326
+ {
38327
+ command: await resolveTarCommand(platform),
38328
+ args: ["-xf", "archive", "-C", "pkg"],
38329
+ cwd: staging
38330
+ },
38331
+ "the archive extraction"
38332
+ );
38333
+ } else {
38334
+ await runProcess(
38335
+ { command: "unzip", args: ["-q", "-o", "archive", "-d", "pkg"], cwd: staging },
38336
+ "the archive extraction"
38337
+ );
38338
+ }
38339
+ await rm10(join17(staging, "archive"), { force: true }).catch(() => void 0);
38340
+ }
38341
+ const stagedExecutable = await findExtractedExecutable(
38342
+ stagedPackage,
38343
+ request.command,
38344
+ platform
38345
+ );
38346
+ if (!stagedExecutable) {
38347
+ throw new Error(`the download did not contain an executable named ${request.command}`);
38348
+ }
38349
+ if (!withinRoot(stagedPackage, stagedExecutable)) {
38350
+ throw new Error("the archive tried to place its executable outside the Zixt folder");
38351
+ }
38352
+ await mkdir11(join17(toolsRoot, "pkgs"), { recursive: true, mode: 448 });
38353
+ await rm10(packageRoot, { recursive: true, force: true });
38354
+ await rename6(stagedPackage, packageRoot);
38355
+ const executable = join17(packageRoot, relative8(stagedPackage, stagedExecutable));
38356
+ await mkdir11(binDirectory, { recursive: true, mode: 448 });
38357
+ if (platform === "win32") {
38358
+ const shim = join17(binDirectory, `${request.command}.cmd`);
38359
+ await writeFile7(shim, `@echo off\r
38360
+ ${quoteForCmd(executable)} %*\r
38361
+ `, {
38362
+ encoding: "utf8",
38363
+ mode: 448
38364
+ });
38365
+ return shim;
38366
+ }
38367
+ await chmod6(executable, 493);
38368
+ const link = join17(binDirectory, request.command);
38369
+ await rm10(link, { force: true });
38370
+ await symlink2(executable, link);
38371
+ return link;
38372
+ } finally {
38373
+ await rm10(staging, { recursive: true, force: true }).catch(() => void 0);
38374
+ }
38375
+ }
38376
+ function createSoftwareInstaller(options = {}) {
38377
+ const platform = options.platform ?? process.platform;
38378
+ const toolsRoot = options.toolsRoot ?? defaultSoftwareToolsRoot();
38379
+ const now = options.now ?? Date.now;
38380
+ const manifestPath = join17(toolsRoot, MANIFEST_NAME);
38381
+ const inFlight = /* @__PURE__ */ new Map();
38382
+ const failures = /* @__PURE__ */ new Map();
38383
+ const searchPath = () => {
38384
+ const inherited = options.resolution?.searchPath ?? process.env.PATH ?? "";
38385
+ const separator = platform === "win32" ? ";" : ":";
38386
+ return [inherited, ...softwareSearchPathEntries(toolsRoot)].filter(Boolean).join(separator);
38387
+ };
38388
+ const resolveCommand = async (command) => resolveTrustedCliCommand(command, {
38389
+ ...options.resolution ?? {},
38390
+ platform,
38391
+ searchPath: searchPath()
38392
+ });
38393
+ const readManifest = async () => {
38394
+ try {
38395
+ const parsed = JSON.parse(await readFile10(manifestPath, "utf8"));
38396
+ return Array.isArray(parsed) ? parsed : [];
38397
+ } catch {
38398
+ return [];
38399
+ }
38400
+ };
38401
+ let manifestTurn = Promise.resolve();
38402
+ const recordInstall = (record2) => {
38403
+ const write = manifestTurn.then(async () => {
38404
+ const existing = (await readManifest()).filter((entry) => entry.command !== record2.command);
38405
+ const staged = `${manifestPath}.${randomUUID11()}`;
38406
+ await writeFile7(staged, `${JSON.stringify([...existing, record2], null, 2)}
38407
+ `, {
38408
+ encoding: "utf8",
38409
+ mode: 384
38410
+ });
38411
+ await rename6(staged, manifestPath);
38412
+ });
38413
+ manifestTurn = write.catch(() => void 0);
38414
+ return write;
38415
+ };
38416
+ const installFromNpm = async (request) => {
38417
+ await mkdir11(toolsRoot, { recursive: true, mode: 448 });
38418
+ const npm = await resolveInstallerCommand({ platform });
38419
+ const args = [
38420
+ "install",
38421
+ "-g",
38422
+ "--prefix",
38423
+ toolsRoot,
38424
+ "--no-audit",
38425
+ "--no-fund",
38426
+ "--ignore-scripts",
38427
+ // `--` ends npm's flag parsing, so even a spec that slipped the pattern
38428
+ // could not become an npm option.
38429
+ "--",
38430
+ request.source
38431
+ ];
38432
+ if (platform === "win32") {
38433
+ await runProcess(
38434
+ { shellLine: windowsInstallerCommandLine(npm, args), cwd: toolsRoot },
38435
+ "the npm install"
38436
+ );
38437
+ } else {
38438
+ await runProcess({ command: npm, args, cwd: toolsRoot }, "the npm install");
38439
+ }
38440
+ };
38441
+ const installFromDownload = async (request) => {
38442
+ const response = await fetch(request.source, {
38443
+ redirect: "follow",
38444
+ signal: AbortSignal.timeout(DOWNLOAD_TIMEOUT_MS)
38445
+ });
38446
+ if (!response.ok) throw new Error(`the download answered HTTP ${response.status}`);
38447
+ if (response.url && !response.url.startsWith("https:")) {
38448
+ throw new Error("the download redirected off HTTPS and was not installed");
38449
+ }
38450
+ const declared = Number(response.headers.get("content-length") ?? "0");
38451
+ if (Number.isFinite(declared) && declared > MAX_DOWNLOAD_BYTES) {
38452
+ throw new Error("the download is larger than Zixt installs unattended");
38453
+ }
38454
+ if (!response.body) throw new Error("the download had no body");
38455
+ const reader = response.body.getReader();
38456
+ const chunks = [];
38457
+ let total = 0;
38458
+ for (; ; ) {
38459
+ const { done, value } = await reader.read();
38460
+ if (done) break;
38461
+ total += value.byteLength;
38462
+ if (total > MAX_DOWNLOAD_BYTES) {
38463
+ await reader.cancel().catch(() => void 0);
38464
+ throw new Error("the download is larger than Zixt installs unattended");
38465
+ }
38466
+ chunks.push(Buffer.from(value));
38467
+ }
38468
+ const body = Buffer.concat(chunks);
38469
+ if (body.length === 0) throw new Error("the download was empty");
38470
+ const digest = createHash6("sha256").update(body).digest("hex");
38471
+ if (request.sha256 && digest !== request.sha256.toLowerCase()) {
38472
+ throw new Error("the download did not match the expected sha256");
38473
+ }
38474
+ await placeDownloadedPayload(body, request, { toolsRoot, platform });
38475
+ };
38476
+ const perform = options.perform ?? (async (request) => {
38477
+ if (request.method === "npm") await installFromNpm(request);
38478
+ else await installFromDownload(request);
38479
+ const resolved = await resolveCommand(request.command);
38480
+ if (!resolved) {
38481
+ throw new Error(
38482
+ `the install finished but ${request.command} is still not runnable on this Machine`
38483
+ );
38484
+ }
38485
+ return resolved;
38486
+ });
38487
+ const attempt = async (request) => {
38488
+ options.onEvent?.({ command: request.command, state: "started" });
38489
+ try {
38490
+ const path = await perform(request, toolsRoot);
38491
+ if (!withinRoot(toolsRoot, path)) {
38492
+ throw new Error(
38493
+ `${request.command} resolves outside the Zixt folder and was not installed by Zixt`
38494
+ );
38495
+ }
38496
+ const record2 = {
38497
+ command: request.command,
38498
+ method: request.method,
38499
+ source: request.source,
38500
+ path,
38501
+ sha256: request.sha256 ? request.sha256.toLowerCase() : null,
38502
+ installedAt: new Date(now()).toISOString()
38503
+ };
38504
+ await recordInstall(record2).catch(() => void 0);
38505
+ options.onEvent?.({ command: request.command, state: "completed" });
38506
+ return { ok: true, record: record2 };
38507
+ } catch (error52) {
38508
+ const message = error52 instanceof Error ? error52.message : "unknown software install error";
38509
+ options.onEvent?.({ command: request.command, state: "failed", error: message });
38510
+ return { ok: false, error: message };
38511
+ }
38512
+ };
38513
+ return {
38514
+ toolsRoot,
38515
+ async probe(command) {
38516
+ if (!COMMAND_PATTERN.test(command)) {
38517
+ return { command, present: false, path: null, managed: false };
38518
+ }
38519
+ const path = await resolveCommand(command);
38520
+ return {
38521
+ command,
38522
+ present: path !== null,
38523
+ path,
38524
+ managed: path !== null && withinRoot(toolsRoot, path)
38525
+ };
38526
+ },
38527
+ async install(request) {
38528
+ const refusal = refuseSoftwareRequest(request);
38529
+ if (refusal) return { ok: false, error: refusal };
38530
+ const key = [
38531
+ request.command,
38532
+ request.method,
38533
+ request.source,
38534
+ request.sha256?.toLowerCase() ?? ""
38535
+ ].join("\n");
38536
+ const running = inFlight.get(key);
38537
+ if (running) return running;
38538
+ const failure2 = failures.get(key);
38539
+ if (failure2 && now() - failure2.at < FAILURE_COOLDOWN_MS2) {
38540
+ return {
38541
+ ok: false,
38542
+ error: `This exact install already failed on this Machine: ${failure2.error}. Do not repeat it. Finish the work another way, or tell the person what is missing and the command they would run.`
38543
+ };
38544
+ }
38545
+ const started = (async () => {
38546
+ const result = await attempt(request);
38547
+ if (result.ok) failures.delete(key);
38548
+ else failures.set(key, { at: now(), error: result.error });
38549
+ return result;
38550
+ })();
38551
+ inFlight.set(key, started);
38552
+ try {
38553
+ return await started;
38554
+ } finally {
38555
+ inFlight.delete(key);
38556
+ }
38557
+ },
38558
+ async installed() {
38559
+ return readManifest();
38560
+ }
38561
+ };
38562
+ }
38563
+
38564
+ // src/runners/ask-user-server.ts
38099
38565
  var CADENCE_PROPS = {
38100
38566
  cadence_kind: {
38101
38567
  type: "string",
@@ -38211,6 +38677,55 @@ var TOOLS = [
38211
38677
  additionalProperties: false
38212
38678
  }
38213
38679
  },
38680
+ {
38681
+ name: "check_software",
38682
+ description: "Check whether a command is already available on this Machine before assuming it is missing. Returns whether it is present, where it resolved, and whether Zixt is the one that installed it.",
38683
+ inputSchema: {
38684
+ type: "object",
38685
+ properties: {
38686
+ command: {
38687
+ type: "string",
38688
+ description: "The plain command name, for example ffmpeg or gh. No path, no arguments."
38689
+ }
38690
+ },
38691
+ required: ["command"],
38692
+ additionalProperties: false
38693
+ }
38694
+ },
38695
+ {
38696
+ name: "install_software",
38697
+ description: "Install a command this Machine is missing, into the folder Zixt owns, after the person approves it. Prefer not to call this. Installing software on someone else\u2019s computer is friction, so first try to finish the work with what the Machine already has: a different tool, a project dependency, or another approach. Call it only when the missing command genuinely blocks the work or is clearly the right way to do it, and never speculatively. Zixt can install an npm package, or download and unpack a release from an HTTPS URL. It cannot use a system package manager such as apt, brew, winget, or choco, cannot ask for elevation or sudo, and cannot build from source. When the tool needs any of those, or the install looks complicated, do not call this: tell the person what is missing, why this work needs it, and the exact command they would run on their operating system. The person sees your reason and the exact source before anything runs, and may say no.",
38698
+ inputSchema: {
38699
+ type: "object",
38700
+ properties: {
38701
+ command: {
38702
+ type: "string",
38703
+ description: "The plain command name the work needs on PATH, for example ffmpeg."
38704
+ },
38705
+ reason: {
38706
+ type: "string",
38707
+ minLength: 1,
38708
+ maxLength: 500,
38709
+ description: "Why this work needs it, in one plain sentence. The person reads this before deciding."
38710
+ },
38711
+ method: {
38712
+ type: "string",
38713
+ enum: [...SOFTWARE_INSTALL_METHODS],
38714
+ description: "npm for an npm package; download for a release archive or binary."
38715
+ },
38716
+ source: {
38717
+ type: "string",
38718
+ description: "npm: the package name, optionally name@version with an exact version. download: the HTTPS URL of the release archive or binary."
38719
+ },
38720
+ sha256: {
38721
+ type: "string",
38722
+ description: "download only: the published SHA-256 of that file, when the project publishes one. Include it whenever you can."
38723
+ }
38724
+ },
38725
+ required: ["command", "reason", "method", "source"],
38726
+ additionalProperties: false
38727
+ }
38728
+ },
38214
38729
  {
38215
38730
  name: "publish_file",
38216
38731
  description: "Snapshot a file you created in this Task workspace into Zixt so the user can download it. This only creates the Zixt file; it does not send it anywhere externally. The result returns an artifact_id.",
@@ -38996,6 +39511,57 @@ function createAskUserServer() {
38996
39511
  }
38997
39512
  return;
38998
39513
  }
39514
+ if (surface.platform && (name === "check_software" || name === "install_software")) {
39515
+ if (!handlers.software) {
39516
+ toolText("Software checks are unavailable for this runner.", true);
39517
+ return;
39518
+ }
39519
+ const command = typeof args["command"] === "string" ? args["command"].trim() : "";
39520
+ if (!command) {
39521
+ toolText("missing required argument `command`", true);
39522
+ return;
39523
+ }
39524
+ try {
39525
+ if (name === "check_software") {
39526
+ toolText(JSON.stringify(await handlers.software.check(command), null, 2));
39527
+ return;
39528
+ }
39529
+ const reason = typeof args["reason"] === "string" ? args["reason"].trim() : "";
39530
+ const method = typeof args["method"] === "string" ? args["method"] : "";
39531
+ const source = typeof args["source"] === "string" ? args["source"].trim() : "";
39532
+ const sha256 = typeof args["sha256"] === "string" && args["sha256"] ? args["sha256"] : void 0;
39533
+ if (!reason) {
39534
+ toolText(
39535
+ "missing required argument `reason`: the person decides by reading why this work needs it",
39536
+ true
39537
+ );
39538
+ return;
39539
+ }
39540
+ if (!SOFTWARE_INSTALL_METHODS.includes(method)) {
39541
+ toolText(`\`method\` must be one of ${SOFTWARE_INSTALL_METHODS.join(", ")}.`, true);
39542
+ return;
39543
+ }
39544
+ const request = {
39545
+ command,
39546
+ method,
39547
+ source,
39548
+ sha256
39549
+ };
39550
+ const refusal = refuseSoftwareRequest(request);
39551
+ if (refusal) {
39552
+ toolText(refusal, true);
39553
+ return;
39554
+ }
39555
+ const outcome = await handlers.software.install({ ...request, reason });
39556
+ toolText(outcome.detail, !outcome.ok);
39557
+ } catch (err) {
39558
+ toolText(
39559
+ `The software request could not be completed: ${String(err instanceof Error ? err.message : err)}`,
39560
+ true
39561
+ );
39562
+ }
39563
+ return;
39564
+ }
38999
39565
  if (surface.platform && name === "publish_file") {
39000
39566
  if (!handlers.publishFile) {
39001
39567
  toolText("file publishing is unavailable for this runner", true);
@@ -39111,6 +39677,7 @@ function createAskUserServer() {
39111
39677
  agentOp: input.agentOp,
39112
39678
  ..."requestApproval" in input && input.requestApproval ? { requestApproval: input.requestApproval } : {},
39113
39679
  ..."publishFile" in input && input.publishFile ? { publishFile: input.publishFile } : {},
39680
+ ..."software" in input && input.software ? { software: input.software } : {},
39114
39681
  ...toolPacks.length > 0 ? { toolPacks } : {}
39115
39682
  };
39116
39683
  const toolOwners = /* @__PURE__ */ new Map();
@@ -39263,7 +39830,10 @@ function buildRunnerEnv(input) {
39263
39830
  env[name] = value;
39264
39831
  }
39265
39832
  }
39266
- const searchPath = sanitizeInheritedSearchPath(inheritedValue(input.inherited, "PATH"));
39833
+ const searchPath = [
39834
+ sanitizeInheritedSearchPath(inheritedValue(input.inherited, "PATH")),
39835
+ ...(input.softwareToolsPath ?? []).filter((entry) => isAbsolute14(entry))
39836
+ ].filter((entry) => entry !== "").join(delimiter2);
39267
39837
  const gitConfig = input.githubShell ? [
39268
39838
  ["credential.helper", ""],
39269
39839
  ["credential.helper", input.githubShell.gitCredentialHelper],
@@ -39330,9 +39900,9 @@ function buildRunnerEnv(input) {
39330
39900
  // src/runners/github-shell-auth.ts
39331
39901
  import { execFile } from "node:child_process";
39332
39902
  import { randomBytes as randomBytes2, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
39333
- import { chmod as chmod6, lstat as lstat10, mkdir as mkdir11, realpath as realpath7, writeFile as writeFile7 } from "node:fs/promises";
39903
+ import { chmod as chmod7, lstat as lstat10, mkdir as mkdir12, realpath as realpath7, writeFile as writeFile8 } from "node:fs/promises";
39334
39904
  import { createServer as createServer3 } from "node:http";
39335
- import { isAbsolute as isAbsolute15, join as join17, relative as relative8 } from "node:path";
39905
+ import { isAbsolute as isAbsolute15, join as join18, relative as relative9 } from "node:path";
39336
39906
  var MAX_REQUEST_BYTES2 = 16 * 1024;
39337
39907
  var DIRECTORY_MODE4 = 448;
39338
39908
  var PRIVATE_FILE_MODE = 384;
@@ -39696,7 +40266,7 @@ function activationCredential(grant, now = Date.now()) {
39696
40266
  return expiresAt.getTime() <= now ? null : { accessToken: grant.accessToken, expiresAt };
39697
40267
  }
39698
40268
  function assertChildPath2(parent, child) {
39699
- const path = relative8(parent, child);
40269
+ const path = relative9(parent, child);
39700
40270
  if (!path || path === ".." || path.startsWith("../") || path.startsWith("..\\") || isAbsolute15(path)) {
39701
40271
  throw new Error("GitHub shell helper path escaped its private run directory");
39702
40272
  }
@@ -39708,11 +40278,11 @@ function quoteForPosixShell(value) {
39708
40278
  return quoteForGitShell2(value);
39709
40279
  }
39710
40280
  async function writePrivate(path, content, executable = false) {
39711
- await writeFile7(path, content, {
40281
+ await writeFile8(path, content, {
39712
40282
  flag: "wx",
39713
40283
  mode: executable ? EXECUTABLE_FILE_MODE : PRIVATE_FILE_MODE
39714
40284
  });
39715
- await chmod6(path, executable ? EXECUTABLE_FILE_MODE : PRIVATE_FILE_MODE);
40285
+ await chmod7(path, executable ? EXECUTABLE_FILE_MODE : PRIVATE_FILE_MODE);
39716
40286
  }
39717
40287
  async function prepareHelpers(input) {
39718
40288
  const rootEntry = await lstat10(input.runRoot);
@@ -39720,7 +40290,7 @@ async function prepareHelpers(input) {
39720
40290
  throw new Error("GitHub shell authentication requires a private real run directory");
39721
40291
  }
39722
40292
  const runRoot = await realpath7(input.runRoot);
39723
- const helperPath = join17(runRoot, "github-shell-git-credential.cjs");
40293
+ const helperPath = join18(runRoot, "github-shell-git-credential.cjs");
39724
40294
  assertChildPath2(runRoot, helperPath);
39725
40295
  await writePrivate(helperPath, GIT_HELPER_SOURCE);
39726
40296
  if (!input.ghExecutablePath) {
@@ -39731,14 +40301,14 @@ async function prepareHelpers(input) {
39731
40301
  wrapperSourcePath: null
39732
40302
  };
39733
40303
  }
39734
- const shellToolsDirectory = join17(runRoot, "shell-tools");
40304
+ const shellToolsDirectory = join18(runRoot, "shell-tools");
39735
40305
  assertChildPath2(runRoot, shellToolsDirectory);
39736
- await mkdir11(shellToolsDirectory, { mode: DIRECTORY_MODE4 });
39737
- await chmod6(shellToolsDirectory, DIRECTORY_MODE4);
39738
- const wrapperSourcePath = join17(runRoot, "github-shell-gh-wrapper.cjs");
40306
+ await mkdir12(shellToolsDirectory, { mode: DIRECTORY_MODE4 });
40307
+ await chmod7(shellToolsDirectory, DIRECTORY_MODE4);
40308
+ const wrapperSourcePath = join18(runRoot, "github-shell-gh-wrapper.cjs");
39739
40309
  assertChildPath2(runRoot, wrapperSourcePath);
39740
40310
  await writePrivate(wrapperSourcePath, GH_WRAPPER_SOURCE);
39741
- const wrapperPath = join17(shellToolsDirectory, process.platform === "win32" ? "gh.cmd" : "gh");
40311
+ const wrapperPath = join18(shellToolsDirectory, process.platform === "win32" ? "gh.cmd" : "gh");
39742
40312
  assertChildPath2(runRoot, wrapperPath);
39743
40313
  const launcher = process.platform === "win32" ? `@"${process.execPath.replaceAll('"', '""')}" "${wrapperSourcePath.replaceAll('"', '""')}" %*\r
39744
40314
  ` : `#!/bin/sh
@@ -39961,7 +40531,7 @@ password=${credential.accessToken}
39961
40531
  }
39962
40532
 
39963
40533
  // src/runners/working-context.ts
39964
- import { spawn as spawn9 } from "node:child_process";
40534
+ import { spawn as spawn10 } from "node:child_process";
39965
40535
  import { resolve as resolve9 } from "node:path";
39966
40536
  var COMMAND_TIMEOUT_MS = 5e3;
39967
40537
  var OUTPUT_LIMIT_BYTES = 128 * 1024;
@@ -40092,7 +40662,7 @@ async function stopWorkingContextCommand(child, childExited, options = {}) {
40092
40662
  function run(command, args, cwd, env, signal) {
40093
40663
  if (signal?.aborted) return Promise.resolve(null);
40094
40664
  return new Promise((resolvePromise) => {
40095
- const child = spawn9(command, [...args], {
40665
+ const child = spawn10(command, [...args], {
40096
40666
  cwd,
40097
40667
  env: { ...env, GIT_OPTIONAL_LOCKS: "0" },
40098
40668
  detached: process.platform !== "win32",
@@ -40510,6 +41080,7 @@ var WorkingContextPullRequestCache = class {
40510
41080
  };
40511
41081
 
40512
41082
  // src/runners/cli-runner.ts
41083
+ var softwareInstaller = createSoftwareInstaller();
40513
41084
  var PRIVATE_CLEANUP_FAILURE = "Private runner cleanup could not be completed. Restart the Zixt Host before accepting more work.";
40514
41085
  var PROCESS_CLEANUP_FAILURE = "Runner process cleanup could not be confirmed. Restart the Zixt Host before accepting more work.";
40515
41086
  var PROVIDER_CLEANUP_FAILURE = "Provider tool cleanup could not be completed. Restart the Zixt Host before accepting more work.";
@@ -40532,7 +41103,7 @@ async function settlesWithin(promise2, timeoutMs) {
40532
41103
  }
40533
41104
  }
40534
41105
  function defaultRunnerWorkspaceRoot() {
40535
- return join18(homedir7(), ".zixt", "workspaces");
41106
+ return join19(homedir7(), ".zixt", "workspaces");
40536
41107
  }
40537
41108
  function defaultRunnerArtifactRoot() {
40538
41109
  return defaultRunArtifactRoot();
@@ -40581,7 +41152,7 @@ function createCliRunner(adapter, opts = {}) {
40581
41152
  const prefixArgs = opts.commandPrefixArgs ?? [];
40582
41153
  const maxWallTimeMs = opts.maxWallTimeMs;
40583
41154
  const workspaceRoot = opts.workspaceRoot ?? defaultRunnerWorkspaceRoot();
40584
- const artifactRoot = opts.artifactRoot ?? (opts.workspaceRoot === void 0 ? defaultRunnerArtifactRoot() : join18(dirname10(workspaceRoot), "run-artifacts"));
41155
+ const artifactRoot = opts.artifactRoot ?? (opts.workspaceRoot === void 0 ? defaultRunnerArtifactRoot() : join19(dirname10(workspaceRoot), "run-artifacts"));
40585
41156
  const runRegistryRoot2 = opts.runRegistryRoot ?? defaultRunRegistryRoot();
40586
41157
  const createArtifacts = opts.createArtifacts ?? createRunArtifacts;
40587
41158
  const toolPackRegistry2 = opts.toolPackRegistry ?? createDefaultToolPackRegistry();
@@ -40599,7 +41170,7 @@ function createCliRunner(adapter, opts = {}) {
40599
41170
  };
40600
41171
  const askUserServer = createAskUserServer();
40601
41172
  const windowsRoot = process.env.SystemRoot ?? process.env.WINDIR;
40602
- const windowsComspecCandidate = process.platform === "win32" && windowsRoot ? join18(windowsRoot, "System32", "cmd.exe") : void 0;
41173
+ const windowsComspecCandidate = process.platform === "win32" && windowsRoot ? join19(windowsRoot, "System32", "cmd.exe") : void 0;
40603
41174
  let safetyFailure;
40604
41175
  return async (task) => {
40605
41176
  if (safetyFailure) {
@@ -40639,8 +41210,8 @@ function createCliRunner(adapter, opts = {}) {
40639
41210
  usage: { inputTokens: 0, outputTokens: 0 }
40640
41211
  };
40641
41212
  }
40642
- const taskRoot = join18(workspaceRoot, task.agentId);
40643
- await mkdir12(taskRoot, { recursive: true });
41213
+ const taskRoot = join19(workspaceRoot, task.agentId);
41214
+ await mkdir13(taskRoot, { recursive: true });
40644
41215
  if (task.cancelledNow()) return cancelledBeforeRun();
40645
41216
  const configuredWorkspace = task.spec.workspace;
40646
41217
  let cwd = taskRoot;
@@ -40687,7 +41258,7 @@ function createCliRunner(adapter, opts = {}) {
40687
41258
  summaryEvidence: "host_observed"
40688
41259
  };
40689
41260
  }
40690
- const runToken = randomUUID11();
41261
+ const runToken = randomUUID12();
40691
41262
  const artifacts = await createArtifacts({
40692
41263
  root: artifactRoot,
40693
41264
  agentId: task.agentId,
@@ -40743,7 +41314,8 @@ function createCliRunner(adapter, opts = {}) {
40743
41314
  runner: { type: adapter.type, auth: runner.auth },
40744
41315
  gitIdentity: githubCommitIdentity(providerGrants),
40745
41316
  isolation: artifacts,
40746
- githubShell
41317
+ githubShell,
41318
+ softwareToolsPath: softwareSearchPathEntries(softwareInstaller.toolsRoot)
40747
41319
  });
40748
41320
  toolPacks = await toolPackRegistry2.createInstances(providerGrants, {
40749
41321
  taskId: task.taskId,
@@ -40836,6 +41408,51 @@ function createCliRunner(adapter, opts = {}) {
40836
41408
  }
40837
41409
  },
40838
41410
  publishFile,
41411
+ // AG-4a. The person approves in the Task thread through the ordinary
41412
+ // approvals pipeline, so the wall clock pauses while they decide, and
41413
+ // a refusal is an answer the session can act on rather than a failure.
41414
+ software: {
41415
+ check: (command2) => softwareInstaller.probe(command2),
41416
+ install: async ({ reason, ...request }) => {
41417
+ pendingAsks++;
41418
+ let decision;
41419
+ try {
41420
+ decision = await task.requestApproval(
41421
+ "agent.question",
41422
+ `Install ${request.command} on this Machine: ${reason}`.slice(0, 500),
41423
+ JSON.stringify({
41424
+ command: request.command,
41425
+ reason,
41426
+ method: request.method,
41427
+ source: request.source,
41428
+ ...request.sha256 ? { sha256: request.sha256 } : {},
41429
+ folder: softwareInstaller.toolsRoot
41430
+ }).slice(0, MAX_APPROVAL_PAYLOAD)
41431
+ );
41432
+ } finally {
41433
+ pendingAsks--;
41434
+ }
41435
+ if (!decision.approved) {
41436
+ return {
41437
+ ok: false,
41438
+ detail: decision.guidance ?? `The person did not approve installing ${request.command}. Do not ask again for this task. Finish the work another way, or explain what is blocked.`
41439
+ };
41440
+ }
41441
+ task.event("status", `Installing ${request.command} on this Machine`, {
41442
+ tool: "install_software"
41443
+ });
41444
+ const result2 = await softwareInstaller.install(request);
41445
+ task.event(
41446
+ "status",
41447
+ result2.ok ? `Installed ${request.command} on this Machine` : `Could not install ${request.command} on this Machine`,
41448
+ { tool: "install_software" }
41449
+ );
41450
+ return result2.ok ? {
41451
+ ok: true,
41452
+ detail: `${request.command} is installed at ${result2.record.path} and is on your PATH. Continue the work.`
41453
+ } : { ok: false, detail: result2.error };
41454
+ }
41455
+ },
40839
41456
  agentOp: (op) => task.agentOp(op),
40840
41457
  // GitHub repository work belongs in the installed `git` and `gh`
40841
41458
  // commands backed by GithubShellAuth. Do not advertise the bundled
@@ -41060,8 +41677,8 @@ ${attachmentSection}` : prompt;
41060
41677
  }
41061
41678
  comspec = resolvedWindowsComspec;
41062
41679
  }
41063
- const exitMarker = `__ZIXT_RUNNER_EXIT_${randomUUID11()}__`;
41064
- const guardianNonce = randomUUID11();
41680
+ const exitMarker = `__ZIXT_RUNNER_EXIT_${randomUUID12()}__`;
41681
+ const guardianNonce = randomUUID12();
41065
41682
  return runCliProcess({
41066
41683
  command: resolvedCommand,
41067
41684
  args,
@@ -41418,8 +42035,8 @@ function runCliProcess(options) {
41418
42035
  }
41419
42036
  return new Promise((resolve19) => {
41420
42037
  const platform = options.platform ?? process.platform;
41421
- const containmentGateNonce = options.guardian && platform === "win32" ? randomUUID11() : void 0;
41422
- const child = options.guardian ? spawn10(
42038
+ const containmentGateNonce = options.guardian && platform === "win32" ? randomUUID12() : void 0;
42039
+ const child = options.guardian ? spawn11(
41423
42040
  options.guardian.nodeCommand,
41424
42041
  [
41425
42042
  options.guardian.scriptPath,
@@ -41707,12 +42324,12 @@ function runCliProcess(options) {
41707
42324
  }
41708
42325
 
41709
42326
  // src/runners/claude-code.ts
41710
- import { randomUUID as randomUUID12 } from "node:crypto";
42327
+ import { randomUUID as randomUUID13 } from "node:crypto";
41711
42328
 
41712
42329
  // src/runners/runtime-observation.ts
41713
- import { open as open6, readdir as readdir5, realpath as realpath9 } from "node:fs/promises";
42330
+ import { open as open6, readdir as readdir6, realpath as realpath9 } from "node:fs/promises";
41714
42331
  import { homedir as homedir8 } from "node:os";
41715
- import { join as join19 } from "node:path";
42332
+ import { join as join20 } from "node:path";
41716
42333
  var READ_WINDOW_BYTES = 1024 * 1024;
41717
42334
  var CATALOG_TIMEOUT_MS = 15e3;
41718
42335
  var CATALOG_OUTPUT_LIMIT_BYTES = 4 * 1024 * 1024;
@@ -41772,9 +42389,9 @@ function displayValue(value, maxLength) {
41772
42389
  return trimmed;
41773
42390
  }
41774
42391
  function claudeTranscriptPath(input) {
41775
- const configDir = input.env["CLAUDE_CONFIG_DIR"] || join19(homeFrom(input.env), ".claude");
42392
+ const configDir = input.env["CLAUDE_CONFIG_DIR"] || join20(homeFrom(input.env), ".claude");
41776
42393
  const slug = input.resolvedCwd.replace(/[^a-zA-Z0-9]/g, "-");
41777
- return join19(configDir, "projects", slug, `${input.sessionId}.jsonl`);
42394
+ return join20(configDir, "projects", slug, `${input.sessionId}.jsonl`);
41778
42395
  }
41779
42396
  async function readClaudeSessionEffort(input) {
41780
42397
  const resolvedCwd = await realpath9(input.cwd).catch(() => input.cwd);
@@ -41789,19 +42406,19 @@ async function readClaudeSessionEffort(input) {
41789
42406
  return null;
41790
42407
  }
41791
42408
  async function newestDirectories(root, limit) {
41792
- const entries = await readdir5(root, { withFileTypes: true }).catch(() => []);
41793
- return entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort((left, right) => right.localeCompare(left)).slice(0, limit).map((name) => join19(root, name));
42409
+ const entries = await readdir6(root, { withFileTypes: true }).catch(() => []);
42410
+ return entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort((left, right) => right.localeCompare(left)).slice(0, limit).map((name) => join20(root, name));
41794
42411
  }
41795
42412
  async function findCodexRolloutPath(input) {
41796
- const codexHome = input.env["CODEX_HOME"] || join19(homeFrom(input.env), ".codex");
41797
- const sessions = join19(codexHome, "sessions");
42413
+ const codexHome = input.env["CODEX_HOME"] || join20(homeFrom(input.env), ".codex");
42414
+ const sessions = join20(codexHome, "sessions");
41798
42415
  const suffix = `-${input.threadId}.jsonl`;
41799
42416
  for (const year of await newestDirectories(sessions, 2)) {
41800
42417
  for (const month of await newestDirectories(year, 2)) {
41801
42418
  for (const day of await newestDirectories(month, 3)) {
41802
- const files = await readdir5(day).catch(() => []);
42419
+ const files = await readdir6(day).catch(() => []);
41803
42420
  const match = files.find((name) => name.endsWith(suffix));
41804
- if (match) return join19(day, match);
42421
+ if (match) return join20(day, match);
41805
42422
  }
41806
42423
  }
41807
42424
  }
@@ -41899,7 +42516,7 @@ var claudeCodeAdapter = {
41899
42516
  input.gitDetected,
41900
42517
  liveInput
41901
42518
  );
41902
- const sessionId = input.task.spec.sessionKey ?? randomUUID12();
42519
+ const sessionId = input.task.spec.sessionKey ?? randomUUID13();
41903
42520
  const observeRuntime = createRuntimeReporter(input, sessionId);
41904
42521
  return {
41905
42522
  argsFor: (mode) => [
@@ -42028,7 +42645,7 @@ function createClaudeLiveParser(onStream, onSessionModel) {
42028
42645
  ...parser,
42029
42646
  async start(writer, prompt) {
42030
42647
  write = writer;
42031
- await writer(input(randomUUID12(), prompt));
42648
+ await writer(input(randomUUID13(), prompt));
42032
42649
  },
42033
42650
  async steer(followUp) {
42034
42651
  if (!write) return false;
@@ -42195,22 +42812,22 @@ function improveErrorMessage(error52) {
42195
42812
  }
42196
42813
 
42197
42814
  // src/runners/codex.ts
42198
- import { mkdir as mkdir13, readFile as readFile10, writeFile as writeFile8 } from "node:fs/promises";
42199
- import { randomUUID as randomUUID13 } from "node:crypto";
42815
+ import { mkdir as mkdir14, readFile as readFile11, writeFile as writeFile9 } from "node:fs/promises";
42816
+ import { randomUUID as randomUUID14 } from "node:crypto";
42200
42817
  import { homedir as homedir9 } from "node:os";
42201
- import { join as join20 } from "node:path";
42818
+ import { join as join21 } from "node:path";
42202
42819
  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.";
42203
42820
  function defaultCodexThreadIndexRoot() {
42204
- return join20(homedir9(), ".zixt", "codex-threads");
42821
+ return join21(homedir9(), ".zixt", "codex-threads");
42205
42822
  }
42206
42823
  var SAFE_SEGMENT3 = /^[A-Za-z0-9_-]{1,200}$/;
42207
42824
  function threadIndexPath(root, agentId, sessionKey) {
42208
42825
  if (!SAFE_SEGMENT3.test(agentId) || !SAFE_SEGMENT3.test(sessionKey)) return null;
42209
- return join20(root, agentId, `${sessionKey}.json`);
42826
+ return join21(root, agentId, `${sessionKey}.json`);
42210
42827
  }
42211
42828
  async function readThreadId(path) {
42212
42829
  try {
42213
- const parsed = JSON.parse(await readFile10(path, "utf8"));
42830
+ const parsed = JSON.parse(await readFile11(path, "utf8"));
42214
42831
  return typeof parsed.threadId === "string" && /^[A-Za-z0-9-]{1,120}$/.test(parsed.threadId) ? parsed.threadId : null;
42215
42832
  } catch {
42216
42833
  return null;
@@ -42310,7 +42927,7 @@ ${value}` : value;
42310
42927
  const recordedThreadId = indexPath ? await readThreadId(indexPath) : null;
42311
42928
  const rememberThread = (threadId) => {
42312
42929
  if (!indexPath) return;
42313
- void mkdir13(join20(threadIndexRoot, task.agentId), { recursive: true }).then(() => writeFile8(indexPath, JSON.stringify({ threadId }), "utf8")).catch(() => {
42930
+ void mkdir14(join21(threadIndexRoot, task.agentId), { recursive: true }).then(() => writeFile9(indexPath, JSON.stringify({ threadId }), "utf8")).catch(() => {
42314
42931
  });
42315
42932
  };
42316
42933
  const observeRuntime = (threadId) => {
@@ -42414,7 +43031,7 @@ function createCodexAppServerParser(onStream, options) {
42414
43031
  params: {
42415
43032
  threadId,
42416
43033
  input: [{ type: "text", text: prompt }],
42417
- clientUserMessageId: randomUUID13(),
43034
+ clientUserMessageId: randomUUID14(),
42418
43035
  ...options.model ? { model: options.model } : {},
42419
43036
  ...options.effort ? { effort: options.effort } : {}
42420
43037
  }
@@ -42773,7 +43390,7 @@ function improveCodexErrorMessage(error52) {
42773
43390
  }
42774
43391
 
42775
43392
  // src/runners/git-preflight.ts
42776
- import { spawn as spawn11 } from "node:child_process";
43393
+ import { spawn as spawn12 } from "node:child_process";
42777
43394
  import { realpath as realpath10 } from "node:fs/promises";
42778
43395
  import { isAbsolute as isAbsolute17, resolve as resolve11 } from "node:path";
42779
43396
  var OUTPUT_LIMIT = 8192;
@@ -42822,7 +43439,7 @@ async function preflightGit(options = {}) {
42822
43439
  }
42823
43440
  async function runVersionProbe(input) {
42824
43441
  return new Promise((resolvePromise) => {
42825
- const child = spawn11(input.executablePath, input.args, {
43442
+ const child = spawn12(input.executablePath, input.args, {
42826
43443
  cwd: input.cwd,
42827
43444
  env: {
42828
43445
  ...process.env.SystemRoot ? { SystemRoot: process.env.SystemRoot } : {},
@@ -43044,16 +43661,16 @@ function run2(command, args) {
43044
43661
  }
43045
43662
 
43046
43663
  // src/linux-service.ts
43047
- import { spawn as spawn12 } from "node:child_process";
43664
+ import { spawn as spawn13 } from "node:child_process";
43048
43665
  import { constants as constants2 } from "node:fs";
43049
- import { access as access5, chmod as chmod8, mkdir as mkdir15, open as open7, rename as rename7, rm as rm11 } from "node:fs/promises";
43666
+ import { access as access5, chmod as chmod9, mkdir as mkdir16, open as open7, rename as rename8, rm as rm12 } from "node:fs/promises";
43050
43667
  import { homedir as homedir11, userInfo } from "node:os";
43051
- import { basename as basename4, dirname as dirname11, join as join22, relative as relative9, resolve as resolve13, sep as sep6 } from "node:path";
43668
+ import { basename as basename4, dirname as dirname11, join as join23, relative as relative10, resolve as resolve13, sep as sep7 } from "node:path";
43052
43669
 
43053
43670
  // src/service-runtime.ts
43054
- import { access as access4, chmod as chmod7, copyFile, mkdir as mkdir14, rename as rename6, rm as rm10 } from "node:fs/promises";
43671
+ import { access as access4, chmod as chmod8, copyFile, mkdir as mkdir15, rename as rename7, rm as rm11 } from "node:fs/promises";
43055
43672
  import { homedir as homedir10 } from "node:os";
43056
- import { join as join21, resolve as resolve12, sep as sep5 } from "node:path";
43673
+ import { join as join22, resolve as resolve12, sep as sep6 } from "node:path";
43057
43674
  async function ensureDurableServiceNode(options = {}) {
43058
43675
  const execPath = resolve12(options.execPath ?? process.execPath);
43059
43676
  const home = options.home ?? homedir10();
@@ -43063,22 +43680,22 @@ async function ensureDurableServiceNode(options = {}) {
43063
43680
  throw new Error("the Node runtime version is not a safe directory name");
43064
43681
  }
43065
43682
  const zixtRoot = resolve12(home, ".zixt");
43066
- if (execPath === zixtRoot || execPath.startsWith(zixtRoot + sep5)) return execPath;
43067
- const directory = join21(zixtRoot, "runtime", `node-${version2}`);
43068
- const destination = join21(directory, platform === "win32" ? "node.exe" : "node");
43683
+ if (execPath === zixtRoot || execPath.startsWith(zixtRoot + sep6)) return execPath;
43684
+ const directory = join22(zixtRoot, "runtime", `node-${version2}`);
43685
+ const destination = join22(directory, platform === "win32" ? "node.exe" : "node");
43069
43686
  const alreadyCopied = await access4(destination).then(
43070
43687
  () => true,
43071
43688
  () => false
43072
43689
  );
43073
43690
  if (alreadyCopied) return destination;
43074
- await mkdir14(directory, { recursive: true, mode: 448 });
43691
+ await mkdir15(directory, { recursive: true, mode: 448 });
43075
43692
  const temporary = `${destination}.${process.pid}.${crypto.randomUUID()}.tmp`;
43076
43693
  try {
43077
43694
  await copyFile(execPath, temporary);
43078
- await chmod7(temporary, 493);
43079
- await rename6(temporary, destination);
43695
+ await chmod8(temporary, 493);
43696
+ await rename7(temporary, destination);
43080
43697
  } catch (error52) {
43081
- await rm10(temporary, { force: true }).catch(() => void 0);
43698
+ await rm11(temporary, { force: true }).catch(() => void 0);
43082
43699
  throw error52;
43083
43700
  }
43084
43701
  await options.syncDirectory?.(directory);
@@ -43114,7 +43731,7 @@ function boundedAppend(current, chunk) {
43114
43731
  async function defaultRunCommand(command, args) {
43115
43732
  const commandEnvironment3 = systemServiceCommandEnvironment();
43116
43733
  return new Promise((resolve19) => {
43117
- const child = spawn12(command, [...args], {
43734
+ const child = spawn13(command, [...args], {
43118
43735
  stdio: ["ignore", "pipe", "pipe"],
43119
43736
  env: commandEnvironment3,
43120
43737
  windowsHide: true
@@ -43186,33 +43803,33 @@ async function defaultSyncDirectory(path) {
43186
43803
  }
43187
43804
  }
43188
43805
  async function ensureDirectory(path, mode, syncDirectory8) {
43189
- const firstCreated = await mkdir15(path, { recursive: true, mode });
43806
+ const firstCreated = await mkdir16(path, { recursive: true, mode });
43190
43807
  if (!firstCreated) return;
43191
43808
  const first = resolve13(firstCreated);
43192
43809
  const target = resolve13(path);
43193
43810
  await syncDirectory8(dirname11(first));
43194
43811
  let current = first;
43195
- const descendants = relative9(first, target);
43196
- for (const part of descendants ? descendants.split(sep6) : []) {
43812
+ const descendants = relative10(first, target);
43813
+ for (const part of descendants ? descendants.split(sep7) : []) {
43197
43814
  await syncDirectory8(current);
43198
- current = join22(current, part);
43815
+ current = join23(current, part);
43199
43816
  }
43200
43817
  }
43201
43818
  async function replacePrivateFile(path, contents, mode, syncDirectory8) {
43202
43819
  const parent = dirname11(path);
43203
43820
  await ensureDirectory(parent, 448, syncDirectory8);
43204
- const temporary = join22(parent, `.${basename4(path)}.${process.pid}.${crypto.randomUUID()}.tmp`);
43821
+ const temporary = join23(parent, `.${basename4(path)}.${process.pid}.${crypto.randomUUID()}.tmp`);
43205
43822
  const handle = await open7(temporary, "wx", mode);
43206
43823
  try {
43207
43824
  await handle.writeFile(contents, "utf8");
43208
43825
  await handle.sync();
43209
43826
  await handle.close();
43210
- await rename7(temporary, path);
43211
- await chmod8(path, mode);
43827
+ await rename8(temporary, path);
43828
+ await chmod9(path, mode);
43212
43829
  await syncDirectory8(parent);
43213
43830
  } catch (error52) {
43214
43831
  await handle.close().catch(() => void 0);
43215
- await rm11(temporary, { force: true }).catch(() => void 0);
43832
+ await rm12(temporary, { force: true }).catch(() => void 0);
43216
43833
  throw error52;
43217
43834
  }
43218
43835
  }
@@ -43253,11 +43870,11 @@ async function installLinuxService(options) {
43253
43870
  "command search path"
43254
43871
  );
43255
43872
  const cloudUrl = options.cloudUrl ? oneLine(options.cloudUrl, "Zixt Cloud address") : void 0;
43256
- const xdgConfigHome = env.XDG_CONFIG_HOME ? oneLine(env.XDG_CONFIG_HOME, "Linux configuration path") : join22(home, ".config");
43257
- const configRoot = options.serviceConfigRoot ?? join22(xdgConfigHome, "zixt");
43258
- const unitRoot = options.userUnitRoot ?? join22(xdgConfigHome, "systemd", "user");
43259
- const environmentPath = join22(configRoot, "host.env");
43260
- const unitPath = join22(unitRoot, SERVICE_NAME);
43873
+ const xdgConfigHome = env.XDG_CONFIG_HOME ? oneLine(env.XDG_CONFIG_HOME, "Linux configuration path") : join23(home, ".config");
43874
+ const configRoot = options.serviceConfigRoot ?? join23(xdgConfigHome, "zixt");
43875
+ const unitRoot = options.userUnitRoot ?? join23(xdgConfigHome, "systemd", "user");
43876
+ const environmentPath = join23(configRoot, "host.env");
43877
+ const unitPath = join23(unitRoot, SERVICE_NAME);
43261
43878
  const installVersion = options.installVersion ?? ((version2, onFailure) => installRelease(version2, onFailure ? { onFailure } : {}));
43262
43879
  const activateVersion = options.activateVersion ?? (options.installVersion ? async (entry) => entry : activateInstalledRelease);
43263
43880
  const resolveCommand = options.resolveCommand ?? defaultResolveCommand;
@@ -43297,7 +43914,7 @@ async function installLinuxService(options) {
43297
43914
  }
43298
43915
  }
43299
43916
  await ensureDirectory(configRoot, 448, syncDirectory8);
43300
- await chmod8(configRoot, 448);
43917
+ await chmod9(configRoot, 448);
43301
43918
  const serviceEnvironment = [
43302
43919
  `ZIXT_HOST_TOKEN=${systemdEnvironmentValue(token2)}`,
43303
43920
  ...cloudUrl ? [`ZIXT_CLOUD_URL=${systemdEnvironmentValue(cloudUrl)}`] : [],
@@ -43385,11 +44002,11 @@ async function installLinuxService(options) {
43385
44002
  }
43386
44003
 
43387
44004
  // src/macos-service.ts
43388
- import { spawn as spawn13 } from "node:child_process";
44005
+ import { spawn as spawn14 } from "node:child_process";
43389
44006
  import { constants as constants3 } from "node:fs";
43390
- import { access as access6, chmod as chmod9, mkdir as mkdir16, open as open8, rename as rename8, rm as rm12 } from "node:fs/promises";
44007
+ import { access as access6, chmod as chmod10, mkdir as mkdir17, open as open8, rename as rename9, rm as rm13 } from "node:fs/promises";
43391
44008
  import { homedir as homedir12, userInfo as userInfo2 } from "node:os";
43392
- import { basename as basename5, dirname as dirname12, join as join23, relative as relative10, resolve as resolve14, sep as sep7 } from "node:path";
44009
+ import { basename as basename5, dirname as dirname12, join as join24, relative as relative11, resolve as resolve14, sep as sep8 } from "node:path";
43393
44010
  var LAUNCH_AGENT_LABEL = "ai.zixt.host";
43394
44011
  var SERVICE_STABILITY_DELAY_MS2 = 2e3;
43395
44012
  var STATUS_WAIT_MS = 2e4;
@@ -43414,32 +44031,32 @@ async function syncDirectory4(path) {
43414
44031
  }
43415
44032
  }
43416
44033
  async function ensureDirectory2(path, sync) {
43417
- const firstCreated = await mkdir16(path, { recursive: true, mode: 448 });
44034
+ const firstCreated = await mkdir17(path, { recursive: true, mode: 448 });
43418
44035
  if (!firstCreated) return;
43419
44036
  const first = resolve14(firstCreated);
43420
44037
  const target = resolve14(path);
43421
44038
  await sync(dirname12(first));
43422
44039
  let current = first;
43423
- for (const part of relative10(first, target).split(sep7).filter(Boolean)) {
44040
+ for (const part of relative11(first, target).split(sep8).filter(Boolean)) {
43424
44041
  await sync(current);
43425
- current = join23(current, part);
44042
+ current = join24(current, part);
43426
44043
  }
43427
44044
  }
43428
44045
  async function replacePrivateFile2(path, contents, mode, sync) {
43429
44046
  const parent = dirname12(path);
43430
44047
  await ensureDirectory2(parent, sync);
43431
- const temporary = join23(parent, `.${basename5(path)}.${process.pid}.${crypto.randomUUID()}.tmp`);
44048
+ const temporary = join24(parent, `.${basename5(path)}.${process.pid}.${crypto.randomUUID()}.tmp`);
43432
44049
  const handle = await open8(temporary, "wx", mode);
43433
44050
  try {
43434
44051
  await handle.writeFile(contents, "utf8");
43435
44052
  await handle.sync();
43436
44053
  await handle.close();
43437
- await rename8(temporary, path);
43438
- await chmod9(path, mode);
44054
+ await rename9(temporary, path);
44055
+ await chmod10(path, mode);
43439
44056
  await sync(parent);
43440
44057
  } catch (error52) {
43441
44058
  await handle.close().catch(() => void 0);
43442
- await rm12(temporary, { force: true }).catch(() => void 0);
44059
+ await rm13(temporary, { force: true }).catch(() => void 0);
43443
44060
  throw error52;
43444
44061
  }
43445
44062
  }
@@ -43453,7 +44070,7 @@ function commandEnvironment(env) {
43453
44070
  }
43454
44071
  async function defaultRunCommand2(command, args, env) {
43455
44072
  return new Promise((resolveResult) => {
43456
- const child = spawn13(command, [...args], {
44073
+ const child = spawn14(command, [...args], {
43457
44074
  stdio: ["ignore", "pipe", "pipe"],
43458
44075
  env: commandEnvironment(env)
43459
44076
  });
@@ -43525,14 +44142,14 @@ async function installMacosService(options) {
43525
44142
  options.path ?? env.PATH ?? "/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin",
43526
44143
  "command search path"
43527
44144
  );
43528
- const configRoot = options.configRoot ?? join23(home, "Library", "Application Support", "Zixt");
43529
- const launchAgentsRoot = options.launchAgentsRoot ?? join23(home, "Library", "LaunchAgents");
43530
- const logRoot = options.logRoot ?? join23(home, "Library", "Logs", "Zixt");
43531
- const configPath = join23(configRoot, "host.env");
43532
- const launcherPath = join23(configRoot, "host-launcher.sh");
43533
- const plistPath = join23(launchAgentsRoot, `${LAUNCH_AGENT_LABEL}.plist`);
43534
- const stdoutPath = join23(logRoot, "host.log");
43535
- const stderrPath = join23(logRoot, "host-error.log");
44145
+ const configRoot = options.configRoot ?? join24(home, "Library", "Application Support", "Zixt");
44146
+ const launchAgentsRoot = options.launchAgentsRoot ?? join24(home, "Library", "LaunchAgents");
44147
+ const logRoot = options.logRoot ?? join24(home, "Library", "Logs", "Zixt");
44148
+ const configPath = join24(configRoot, "host.env");
44149
+ const launcherPath = join24(configRoot, "host-launcher.sh");
44150
+ const plistPath = join24(launchAgentsRoot, `${LAUNCH_AGENT_LABEL}.plist`);
44151
+ const stdoutPath = join24(logRoot, "host.log");
44152
+ const stderrPath = join24(logRoot, "host-error.log");
43536
44153
  const installVersion = options.installVersion ?? ((version2, onFailure) => installRelease(version2, onFailure ? { onFailure } : {}));
43537
44154
  const activateVersion = options.activateVersion ?? (options.installVersion ? async (entry) => entry : (entry) => activateInstalledRelease(entry));
43538
44155
  const resolveCommand = options.resolveCommand ?? (async () => defaultResolveCommand2());
@@ -43555,7 +44172,7 @@ async function installMacosService(options) {
43555
44172
  await ensureDirectory2(configRoot, sync);
43556
44173
  await ensureDirectory2(launchAgentsRoot, sync);
43557
44174
  await ensureDirectory2(logRoot, sync);
43558
- await chmod9(configRoot, 448);
44175
+ await chmod10(configRoot, 448);
43559
44176
  const serviceEnvironment = [
43560
44177
  `ZIXT_HOST_TOKEN=${shellValue(token2)}`,
43561
44178
  ...cloudUrl ? [`ZIXT_CLOUD_URL=${shellValue(cloudUrl)}`] : [],
@@ -43633,11 +44250,11 @@ async function installMacosService(options) {
43633
44250
  }
43634
44251
 
43635
44252
  // src/windows-service.ts
43636
- import { spawn as spawn14 } from "node:child_process";
44253
+ import { spawn as spawn15 } from "node:child_process";
43637
44254
  import { constants as constants4 } from "node:fs";
43638
- import { access as access7, mkdir as mkdir17, open as open9, readFile as readFile11, rename as rename9, rm as rm13 } from "node:fs/promises";
44255
+ import { access as access7, mkdir as mkdir18, open as open9, readFile as readFile12, rename as rename10, rm as rm14 } from "node:fs/promises";
43639
44256
  import { homedir as homedir13 } from "node:os";
43640
- 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";
44257
+ import { basename as basename6, dirname as dirname13, isAbsolute as isAbsolute18, join as join25, relative as relative12, resolve as resolve15, sep as sep9 } from "node:path";
43641
44258
  var TASK_NAME = "Zixt Host";
43642
44259
  var COMMAND_TIMEOUT_MS3 = 7e4;
43643
44260
  var SERVICE_STABILITY_DELAY_MS3 = 2e3;
@@ -43663,31 +44280,31 @@ async function syncDirectory5(path) {
43663
44280
  }
43664
44281
  }
43665
44282
  async function ensureDirectory3(path, sync) {
43666
- const firstCreated = await mkdir17(path, { recursive: true, mode: 448 });
44283
+ const firstCreated = await mkdir18(path, { recursive: true, mode: 448 });
43667
44284
  if (!firstCreated) return;
43668
44285
  const first = resolve15(firstCreated);
43669
44286
  const target = resolve15(path);
43670
44287
  await sync(dirname13(first));
43671
44288
  let current = first;
43672
- for (const part of relative11(first, target).split(sep8).filter(Boolean)) {
44289
+ for (const part of relative12(first, target).split(sep9).filter(Boolean)) {
43673
44290
  await sync(current);
43674
- current = join24(current, part);
44291
+ current = join25(current, part);
43675
44292
  }
43676
44293
  }
43677
44294
  async function replacePrivateFile3(path, contents, sync, encoding = "utf8") {
43678
44295
  const parent = dirname13(path);
43679
44296
  await ensureDirectory3(parent, sync);
43680
- const temporary = join24(parent, `.${basename6(path)}.${process.pid}.${crypto.randomUUID()}.tmp`);
44297
+ const temporary = join25(parent, `.${basename6(path)}.${process.pid}.${crypto.randomUUID()}.tmp`);
43681
44298
  const handle = await open9(temporary, "wx", 384);
43682
44299
  try {
43683
44300
  await handle.writeFile(encoding === "utf16le" ? `\uFEFF${contents}` : contents, encoding);
43684
44301
  await handle.sync();
43685
44302
  await handle.close();
43686
- await rename9(temporary, path);
44303
+ await rename10(temporary, path);
43687
44304
  await sync(parent);
43688
44305
  } catch (error52) {
43689
44306
  await handle.close().catch(() => void 0);
43690
- await rm13(temporary, { force: true }).catch(() => void 0);
44307
+ await rm14(temporary, { force: true }).catch(() => void 0);
43691
44308
  throw error52;
43692
44309
  }
43693
44310
  }
@@ -43698,7 +44315,7 @@ function commandEnvironment2(env) {
43698
44315
  }
43699
44316
  async function runChild(command, args, env, input) {
43700
44317
  return new Promise((resolveResult) => {
43701
- const child = spawn14(command, [...args], {
44318
+ const child = spawn15(command, [...args], {
43702
44319
  stdio: [input === void 0 ? "ignore" : "pipe", "pipe", "pipe"],
43703
44320
  env: commandEnvironment2(env),
43704
44321
  windowsHide: true
@@ -43732,7 +44349,7 @@ async function runChild(command, args, env, input) {
43732
44349
  async function defaultResolveCommand3(name, env) {
43733
44350
  const root = env.SYSTEMROOT ?? env.WINDIR;
43734
44351
  if (!root || !isAbsolute18(root)) return null;
43735
- const candidate = name === "powershell" ? join24(root, "System32", "WindowsPowerShell", "v1.0", "powershell.exe") : join24(root, "System32", `${name}.exe`);
44352
+ const candidate = name === "powershell" ? join25(root, "System32", "WindowsPowerShell", "v1.0", "powershell.exe") : join25(root, "System32", `${name}.exe`);
43736
44353
  return access7(candidate, constants4.X_OK).then(
43737
44354
  () => candidate,
43738
44355
  () => null
@@ -43822,7 +44439,7 @@ exit $code
43822
44439
  }
43823
44440
  async function defaultObserveStatus(path, generation) {
43824
44441
  try {
43825
- const text = (await readFile11(path, "utf8")).replace(/^\uFEFF/, "");
44442
+ const text = (await readFile12(path, "utf8")).replace(/^\uFEFF/, "");
43826
44443
  const value = JSON.parse(text);
43827
44444
  if (value.schema !== 1 || value.generation !== generation || typeof value.pid !== "number" || !Number.isSafeInteger(value.pid) || value.pid <= 0) {
43828
44445
  return null;
@@ -43883,12 +44500,12 @@ async function installWindowsService(options) {
43883
44500
  const token2 = oneLine3(options.token, "pairing code");
43884
44501
  const cloudUrl = options.cloudUrl ? oneLine3(options.cloudUrl, "Zixt Cloud address") : void 0;
43885
44502
  const path = oneLine3(options.path ?? env.PATH ?? "", "command search path");
43886
- const configRoot = options.configRoot ?? join24(localAppData, "Zixt", "Host");
43887
- const configPath = join24(configRoot, "host.json");
43888
- const launcherPath = join24(configRoot, "host-launcher.ps1");
43889
- const launchShimPath = join24(configRoot, "host-launch.vbs");
43890
- const taskXmlPath = join24(configRoot, "host-task.xml");
43891
- const statusPath = join24(configRoot, "host-status.json");
44503
+ const configRoot = options.configRoot ?? join25(localAppData, "Zixt", "Host");
44504
+ const configPath = join25(configRoot, "host.json");
44505
+ const launcherPath = join25(configRoot, "host-launcher.ps1");
44506
+ const launchShimPath = join25(configRoot, "host-launch.vbs");
44507
+ const taskXmlPath = join25(configRoot, "host-task.xml");
44508
+ const statusPath = join25(configRoot, "host-status.json");
43892
44509
  const installVersion = options.installVersion ?? ((version2, onFailure) => installRelease(version2, onFailure ? { onFailure } : {}));
43893
44510
  const activateVersion = options.activateVersion ?? (options.installVersion ? async (entry) => entry : (entry) => activateInstalledRelease(entry));
43894
44511
  const resolveCommand = options.resolveCommand ?? ((name) => defaultResolveCommand3(name, env));
@@ -43955,7 +44572,7 @@ async function installWindowsService(options) {
43955
44572
  sync,
43956
44573
  "utf16le"
43957
44574
  );
43958
- await rm13(statusPath, { force: true });
44575
+ await rm14(statusPath, { force: true });
43959
44576
  const acl = await run3(icacls, [
43960
44577
  configRoot,
43961
44578
  "/inheritance:r",
@@ -44015,23 +44632,23 @@ async function installSystemService(options) {
44015
44632
  }
44016
44633
 
44017
44634
  // src/terminal-outcomes.ts
44018
- 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";
44635
+ import { chmod as chmod11, lstat as lstat12, mkdir as mkdir19, open as open10, readdir as readdir7, readFile as readFile13, rename as rename11, rm as rm15 } from "node:fs/promises";
44019
44636
  import { homedir as homedir14 } from "node:os";
44020
- import { dirname as dirname14, join as join25, relative as relative12, resolve as resolve16, sep as sep9 } from "node:path";
44637
+ import { dirname as dirname14, join as join26, relative as relative13, resolve as resolve16, sep as sep10 } from "node:path";
44021
44638
  var DIRECTORY_MODE5 = 448;
44022
44639
  var FILE_MODE4 = 384;
44023
44640
  var MAX_OUTCOME_BYTES = 4 * 1024 * 1024;
44024
44641
  var HOST_DIRECTORY = /^hst_[0-9a-f]{32}$/;
44025
44642
  var OUTCOME_FILE = /^(tsk_[0-9a-f]{32})\.([1-9][0-9]*)\.json$/;
44026
44643
  function defaultTerminalOutcomeRoot() {
44027
- return join25(homedir14(), ".zixt", "terminal-outcomes");
44644
+ return join26(homedir14(), ".zixt", "terminal-outcomes");
44028
44645
  }
44029
44646
  function hostOutcomeRoot(root, hostId) {
44030
44647
  if (!HOST_DIRECTORY.test(hostId)) throw new Error("terminal outcome Host identity is malformed");
44031
- return join25(root, hostId);
44648
+ return join26(root, hostId);
44032
44649
  }
44033
44650
  function outcomePath(root, hostId, taskId, epoch) {
44034
- return join25(hostOutcomeRoot(root, hostId), `${taskId}.${epoch}.json`);
44651
+ return join26(hostOutcomeRoot(root, hostId), `${taskId}.${epoch}.json`);
44035
44652
  }
44036
44653
  async function syncDirectory6(root) {
44037
44654
  if (process.platform === "win32") return;
@@ -44043,22 +44660,22 @@ async function syncDirectory6(root) {
44043
44660
  }
44044
44661
  }
44045
44662
  async function requirePrivateRoot(root, sync = syncDirectory6) {
44046
- const firstCreated = await mkdir18(root, { recursive: true, mode: DIRECTORY_MODE5 });
44663
+ const firstCreated = await mkdir19(root, { recursive: true, mode: DIRECTORY_MODE5 });
44047
44664
  if (firstCreated) {
44048
44665
  const first = resolve16(firstCreated);
44049
44666
  const target = resolve16(root);
44050
44667
  await sync(dirname14(first));
44051
44668
  let current = first;
44052
- for (const part of relative12(first, target).split(sep9).filter(Boolean)) {
44669
+ for (const part of relative13(first, target).split(sep10).filter(Boolean)) {
44053
44670
  await sync(current);
44054
- current = join25(current, part);
44671
+ current = join26(current, part);
44055
44672
  }
44056
44673
  }
44057
44674
  const stat4 = await lstat12(root);
44058
44675
  if (stat4.isSymbolicLink() || !stat4.isDirectory()) {
44059
44676
  throw new Error("terminal outcome journal root is not a trusted directory");
44060
44677
  }
44061
- await chmod10(root, DIRECTORY_MODE5);
44678
+ await chmod11(root, DIRECTORY_MODE5);
44062
44679
  }
44063
44680
  function parseCommittedOutcome(text, taskId, epoch) {
44064
44681
  let json2;
@@ -44082,7 +44699,7 @@ async function recordTerminalOutcome(hostId, input, root = defaultTerminalOutcom
44082
44699
  const destination = outcomePath(root, hostId, outcome.taskId, outcome.epoch);
44083
44700
  try {
44084
44701
  const existing = parseCommittedOutcome(
44085
- await readFile12(destination, { encoding: "utf8", flag: "r" }),
44702
+ await readFile13(destination, { encoding: "utf8", flag: "r" }),
44086
44703
  outcome.taskId,
44087
44704
  outcome.epoch
44088
44705
  );
@@ -44091,7 +44708,7 @@ async function recordTerminalOutcome(hostId, input, root = defaultTerminalOutcom
44091
44708
  } catch (error52) {
44092
44709
  if (error52.code !== "ENOENT") throw error52;
44093
44710
  }
44094
- const temporary = join25(
44711
+ const temporary = join26(
44095
44712
  scopedRoot,
44096
44713
  `.${outcome.taskId}.${outcome.epoch}.${process.pid}.${Date.now()}.${outcome.resultId}.tmp`
44097
44714
  );
@@ -44102,13 +44719,13 @@ async function recordTerminalOutcome(hostId, input, root = defaultTerminalOutcom
44102
44719
  await handle.sync();
44103
44720
  await handle.close();
44104
44721
  handle = void 0;
44105
- await rename10(temporary, destination);
44722
+ await rename11(temporary, destination);
44106
44723
  await sync(scopedRoot);
44107
44724
  await sync(root);
44108
44725
  } finally {
44109
44726
  await handle?.close().catch(() => {
44110
44727
  });
44111
- await rm14(temporary, { force: true }).catch(() => {
44728
+ await rm15(temporary, { force: true }).catch(() => {
44112
44729
  });
44113
44730
  }
44114
44731
  }
@@ -44123,8 +44740,8 @@ async function readTerminalOutcomesStrict(root = defaultTerminalOutcomeRoot()) {
44123
44740
  if (rootStat.isSymbolicLink() || !rootStat.isDirectory()) {
44124
44741
  throw new Error("terminal outcome journal root is not a trusted directory");
44125
44742
  }
44126
- await chmod10(root, DIRECTORY_MODE5);
44127
- const hostEntries = await readdir6(root, { withFileTypes: true });
44743
+ await chmod11(root, DIRECTORY_MODE5);
44744
+ const hostEntries = await readdir7(root, { withFileTypes: true });
44128
44745
  const outcomes = [];
44129
44746
  const resultIds = /* @__PURE__ */ new Set();
44130
44747
  for (const hostEntry of hostEntries) {
@@ -44136,21 +44753,21 @@ async function readTerminalOutcomesStrict(root = defaultTerminalOutcomeRoot()) {
44136
44753
  if (scopedStat.isSymbolicLink() || !scopedStat.isDirectory()) {
44137
44754
  throw new Error("terminal outcome Host scope is not a trusted directory");
44138
44755
  }
44139
- await chmod10(scopedRoot, DIRECTORY_MODE5);
44140
- const entries = await readdir6(scopedRoot, { withFileTypes: true });
44756
+ await chmod11(scopedRoot, DIRECTORY_MODE5);
44757
+ const entries = await readdir7(scopedRoot, { withFileTypes: true });
44141
44758
  for (const entry of entries) {
44142
44759
  if (!entry.name.endsWith(".json")) continue;
44143
44760
  const match = OUTCOME_FILE.exec(entry.name);
44144
44761
  if (!match || !entry.isFile() || entry.isSymbolicLink()) {
44145
44762
  throw new Error("committed terminal outcome is not a trusted regular file");
44146
44763
  }
44147
- const path = join25(scopedRoot, entry.name);
44764
+ const path = join26(scopedRoot, entry.name);
44148
44765
  const stat4 = await lstat12(path);
44149
44766
  if (!stat4.isFile() || stat4.isSymbolicLink() || stat4.size > MAX_OUTCOME_BYTES) {
44150
44767
  throw new Error("committed terminal outcome is not a trusted regular file");
44151
44768
  }
44152
44769
  const outcome = parseCommittedOutcome(
44153
- await readFile12(path, "utf8"),
44770
+ await readFile13(path, "utf8"),
44154
44771
  match[1],
44155
44772
  Number(match[2])
44156
44773
  );
@@ -44177,7 +44794,7 @@ async function forgetAcknowledgedTerminalOutcomes(refs, root = defaultTerminalOu
44177
44794
  if (acknowledged.get(`${hostId}:${outcome.taskId}:${outcome.epoch}`) !== outcome.resultId) {
44178
44795
  continue;
44179
44796
  }
44180
- await rm14(outcomePath(root, hostId, outcome.taskId, outcome.epoch), { force: true });
44797
+ await rm15(outcomePath(root, hostId, outcome.taskId, outcome.epoch), { force: true });
44181
44798
  changedHostRoots.add(hostOutcomeRoot(root, hostId));
44182
44799
  }
44183
44800
  for (const scopedRoot of changedHostRoots) await syncDirectory6(scopedRoot);
@@ -44189,22 +44806,22 @@ async function forgetSupersededTerminalOutcomes(hostId, taskId, epoch, root = de
44189
44806
  if (scoped.hostId !== hostId) continue;
44190
44807
  const { outcome } = scoped;
44191
44808
  if (outcome.taskId !== taskId || outcome.epoch >= epoch) continue;
44192
- await rm14(outcomePath(root, hostId, outcome.taskId, outcome.epoch), { force: true });
44809
+ await rm15(outcomePath(root, hostId, outcome.taskId, outcome.epoch), { force: true });
44193
44810
  removed = true;
44194
44811
  }
44195
44812
  if (removed) await syncDirectory6(hostOutcomeRoot(root, hostId));
44196
44813
  }
44197
44814
 
44198
44815
  // src/accepted-assignments.ts
44199
- 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";
44816
+ import { chmod as chmod12, lstat as lstat13, mkdir as mkdir20, open as open11, readdir as readdir8, rename as rename12, rm as rm16 } from "node:fs/promises";
44200
44817
  import { homedir as homedir15 } from "node:os";
44201
- import { dirname as dirname15, join as join26, relative as relative13, resolve as resolve17, sep as sep10 } from "node:path";
44818
+ import { dirname as dirname15, join as join27, relative as relative14, resolve as resolve17, sep as sep11 } from "node:path";
44202
44819
  var DIRECTORY_MODE6 = 448;
44203
44820
  var FILE_MODE5 = 384;
44204
44821
  var CLAIM_FILE = /^(tsk_[0-9a-f]{32})\.([1-9][0-9]*)\.json$/;
44205
44822
  var TASK_ID = /^tsk_[0-9a-f]{32}$/;
44206
44823
  function defaultAcceptedAssignmentRoot() {
44207
- return join26(homedir15(), ".zixt", "accepted-assignments");
44824
+ return join27(homedir15(), ".zixt", "accepted-assignments");
44208
44825
  }
44209
44826
  async function syncDirectory7(root) {
44210
44827
  if (process.platform === "win32") return;
@@ -44216,29 +44833,29 @@ async function syncDirectory7(root) {
44216
44833
  }
44217
44834
  }
44218
44835
  async function requirePrivateRoot2(root, sync = syncDirectory7) {
44219
- const firstCreated = await mkdir19(root, { recursive: true, mode: DIRECTORY_MODE6 });
44836
+ const firstCreated = await mkdir20(root, { recursive: true, mode: DIRECTORY_MODE6 });
44220
44837
  if (firstCreated) {
44221
44838
  const first = resolve17(firstCreated);
44222
44839
  const target = resolve17(root);
44223
44840
  await sync(dirname15(first));
44224
44841
  let current = first;
44225
- for (const part of relative13(first, target).split(sep10).filter(Boolean)) {
44842
+ for (const part of relative14(first, target).split(sep11).filter(Boolean)) {
44226
44843
  await sync(current);
44227
- current = join26(current, part);
44844
+ current = join27(current, part);
44228
44845
  }
44229
44846
  }
44230
44847
  const stat4 = await lstat13(root);
44231
44848
  if (stat4.isSymbolicLink() || !stat4.isDirectory()) {
44232
44849
  throw new Error("accepted assignment journal root is not a trusted directory");
44233
44850
  }
44234
- await chmod11(root, DIRECTORY_MODE6);
44851
+ await chmod12(root, DIRECTORY_MODE6);
44235
44852
  }
44236
44853
  function claimPath(root, taskId, epoch) {
44237
44854
  if (!TASK_ID.test(taskId)) throw new Error("accepted assignment Task identity is malformed");
44238
44855
  if (!Number.isSafeInteger(epoch) || epoch < 1) {
44239
44856
  throw new Error("accepted assignment epoch is malformed");
44240
44857
  }
44241
- return join26(root, `${taskId}.${epoch}.json`);
44858
+ return join27(root, `${taskId}.${epoch}.json`);
44242
44859
  }
44243
44860
  async function recordAcceptedAssignment(assignment, root = defaultAcceptedAssignmentRoot(), options = {}) {
44244
44861
  const sync = options.syncDirectory ?? syncDirectory7;
@@ -44248,7 +44865,7 @@ async function recordAcceptedAssignment(assignment, root = defaultAcceptedAssign
44248
44865
  } catch {
44249
44866
  return false;
44250
44867
  }
44251
- const temporary = join26(
44868
+ const temporary = join27(
44252
44869
  root,
44253
44870
  `.${assignment.taskId}.${assignment.epoch}.${process.pid}.${Date.now()}.tmp`
44254
44871
  );
@@ -44260,7 +44877,7 @@ async function recordAcceptedAssignment(assignment, root = defaultAcceptedAssign
44260
44877
  await handle.sync();
44261
44878
  await handle.close();
44262
44879
  handle = void 0;
44263
- await rename11(temporary, destination);
44880
+ await rename12(temporary, destination);
44264
44881
  if (process.platform !== "win32") await sync(root);
44265
44882
  return true;
44266
44883
  } catch {
@@ -44268,7 +44885,7 @@ async function recordAcceptedAssignment(assignment, root = defaultAcceptedAssign
44268
44885
  } finally {
44269
44886
  await handle?.close().catch(() => {
44270
44887
  });
44271
- await rm15(temporary, { force: true }).catch(() => {
44888
+ await rm16(temporary, { force: true }).catch(() => {
44272
44889
  });
44273
44890
  }
44274
44891
  }
@@ -44283,9 +44900,9 @@ async function recoverAcceptedAssignments(root = defaultAcceptedAssignmentRoot()
44283
44900
  if (rootStat.isSymbolicLink() || !rootStat.isDirectory()) {
44284
44901
  throw new Error("accepted assignment journal root is not a trusted directory");
44285
44902
  }
44286
- await chmod11(root, DIRECTORY_MODE6);
44903
+ await chmod12(root, DIRECTORY_MODE6);
44287
44904
  const claims = [];
44288
- for (const entry of await readdir7(root, { withFileTypes: true })) {
44905
+ for (const entry of await readdir8(root, { withFileTypes: true })) {
44289
44906
  if (!entry.isFile()) continue;
44290
44907
  const match = CLAIM_FILE.exec(entry.name);
44291
44908
  if (!match) continue;
@@ -44302,7 +44919,7 @@ async function forgetAcceptedAssignment(assignment, root = defaultAcceptedAssign
44302
44919
  } catch {
44303
44920
  return;
44304
44921
  }
44305
- await rm15(path, { force: true }).catch(() => {
44922
+ await rm16(path, { force: true }).catch(() => {
44306
44923
  });
44307
44924
  }
44308
44925
  async function forgetAcknowledgedAcceptedAssignments(assignments, root = defaultAcceptedAssignmentRoot()) {
@@ -44310,9 +44927,9 @@ async function forgetAcknowledgedAcceptedAssignments(assignments, root = default
44310
44927
  }
44311
44928
 
44312
44929
  // src/local-observability.ts
44313
- import { appendFile, mkdir as mkdir20, open as open12, readdir as readdir8, rename as rename12, rm as rm16, stat as stat3 } from "node:fs/promises";
44930
+ import { appendFile, mkdir as mkdir21, open as open12, readdir as readdir9, rename as rename13, rm as rm17, stat as stat3 } from "node:fs/promises";
44314
44931
  import { homedir as homedir16 } from "node:os";
44315
- import { basename as basename7, dirname as dirname16, join as join27 } from "node:path";
44932
+ import { basename as basename7, dirname as dirname16, join as join28 } from "node:path";
44316
44933
 
44317
44934
  // src/logger.ts
44318
44935
  var ANSI = {
@@ -44424,11 +45041,11 @@ var LOCAL_STATUS_FILE = "status.json";
44424
45041
  var LOCAL_REQUESTS_DIR = "requests";
44425
45042
  var DEFAULT_CONSOLE_ROTATE_BYTES = 2 * 1024 * 1024;
44426
45043
  function defaultLocalObservabilityRoot() {
44427
- return join27(homedir16(), ".zixt", "observability");
45044
+ return join28(homedir16(), ".zixt", "observability");
44428
45045
  }
44429
45046
  function createLocalConsoleSink(options = {}) {
44430
45047
  const root = options.root ?? defaultLocalObservabilityRoot();
44431
- const consolePath = join27(root, LOCAL_CONSOLE_FILE);
45048
+ const consolePath = join28(root, LOCAL_CONSOLE_FILE);
44432
45049
  const rotateBytes = options.rotateBytes ?? DEFAULT_CONSOLE_ROTATE_BYTES;
44433
45050
  let disabled = false;
44434
45051
  let prepared = false;
@@ -44438,7 +45055,7 @@ function createLocalConsoleSink(options = {}) {
44438
45055
  if (disabled) return;
44439
45056
  try {
44440
45057
  if (!prepared) {
44441
- await mkdir20(root, { recursive: true, mode: 448 });
45058
+ await mkdir21(root, { recursive: true, mode: 448 });
44442
45059
  approximateBytes = await stat3(consolePath).then(
44443
45060
  (existing) => existing.size,
44444
45061
  () => 0
@@ -44446,8 +45063,8 @@ function createLocalConsoleSink(options = {}) {
44446
45063
  prepared = true;
44447
45064
  }
44448
45065
  if (approximateBytes >= rotateBytes) {
44449
- await rm16(join27(root, LOCAL_CONSOLE_PREVIOUS_FILE), { force: true });
44450
- await rename12(consolePath, join27(root, LOCAL_CONSOLE_PREVIOUS_FILE)).catch(
45066
+ await rm17(join28(root, LOCAL_CONSOLE_PREVIOUS_FILE), { force: true });
45067
+ await rename13(consolePath, join28(root, LOCAL_CONSOLE_PREVIOUS_FILE)).catch(
44451
45068
  (error52) => {
44452
45069
  if (error52.code !== "ENOENT") throw error52;
44453
45070
  }
@@ -44478,11 +45095,11 @@ function createLocalConsoleSink(options = {}) {
44478
45095
  };
44479
45096
  }
44480
45097
  async function consumeRunnerInstallRequests(root = defaultLocalObservabilityRoot()) {
44481
- const directory = join27(root, LOCAL_REQUESTS_DIR);
45098
+ const directory = join28(root, LOCAL_REQUESTS_DIR);
44482
45099
  const requested = /* @__PURE__ */ new Set();
44483
45100
  let names;
44484
45101
  try {
44485
- names = await readdir8(directory);
45102
+ names = await readdir9(directory);
44486
45103
  } catch {
44487
45104
  return requested;
44488
45105
  }
@@ -44490,7 +45107,7 @@ async function consumeRunnerInstallRequests(root = defaultLocalObservabilityRoot
44490
45107
  const name = `install-runner-${type}.json`;
44491
45108
  if (!names.includes(name)) continue;
44492
45109
  try {
44493
- await rm16(join27(directory, name), { force: true });
45110
+ await rm17(join28(directory, name), { force: true });
44494
45111
  requested.add(type);
44495
45112
  } catch {
44496
45113
  }
@@ -44498,13 +45115,13 @@ async function consumeRunnerInstallRequests(root = defaultLocalObservabilityRoot
44498
45115
  return requested;
44499
45116
  }
44500
45117
  async function writeLocalStatus(status, root = defaultLocalObservabilityRoot()) {
44501
- const destination = join27(root, LOCAL_STATUS_FILE);
44502
- const temporary = join27(
45118
+ const destination = join28(root, LOCAL_STATUS_FILE);
45119
+ const temporary = join28(
44503
45120
  dirname16(destination),
44504
45121
  `.${basename7(destination)}.${process.pid}.${crypto.randomUUID()}.tmp`
44505
45122
  );
44506
45123
  try {
44507
- await mkdir20(root, { recursive: true, mode: 448 });
45124
+ await mkdir21(root, { recursive: true, mode: 448 });
44508
45125
  const handle = await open12(temporary, "wx", 384);
44509
45126
  try {
44510
45127
  await handle.writeFile(`${JSON.stringify(status)}
@@ -44512,14 +45129,14 @@ async function writeLocalStatus(status, root = defaultLocalObservabilityRoot())
44512
45129
  } finally {
44513
45130
  await handle.close();
44514
45131
  }
44515
- await rename12(temporary, destination);
45132
+ await rename13(temporary, destination);
44516
45133
  } catch {
44517
- await rm16(temporary, { force: true }).catch(() => void 0);
45134
+ await rm17(temporary, { force: true }).catch(() => void 0);
44518
45135
  }
44519
45136
  }
44520
45137
 
44521
45138
  // src/demo-state.ts
44522
- import { isAbsolute as isAbsolute19, join as join28, parse as parse3, resolve as resolve18 } from "node:path";
45139
+ import { isAbsolute as isAbsolute19, join as join29, parse as parse3, resolve as resolve18 } from "node:path";
44523
45140
  var DEMO_STATE_ROOT_ENV = "ZIXT_DEMO_STATE_ROOT";
44524
45141
  function resolveDemoHostStatePaths(env = process.env) {
44525
45142
  const configured = env.ZIXT_RUNNER === "demo" ? env[DEMO_STATE_ROOT_ENV] : void 0;
@@ -44529,14 +45146,14 @@ function resolveDemoHostStatePaths(env = process.env) {
44529
45146
  throw new Error(`${DEMO_STATE_ROOT_ENV} must be a dedicated absolute directory`);
44530
45147
  }
44531
45148
  return {
44532
- runRegistryRoot: join28(root, "run-registry"),
44533
- terminalOutcomeRoot: join28(root, "terminal-outcomes"),
44534
- acceptedAssignmentRoot: join28(root, "accepted-assignments"),
44535
- runArtifactRoot: join28(root, "run-artifacts"),
44536
- browserProfileRoot: join28(root, "browser-profiles"),
44537
- runnerWorkspaceRoot: join28(root, "workspaces"),
44538
- codexThreadIndexRoot: join28(root, "codex-threads"),
44539
- localObservabilityRoot: join28(root, "local-observability")
45149
+ runRegistryRoot: join29(root, "run-registry"),
45150
+ terminalOutcomeRoot: join29(root, "terminal-outcomes"),
45151
+ acceptedAssignmentRoot: join29(root, "accepted-assignments"),
45152
+ runArtifactRoot: join29(root, "run-artifacts"),
45153
+ browserProfileRoot: join29(root, "browser-profiles"),
45154
+ runnerWorkspaceRoot: join29(root, "workspaces"),
45155
+ codexThreadIndexRoot: join29(root, "codex-threads"),
45156
+ localObservabilityRoot: join29(root, "local-observability")
44540
45157
  };
44541
45158
  }
44542
45159