@zixt/host 0.0.49 → 0.0.51

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 +586 -315
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -15,23 +15,23 @@ import { spawn as spawn4 } from "node:child_process";
15
15
  import { fstatSync } from "node:fs";
16
16
  import {
17
17
  access as access2,
18
- lstat as lstat3,
18
+ lstat as lstat4,
19
19
  mkdir as mkdir3,
20
20
  open as open3,
21
- readFile as readFile4,
21
+ readFile as readFile5,
22
22
  readlink,
23
23
  readdir as readdir2,
24
24
  rename as rename2,
25
25
  rm as rm3,
26
26
  symlink
27
27
  } from "node:fs/promises";
28
- import { basename as basename2, dirname as dirname3, isAbsolute as isAbsolute6, join as join6, relative as relative2, resolve as resolve3, sep as sep2 } from "node:path";
28
+ import { basename as basename3, dirname as dirname3, isAbsolute as isAbsolute7, join as join6, relative as relative3, resolve as resolve4, sep as sep3 } from "node:path";
29
29
  import { homedir } from "node:os";
30
30
 
31
31
  // package.json
32
32
  var package_default = {
33
33
  name: "@zixt/host",
34
- version: "0.0.49",
34
+ version: "0.0.51",
35
35
  type: "module",
36
36
  exports: {
37
37
  ".": "./src/client.ts",
@@ -14647,6 +14647,8 @@ var ID_PREFIXES = {
14647
14647
  browserSession: "brs",
14648
14648
  /** One file a person attached to a chat message ('att' is taken by attempt). */
14649
14649
  attachment: "atc",
14650
+ /** Immutable file created by an AI teammate during a Task. */
14651
+ artifact: "art",
14650
14652
  /** One curated memory entry an agent chose to keep ('mem' is taken by member). */
14651
14653
  memory: "mry",
14652
14654
  /** Org-singleton Manager configuration (PRD §8.13). */
@@ -14694,6 +14696,7 @@ var OrgSkillId = idSchema(ID_PREFIXES.orgSkill, "organization skill id");
14694
14696
  var OrgRoutineId = idSchema(ID_PREFIXES.orgRoutine, "organization routine id");
14695
14697
  var BrowserSessionId = idSchema(ID_PREFIXES.browserSession, "browser session id");
14696
14698
  var AttachmentId = idSchema(ID_PREFIXES.attachment, "attachment id");
14699
+ var TaskArtifactId = idSchema(ID_PREFIXES.artifact, "task artifact id");
14697
14700
  var MemoryId = idSchema(ID_PREFIXES.memory, "memory id");
14698
14701
  var ManagerId = idSchema(ID_PREFIXES.manager, "manager id");
14699
14702
  var ManagerMemoryId = idSchema(ID_PREFIXES.managerMemory, "manager memory id");
@@ -16019,6 +16022,28 @@ var UploadAttachmentRequest = external_exports.object({
16019
16022
  data: external_exports.string().min(1).max(Math.ceil(TASK_ATTACHMENT_MAX_BYTES / 3 * 4) + 4)
16020
16023
  });
16021
16024
  var UploadAttachmentResponse = external_exports.object({ attachment: TaskAttachmentRef });
16025
+ var TASK_ARTIFACT_MAX_BYTES = 10 * 1024 * 1024;
16026
+ var TaskArtifact = external_exports.object({
16027
+ id: TaskArtifactId,
16028
+ taskId: TaskId,
16029
+ name: external_exports.string().min(1).max(200).regex(/^[^/\\]+$/, "artifact name must be a filename").refine(isSafeSingleLineDisplayText, "invalid artifact name"),
16030
+ mediaType: external_exports.string().max(200).regex(/^[\w.+-]+\/[\w.+-]+$/, "invalid media type"),
16031
+ size: external_exports.number().int().min(1).max(TASK_ARTIFACT_MAX_BYTES),
16032
+ sha256: external_exports.string().regex(/^[a-f0-9]{64}$/),
16033
+ createdAt: IsoDate
16034
+ });
16035
+ var TaskFileCapability = external_exports.object({
16036
+ target: external_exports.enum(["zixt", "slack", "linear"]),
16037
+ operation: external_exports.enum(["download", "share", "issue_attachment"]),
16038
+ supported: external_exports.boolean(),
16039
+ available: external_exports.boolean(),
16040
+ maxBytes: external_exports.number().int().positive(),
16041
+ reason: external_exports.string().min(1).max(500).nullable(),
16042
+ remedy: external_exports.enum(["none", "connect", "reconnect", "grant_scope", "manual_link"])
16043
+ });
16044
+ var TaskFileCapabilities = external_exports.object({
16045
+ capabilities: external_exports.array(TaskFileCapability).length(3)
16046
+ });
16022
16047
  var TaskDisposition = external_exports.object({
16023
16048
  outcome: external_exports.enum(["done", "nothing_to_do", "escalated", "cancelled", "failed"]),
16024
16049
  summary: external_exports.string().max(5e4)
@@ -16451,6 +16476,7 @@ var TaskWorkingContextObservation = TaskWorkingContextBase.omit({
16451
16476
  var TaskDetailResponse = external_exports.object({
16452
16477
  task: TaskProjection,
16453
16478
  events: external_exports.array(TaskEventRecord),
16479
+ artifacts: external_exports.array(TaskArtifact),
16454
16480
  /** Newest assignment epoch first. */
16455
16481
  attempts: external_exports.array(TaskAttemptProjection),
16456
16482
  /** Only unresolved asks for this task; decisions still use the typed approval endpoint. */
@@ -16982,6 +17008,39 @@ var AgentOp = external_exports.union([
16982
17008
  }),
16983
17009
  /** The channels a teammate can actually post to: the ones the bot is in. */
16984
17010
  external_exports.object({ kind: external_exports.literal("comm.list_channels"), provider: external_exports.literal("slack") }),
17011
+ /** Snapshot a regular Task-workspace file into immutable tenant storage. */
17012
+ external_exports.object({
17013
+ kind: external_exports.literal("artifact.create"),
17014
+ name: TaskArtifact.shape.name,
17015
+ mediaType: external_exports.string().max(200).regex(/^[\w.+-]+\/[\w.+-]+$/),
17016
+ size: external_exports.number().int().min(1).max(TASK_ARTIFACT_MAX_BYTES),
17017
+ sha256: external_exports.string().regex(/^[a-f0-9]{64}$/),
17018
+ data: external_exports.string().min(1).max(Math.ceil(TASK_ARTIFACT_MAX_BYTES / 3 * 4) + 4)
17019
+ }),
17020
+ /** Truthful per-provider file delivery inventory for the current Task. */
17021
+ external_exports.object({ kind: external_exports.literal("artifact.capabilities") }),
17022
+ /** Read-only, provider-verified labels for the exact approval card. */
17023
+ external_exports.object({
17024
+ kind: external_exports.literal("artifact.delivery.preview"),
17025
+ target: external_exports.enum(["slack", "linear"]),
17026
+ artifactId: TaskArtifactId,
17027
+ destinationId: external_exports.string().min(1).max(200)
17028
+ }),
17029
+ /** Cloud Comms Gateway delivery using the vault-held Slack bot token. */
17030
+ external_exports.object({
17031
+ kind: external_exports.literal("artifact.deliver.slack"),
17032
+ artifactId: TaskArtifactId,
17033
+ to: external_exports.string().min(1).max(200),
17034
+ comment: external_exports.string().max(3e3).optional(),
17035
+ threadTs: external_exports.string().max(64).optional()
17036
+ }),
17037
+ /** Upload to Linear private storage and attach the asset to one issue. */
17038
+ external_exports.object({
17039
+ kind: external_exports.literal("artifact.deliver.linear"),
17040
+ artifactId: TaskArtifactId,
17041
+ issueId: external_exports.string().min(1).max(200),
17042
+ title: external_exports.string().min(1).max(1e3).optional()
17043
+ }),
16985
17044
  /** Claim a cloud-side intent before a direct host → Linear mutation. */
16986
17045
  ProviderIntent,
16987
17046
  /** Record provider-confirmed success after the direct mutation returns. */
@@ -19894,10 +19953,77 @@ async function discoverTools(params, fetchFn = fetch) {
19894
19953
  })).filter((t) => t.name.length > 0);
19895
19954
  }
19896
19955
 
19956
+ // src/runners/task-artifacts.ts
19957
+ import { createHash } from "node:crypto";
19958
+ import { lstat, readFile, realpath } from "node:fs/promises";
19959
+ import { basename, extname, isAbsolute, relative, resolve, sep } from "node:path";
19960
+ var MEDIA_TYPES = {
19961
+ ".csv": "text/csv",
19962
+ ".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
19963
+ ".gif": "image/gif",
19964
+ ".html": "text/html",
19965
+ ".jpeg": "image/jpeg",
19966
+ ".jpg": "image/jpeg",
19967
+ ".json": "application/json",
19968
+ ".md": "text/markdown",
19969
+ ".pdf": "application/pdf",
19970
+ ".png": "image/png",
19971
+ ".pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
19972
+ ".svg": "image/svg+xml",
19973
+ ".txt": "text/plain",
19974
+ ".webp": "image/webp",
19975
+ ".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
19976
+ ".xml": "application/xml",
19977
+ ".zip": "application/zip"
19978
+ };
19979
+ function artifactDataContainsSensitiveValue(data, sensitiveValues) {
19980
+ const decoded = Buffer.from(data, "base64").toString("utf8");
19981
+ return sensitiveValues.some((secret) => secret.length > 0 && decoded.includes(secret));
19982
+ }
19983
+ function isWithin(file2, root) {
19984
+ const child = relative(root, file2);
19985
+ return child === "" || !child.startsWith(`..${sep}`) && child !== ".." && !isAbsolute(child);
19986
+ }
19987
+ async function publishTaskFile(input) {
19988
+ const candidate = resolve(input.cwd, input.path);
19989
+ const [file2, roots] = await Promise.all([
19990
+ realpath(candidate),
19991
+ Promise.all(input.allowedRoots.map((root) => realpath(root)))
19992
+ ]);
19993
+ if (!roots.some((root) => isWithin(file2, root))) {
19994
+ return { ok: false, error: "the file is outside this task workspace" };
19995
+ }
19996
+ const stat3 = await lstat(file2);
19997
+ if (!stat3.isFile()) return { ok: false, error: "only regular files can be published" };
19998
+ if (stat3.size < 1) return { ok: false, error: "empty files cannot be published" };
19999
+ if (stat3.size > TASK_ARTIFACT_MAX_BYTES) {
20000
+ return {
20001
+ ok: false,
20002
+ error: `the file is larger than Zixt's ${TASK_ARTIFACT_MAX_BYTES / 1024 / 1024} MB limit`
20003
+ };
20004
+ }
20005
+ const name = basename(file2);
20006
+ if (name.length > 200) return { ok: false, error: "the filename is too long" };
20007
+ const inferred = MEDIA_TYPES[extname(name).toLowerCase()] ?? "application/octet-stream";
20008
+ const mediaType = input.mediaType?.trim() || inferred;
20009
+ if (!/^[\w.+-]+\/[\w.+-]+$/.test(mediaType) || mediaType.length > 200) {
20010
+ return { ok: false, error: "media_type must be a valid content type" };
20011
+ }
20012
+ const bytes = await readFile(file2);
20013
+ return input.agentOp({
20014
+ kind: "artifact.create",
20015
+ name,
20016
+ mediaType,
20017
+ size: bytes.length,
20018
+ sha256: createHash("sha256").update(bytes).digest("hex"),
20019
+ data: bytes.toString("base64")
20020
+ });
20021
+ }
20022
+
19897
20023
  // src/runners/exec.ts
19898
20024
  import { spawn } from "node:child_process";
19899
- import { realpath, stat } from "node:fs/promises";
19900
- import { delimiter, extname, isAbsolute, join, resolve } from "node:path";
20025
+ import { realpath as realpath2, stat } from "node:fs/promises";
20026
+ import { delimiter, extname as extname2, isAbsolute as isAbsolute2, join, resolve as resolve2 } from "node:path";
19901
20027
  function spawnCli(command, args, options = {}) {
19902
20028
  if (process.platform === "win32") {
19903
20029
  return spawn([quoteForCmd(command), ...args.map(quoteForCmd)].join(" "), {
@@ -19909,26 +20035,26 @@ function spawnCli(command, args, options = {}) {
19909
20035
  }
19910
20036
  async function resolveTrustedCliCommand(command, options = {}) {
19911
20037
  const platform = options.platform ?? process.platform;
19912
- const trustedCwd = resolve(options.trustedCwd ?? process.cwd());
20038
+ const trustedCwd = resolve2(options.trustedCwd ?? process.cwd());
19913
20039
  const hasSeparator = command.includes("/") || command.includes("\\");
19914
20040
  const bases = [];
19915
- if (isAbsolute(command)) {
20041
+ if (isAbsolute2(command)) {
19916
20042
  bases.push(command);
19917
20043
  } else if (hasSeparator) {
19918
- bases.push(resolve(trustedCwd, command));
20044
+ bases.push(resolve2(trustedCwd, command));
19919
20045
  } else {
19920
20046
  for (const entry of (options.searchPath ?? process.env.PATH ?? "").split(delimiter)) {
19921
20047
  if (!entry) continue;
19922
- bases.push(join(isAbsolute(entry) ? entry : resolve(trustedCwd, entry), command));
20048
+ bases.push(join(isAbsolute2(entry) ? entry : resolve2(trustedCwd, entry), command));
19923
20049
  }
19924
20050
  }
19925
- const extensions = platform === "win32" && extname(command) === "" ? (options.pathExt ?? process.env.PATHEXT ?? ".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean) : [""];
20051
+ const extensions = platform === "win32" && extname2(command) === "" ? (options.pathExt ?? process.env.PATHEXT ?? ".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean) : [""];
19926
20052
  for (const base of bases) {
19927
20053
  for (const extension of extensions) {
19928
20054
  try {
19929
- const candidate = await realpath(`${base}${extension}`);
20055
+ const candidate = await realpath2(`${base}${extension}`);
19930
20056
  const entry = await stat(candidate);
19931
- if (entry.isFile() && isAbsolute(candidate)) return candidate;
20057
+ if (entry.isFile() && isAbsolute2(candidate)) return candidate;
19932
20058
  } catch {
19933
20059
  }
19934
20060
  }
@@ -19961,7 +20087,7 @@ async function generateTaskTitle(instructions, runner) {
19961
20087
  instructions.slice(0, INSTRUCTIONS_BUDGET),
19962
20088
  "</task_request>"
19963
20089
  ].join("\n");
19964
- return new Promise((resolve15) => {
20090
+ return new Promise((resolve16) => {
19965
20091
  const child = spawnCli(
19966
20092
  command,
19967
20093
  [
@@ -19984,7 +20110,7 @@ async function generateTaskTitle(instructions, runner) {
19984
20110
  if (settled) return;
19985
20111
  settled = true;
19986
20112
  clearTimeout(timer);
19987
- resolve15(value);
20113
+ resolve16(value);
19988
20114
  };
19989
20115
  const timer = setTimeout(() => {
19990
20116
  child.kill();
@@ -20022,7 +20148,7 @@ function isPlausibleTaskTitle(title) {
20022
20148
  // src/worker-watchdog.ts
20023
20149
  import { randomUUID } from "node:crypto";
20024
20150
  import { writeFileSync as writeFileSync2 } from "node:fs";
20025
- import { isAbsolute as isAbsolute3 } from "node:path";
20151
+ import { isAbsolute as isAbsolute4 } from "node:path";
20026
20152
 
20027
20153
  // src/worker-ownership.ts
20028
20154
  import {
@@ -20035,8 +20161,8 @@ import {
20035
20161
  rmSync,
20036
20162
  writeFileSync
20037
20163
  } from "node:fs";
20038
- import { chmod, lstat, mkdir, open, readFile, readdir, rm, rmdir } from "node:fs/promises";
20039
- import { basename, dirname, isAbsolute as isAbsolute2, join as join2, relative, resolve as resolve2, sep } from "node:path";
20164
+ import { chmod, lstat as lstat2, mkdir, open, readFile as readFile2, readdir, rm, rmdir } from "node:fs/promises";
20165
+ import { basename as basename2, dirname, isAbsolute as isAbsolute3, join as join2, relative as relative2, resolve as resolve3, sep as sep2 } from "node:path";
20040
20166
  var LAUNCHER_OWNERSHIP_DIR_ENV = "ZIXT_HOST_LAUNCHER_OWNERSHIP_DIR";
20041
20167
  var WORKER_OWNERSHIP_FILE_ENV = "ZIXT_HOST_WORKER_OWNERSHIP_FILE";
20042
20168
  var SUPERVISOR_OWNERSHIP_FILE_ENV = "ZIXT_HOST_SUPERVISOR_OWNERSHIP_FILE";
@@ -20046,7 +20172,7 @@ var MAX_OWNERSHIP_RECORD_BYTES = 4 * 1024;
20046
20172
  var MAX_OWNERSHIP_RECORDS = 32;
20047
20173
  var MAX_OWNERSHIP_GENERATIONS = 32;
20048
20174
  function workerOwnershipFile(directory, nonce) {
20049
- if (!isAbsolute2(directory) || !SAFE_WORKER_OWNERSHIP_NONCE.test(nonce)) return null;
20175
+ if (!isAbsolute3(directory) || !SAFE_WORKER_OWNERSHIP_NONCE.test(nonce)) return null;
20050
20176
  return join2(directory, `${nonce}.json`);
20051
20177
  }
20052
20178
  function workerOwnershipArguments(nonce) {
@@ -20056,7 +20182,7 @@ function consumeWorkerOwnershipArguments(argv, env) {
20056
20182
  const file2 = env[WORKER_OWNERSHIP_FILE_ENV];
20057
20183
  const nonce = env.ZIXT_HOST_WORKER_WATCHDOG_NONCE;
20058
20184
  if (typeof file2 !== "string") return { argv: [...argv], requested: false, valid: true };
20059
- if (typeof nonce !== "string" || !SAFE_WORKER_OWNERSHIP_NONCE.test(nonce) || !isAbsolute2(file2) || basename(file2) !== `${nonce}.json`) {
20185
+ if (typeof nonce !== "string" || !SAFE_WORKER_OWNERSHIP_NONCE.test(nonce) || !isAbsolute3(file2) || basename2(file2) !== `${nonce}.json`) {
20060
20186
  return { argv: [...argv], requested: true, valid: false };
20061
20187
  }
20062
20188
  const result = [];
@@ -20083,7 +20209,7 @@ function syncDirectorySync(path) {
20083
20209
  }
20084
20210
  }
20085
20211
  function recordWorkerOwnership(path, nonce, pid = process.pid) {
20086
- if (!isAbsolute2(path) || !SAFE_WORKER_OWNERSHIP_NONCE.test(nonce) || basename(path) !== `${nonce}.json` || !Number.isSafeInteger(pid) || pid <= 1) {
20212
+ if (!isAbsolute3(path) || !SAFE_WORKER_OWNERSHIP_NONCE.test(nonce) || basename2(path) !== `${nonce}.json` || !Number.isSafeInteger(pid) || pid <= 1) {
20087
20213
  return false;
20088
20214
  }
20089
20215
  const directory = dirname(path);
@@ -20141,19 +20267,19 @@ async function syncDirectory(path) {
20141
20267
  }
20142
20268
  }
20143
20269
  async function ensurePrivateOwnershipRoot(root) {
20144
- if (!isAbsolute2(root)) throw new Error("launcher ownership root is invalid");
20270
+ if (!isAbsolute3(root)) throw new Error("launcher ownership root is invalid");
20145
20271
  const firstCreated = await mkdir(root, { recursive: true, mode: 448 });
20146
20272
  if (firstCreated && process.platform !== "win32") {
20147
- const first = resolve2(firstCreated);
20148
- const target = resolve2(root);
20273
+ const first = resolve3(firstCreated);
20274
+ const target = resolve3(root);
20149
20275
  await syncDirectory(dirname(first));
20150
20276
  let current = first;
20151
- for (const part of relative(first, target).split(sep).filter(Boolean)) {
20277
+ for (const part of relative2(first, target).split(sep2).filter(Boolean)) {
20152
20278
  await syncDirectory(current);
20153
20279
  current = join2(current, part);
20154
20280
  }
20155
20281
  }
20156
- const metadata = await lstat(root);
20282
+ const metadata = await lstat2(root);
20157
20283
  if (metadata.isSymbolicLink() || !metadata.isDirectory()) {
20158
20284
  throw new Error("launcher ownership root is not a trusted directory");
20159
20285
  }
@@ -20190,7 +20316,7 @@ async function readLauncherOwnershipGenerations(root) {
20190
20316
  throw new Error("launcher ownership root is malformed");
20191
20317
  }
20192
20318
  const directory = join2(root, entry.name);
20193
- const metadata = await lstat(directory);
20319
+ const metadata = await lstat2(directory);
20194
20320
  if (metadata.isSymbolicLink() || !metadata.isDirectory()) {
20195
20321
  throw new Error("launcher ownership generation is not a trusted directory");
20196
20322
  }
@@ -20212,7 +20338,7 @@ function parseRecord(value, path, expectedNonce) {
20212
20338
  return { schema: 1, nonce: expectedNonce, pid: record2.pid, path };
20213
20339
  }
20214
20340
  async function readWorkerOwnershipRecords(directory) {
20215
- if (!isAbsolute2(directory)) throw new Error("worker ownership directory is invalid");
20341
+ if (!isAbsolute3(directory)) throw new Error("worker ownership directory is invalid");
20216
20342
  const entries = await readdir(directory, { withFileTypes: true }).catch(
20217
20343
  (error52) => {
20218
20344
  if (error52.code === "ENOENT") return [];
@@ -20231,13 +20357,13 @@ async function readWorkerOwnershipRecords(directory) {
20231
20357
  }
20232
20358
  const match = /^([A-Za-z0-9_-]{16,200})\.json$/.exec(entry.name);
20233
20359
  if (!entry.isFile() || !match) throw new Error("worker ownership directory is malformed");
20234
- const metadata = await lstat(path);
20360
+ const metadata = await lstat2(path);
20235
20361
  if (!metadata.isFile() || metadata.size > MAX_OWNERSHIP_RECORD_BYTES) {
20236
20362
  throw new Error("worker ownership record is invalid");
20237
20363
  }
20238
20364
  let value;
20239
20365
  try {
20240
- value = JSON.parse(await readFile(path, "utf8"));
20366
+ value = JSON.parse(await readFile2(path, "utf8"));
20241
20367
  } catch {
20242
20368
  throw new Error("worker ownership record is invalid");
20243
20369
  }
@@ -20246,7 +20372,7 @@ async function readWorkerOwnershipRecords(directory) {
20246
20372
  return records;
20247
20373
  }
20248
20374
  async function forgetWorkerOwnership(path) {
20249
- if (!isAbsolute2(path)) throw new Error("worker ownership path is invalid");
20375
+ if (!isAbsolute3(path)) throw new Error("worker ownership path is invalid");
20250
20376
  const directory = dirname(path);
20251
20377
  await rm(path, { force: true });
20252
20378
  await syncDirectory(directory);
@@ -20306,11 +20432,11 @@ function createWorkerWatchdogSendDrain() {
20306
20432
  if (completed) return;
20307
20433
  completed = true;
20308
20434
  pending--;
20309
- if (pending === 0) drained.splice(0).forEach((resolve15) => resolve15());
20435
+ if (pending === 0) drained.splice(0).forEach((resolve16) => resolve16());
20310
20436
  };
20311
20437
  },
20312
20438
  drain: async () => {
20313
- if (pending > 0) await new Promise((resolve15) => drained.push(resolve15));
20439
+ if (pending > 0) await new Promise((resolve16) => drained.push(resolve16));
20314
20440
  }
20315
20441
  };
20316
20442
  }
@@ -20336,7 +20462,7 @@ function startWorkerWatchdogHeartbeat(env = process.env, argv = process.argv.sli
20336
20462
  }
20337
20463
  const heartbeatFile = env[WORKER_WATCHDOG_FILE_ENV];
20338
20464
  const ipc = typeof process.send === "function" && process.connected;
20339
- const file2 = !ipc && typeof heartbeatFile === "string" && isAbsolute3(heartbeatFile) ? heartbeatFile : null;
20465
+ const file2 = !ipc && typeof heartbeatFile === "string" && isAbsolute4(heartbeatFile) ? heartbeatFile : null;
20340
20466
  if (!ipc && !file2) {
20341
20467
  heartbeatActive = false;
20342
20468
  heartbeatUsesIpc = false;
@@ -20555,7 +20681,7 @@ async function waitForOperationGrantRetry(retryAt, signal) {
20555
20681
  const deadline = Date.parse(retryAt);
20556
20682
  if (!Number.isFinite(deadline) || signal.aborted) return false;
20557
20683
  if (deadline <= Date.now()) return true;
20558
- return await new Promise((resolve15) => {
20684
+ return await new Promise((resolve16) => {
20559
20685
  let settled = false;
20560
20686
  let timer;
20561
20687
  const finish = (ready) => {
@@ -20563,7 +20689,7 @@ async function waitForOperationGrantRetry(retryAt, signal) {
20563
20689
  settled = true;
20564
20690
  if (timer) clearTimeout(timer);
20565
20691
  signal.removeEventListener("abort", onAbort);
20566
- resolve15(ready);
20692
+ resolve16(ready);
20567
20693
  };
20568
20694
  const onAbort = () => finish(false);
20569
20695
  const schedule = () => {
@@ -20831,22 +20957,22 @@ var HostClient = class _HostClient {
20831
20957
  const unwindingAssignments = [...this.activeAssignments.values()];
20832
20958
  for (const cancel of this.cancels.values()) cancel(stopReason);
20833
20959
  for (const entry of this.secretGrants.values()) {
20834
- for (const resolve15 of entry.resolvers) resolve15({});
20960
+ for (const resolve16 of entry.resolvers) resolve16({});
20835
20961
  entry.resolvers = [];
20836
20962
  delete entry.value;
20837
20963
  }
20838
20964
  for (const entry of this.connectionGrants.values()) {
20839
- for (const resolve15 of entry.resolvers) resolve15([]);
20965
+ for (const resolve16 of entry.resolvers) resolve16([]);
20840
20966
  entry.resolvers = [];
20841
20967
  delete entry.value;
20842
20968
  }
20843
20969
  for (const entry of this.providerGrants.values()) {
20844
- for (const resolve15 of entry.resolvers) resolve15([]);
20970
+ for (const resolve16 of entry.resolvers) resolve16([]);
20845
20971
  entry.resolvers = [];
20846
20972
  delete entry.value;
20847
20973
  }
20848
20974
  for (const waiters of this.approvalWaiters.values()) {
20849
- for (const resolve15 of waiters.values()) resolve15({ approved: false, guidance: reason });
20975
+ for (const resolve16 of waiters.values()) resolve16({ approved: false, guidance: reason });
20850
20976
  }
20851
20977
  for (const waiters of this.agentOpWaiters.values()) {
20852
20978
  for (const waiter of waiters.values()) {
@@ -20872,9 +20998,9 @@ var HostClient = class _HostClient {
20872
20998
  let drainTimer;
20873
20999
  const drained = await Promise.race([
20874
21000
  Promise.allSettled(runs).then(() => true),
20875
- new Promise((resolve15) => {
21001
+ new Promise((resolve16) => {
20876
21002
  drainTimer = setTimeout(
20877
- () => resolve15(false),
21003
+ () => resolve16(false),
20878
21004
  this.opts.unwindTimeoutMs ?? _HostClient.DEFAULT_UNWIND_TIMEOUT_MS
20879
21005
  );
20880
21006
  drainTimer.unref?.();
@@ -21018,9 +21144,9 @@ var HostClient = class _HostClient {
21018
21144
  let frameDrainTimer;
21019
21145
  const framesDrained = await Promise.race([
21020
21146
  frameTail.then(() => true),
21021
- new Promise((resolve15) => {
21147
+ new Promise((resolve16) => {
21022
21148
  frameDrainTimer = setTimeout(
21023
- () => resolve15(false),
21149
+ () => resolve16(false),
21024
21150
  this.opts.unwindTimeoutMs ?? _HostClient.DEFAULT_UNWIND_TIMEOUT_MS
21025
21151
  );
21026
21152
  frameDrainTimer.unref?.();
@@ -21564,7 +21690,7 @@ var HostClient = class _HostClient {
21564
21690
  const entry = this.secretGrants.get(key) ?? { resolvers: [] };
21565
21691
  entry.value = message.secrets;
21566
21692
  entry.expiresAt = expiresAt;
21567
- for (const resolve15 of entry.resolvers) resolve15(message.secrets);
21693
+ for (const resolve16 of entry.resolvers) resolve16(message.secrets);
21568
21694
  entry.resolvers = [];
21569
21695
  this.secretGrants.set(key, entry);
21570
21696
  return;
@@ -21595,13 +21721,13 @@ var HostClient = class _HostClient {
21595
21721
  const entry = this.connectionGrants.get(key) ?? { resolvers: [] };
21596
21722
  entry.value = message.connections;
21597
21723
  entry.expiresAt = expiresAt;
21598
- for (const resolve15 of entry.resolvers) resolve15(message.connections);
21724
+ for (const resolve16 of entry.resolvers) resolve16(message.connections);
21599
21725
  entry.resolvers = [];
21600
21726
  this.connectionGrants.set(key, entry);
21601
21727
  const providerEntry = this.providerGrants.get(key) ?? { resolvers: [] };
21602
21728
  providerEntry.value = providers;
21603
21729
  providerEntry.expiresAt = authorityExpiresAt;
21604
- for (const resolve15 of providerEntry.resolvers) resolve15(providers);
21730
+ for (const resolve16 of providerEntry.resolvers) resolve16(providers);
21605
21731
  providerEntry.resolvers = [];
21606
21732
  this.providerGrants.set(key, providerEntry);
21607
21733
  return;
@@ -21735,8 +21861,8 @@ var HostClient = class _HostClient {
21735
21861
  return redactCredentialText(text, sensitiveSnapshot()).slice(0, maxLength);
21736
21862
  };
21737
21863
  let resolveCancelled;
21738
- const cancelledPromise = new Promise((resolve15) => {
21739
- resolveCancelled = resolve15;
21864
+ const cancelledPromise = new Promise((resolve16) => {
21865
+ resolveCancelled = resolve16;
21740
21866
  });
21741
21867
  const endAuthority = (reason = "cloud_cancel") => {
21742
21868
  if (stopReason) return;
@@ -21745,21 +21871,21 @@ var HostClient = class _HostClient {
21745
21871
  authorityController.abort(reason);
21746
21872
  const secretEntry = this.secretGrants.get(cancelKey);
21747
21873
  if (secretEntry) {
21748
- for (const resolve15 of secretEntry.resolvers) resolve15({});
21874
+ for (const resolve16 of secretEntry.resolvers) resolve16({});
21749
21875
  secretEntry.resolvers = [];
21750
21876
  delete secretEntry.value;
21751
21877
  }
21752
21878
  this.secretGrants.delete(cancelKey);
21753
21879
  const connectionEntry = this.connectionGrants.get(cancelKey);
21754
21880
  if (connectionEntry) {
21755
- for (const resolve15 of connectionEntry.resolvers) resolve15([]);
21881
+ for (const resolve16 of connectionEntry.resolvers) resolve16([]);
21756
21882
  connectionEntry.resolvers = [];
21757
21883
  delete connectionEntry.value;
21758
21884
  }
21759
21885
  this.connectionGrants.delete(cancelKey);
21760
21886
  const providerEntry = this.providerGrants.get(cancelKey);
21761
21887
  if (providerEntry) {
21762
- for (const resolve15 of providerEntry.resolvers) resolve15([]);
21888
+ for (const resolve16 of providerEntry.resolvers) resolve16([]);
21763
21889
  providerEntry.resolvers = [];
21764
21890
  delete providerEntry.value;
21765
21891
  }
@@ -21767,8 +21893,8 @@ var HostClient = class _HostClient {
21767
21893
  this.clearAuthorityExpiry(cancelKey);
21768
21894
  const approvalWaiters = this.approvalWaiters.get(cancelKey);
21769
21895
  if (approvalWaiters) {
21770
- for (const resolve15 of approvalWaiters.values()) {
21771
- resolve15({ approved: false, guidance: "task was cancelled" });
21896
+ for (const resolve16 of approvalWaiters.values()) {
21897
+ resolve16({ approved: false, guidance: "task was cancelled" });
21772
21898
  }
21773
21899
  approvalWaiters.clear();
21774
21900
  }
@@ -21894,9 +22020,9 @@ var HostClient = class _HostClient {
21894
22020
  return value;
21895
22021
  };
21896
22022
  if (entry.value) return Promise.resolve(capture(entry.value));
21897
- return new Promise((resolve15) => {
21898
- entry.resolvers.push((value) => resolve15(capture(value)));
21899
- setTimeout(() => resolve15(capture(entry.value ?? {})), _HostClient.SECRETS_WAIT_MS);
22023
+ return new Promise((resolve16) => {
22024
+ entry.resolvers.push((value) => resolve16(capture(value)));
22025
+ setTimeout(() => resolve16(capture(entry.value ?? {})), _HostClient.SECRETS_WAIT_MS);
21900
22026
  });
21901
22027
  };
21902
22028
  const connections = () => {
@@ -21913,9 +22039,9 @@ var HostClient = class _HostClient {
21913
22039
  return value;
21914
22040
  };
21915
22041
  if (entry.value) return Promise.resolve(capture(entry.value));
21916
- return new Promise((resolve15) => {
21917
- entry.resolvers.push((value) => resolve15(capture(value)));
21918
- setTimeout(() => resolve15(capture(entry.value ?? [])), _HostClient.SECRETS_WAIT_MS);
22042
+ return new Promise((resolve16) => {
22043
+ entry.resolvers.push((value) => resolve16(capture(value)));
22044
+ setTimeout(() => resolve16(capture(entry.value ?? [])), _HostClient.SECRETS_WAIT_MS);
21919
22045
  });
21920
22046
  };
21921
22047
  const providers = () => {
@@ -21932,9 +22058,9 @@ var HostClient = class _HostClient {
21932
22058
  return value;
21933
22059
  };
21934
22060
  if (entry.value !== void 0) return Promise.resolve(capture(entry.value));
21935
- return new Promise((resolve15) => {
21936
- entry.resolvers.push((value) => resolve15(capture(value)));
21937
- setTimeout(() => resolve15(capture(entry.value ?? [])), _HostClient.SECRETS_WAIT_MS);
22061
+ return new Promise((resolve16) => {
22062
+ entry.resolvers.push((value) => resolve16(capture(value)));
22063
+ setTimeout(() => resolve16(capture(entry.value ?? [])), _HostClient.SECRETS_WAIT_MS);
21938
22064
  });
21939
22065
  };
21940
22066
  const linear = async () => {
@@ -21960,13 +22086,13 @@ var HostClient = class _HostClient {
21960
22086
  payload: safe(payload, 5e4),
21961
22087
  ...questionChoices ? { questionChoices: [...questionChoices] } : {}
21962
22088
  });
21963
- return new Promise((resolve15) => {
22089
+ return new Promise((resolve16) => {
21964
22090
  const waiters = this.approvalWaiters.get(cancelKey) ?? /* @__PURE__ */ new Map();
21965
22091
  this.approvalWaiters.set(cancelKey, waiters);
21966
- waiters.set(requestId, resolve15);
22092
+ waiters.set(requestId, resolve16);
21967
22093
  void cancelledPromise.then(() => {
21968
22094
  if (waiters.delete(requestId)) {
21969
- resolve15({ approved: false, guidance: "task was cancelled" });
22095
+ resolve16({ approved: false, guidance: "task was cancelled" });
21970
22096
  }
21971
22097
  });
21972
22098
  });
@@ -21977,6 +22103,14 @@ var HostClient = class _HostClient {
21977
22103
  const detail = parsed.error.issues.map((i) => `${i.path.join(".") || "op"}: ${i.message}`).join("; ");
21978
22104
  return Promise.resolve({ ok: false, error: `invalid arguments: ${detail}` });
21979
22105
  }
22106
+ if (parsed.data.kind === "artifact.create") {
22107
+ if (artifactDataContainsSensitiveValue(parsed.data.data, sensitiveSnapshot())) {
22108
+ return Promise.resolve({
22109
+ ok: false,
22110
+ error: "the file contains a task credential and cannot be published"
22111
+ });
22112
+ }
22113
+ }
21980
22114
  if (requestId.length < 1 || requestId.length > 200) {
21981
22115
  return Promise.resolve({ ok: false, error: "invalid provider settlement request id" });
21982
22116
  }
@@ -22004,11 +22138,11 @@ var HostClient = class _HostClient {
22004
22138
  if (existing) message = existing;
22005
22139
  else terminalMessages.set(requestId, message);
22006
22140
  }
22007
- return new Promise((resolve15) => {
22141
+ return new Promise((resolve16) => {
22008
22142
  const waiters = this.agentOpWaiters.get(cancelKey) ?? /* @__PURE__ */ new Map();
22009
22143
  this.agentOpWaiters.set(cancelKey, waiters);
22010
22144
  if (waiters.has(requestId)) {
22011
- resolve15({ ok: false, error: "provider settlement request is already in flight" });
22145
+ resolve16({ ok: false, error: "provider settlement request is already in flight" });
22012
22146
  return;
22013
22147
  }
22014
22148
  const timer = setTimeout(() => {
@@ -22019,7 +22153,7 @@ var HostClient = class _HostClient {
22019
22153
  (pending) => !(pending.type === "agent.op" && pending.requestId === requestId)
22020
22154
  );
22021
22155
  }
22022
- resolve15({
22156
+ resolve16({
22023
22157
  ok: false,
22024
22158
  error: terminal ? "The provider call completed, but Zixt could not record its outcome. Do not retry; wait for reconciliation." : "the platform did not answer in time; verify with a list_* tool before retrying a mutating call"
22025
22159
  });
@@ -22027,7 +22161,7 @@ var HostClient = class _HostClient {
22027
22161
  }, _HostClient.AGENT_OP_TIMEOUT_MS);
22028
22162
  timer.unref?.();
22029
22163
  waiters.set(requestId, {
22030
- resolve: resolve15,
22164
+ resolve: resolve16,
22031
22165
  timer,
22032
22166
  ...terminal ? { terminalMessage: message } : {}
22033
22167
  });
@@ -22073,12 +22207,12 @@ var HostClient = class _HostClient {
22073
22207
  "No GitHub change was attempted; the authority grant request was invalid."
22074
22208
  );
22075
22209
  }
22076
- const outcome = await new Promise((resolve15) => {
22210
+ const outcome = await new Promise((resolve16) => {
22077
22211
  const timer = setTimeout(() => {
22078
22212
  const waiter = this.operationGrantWaiters.get(requestId);
22079
22213
  if (!waiter) return;
22080
22214
  this.operationGrantWaiters.delete(requestId);
22081
- resolve15({ grant: null, retryable: true, reason: "no_reply_from_zixt" });
22215
+ resolve16({ grant: null, retryable: true, reason: "no_reply_from_zixt" });
22082
22216
  }, this.operationGrantTimeoutMs);
22083
22217
  timer.unref?.();
22084
22218
  this.operationGrantWaiters.set(requestId, {
@@ -22091,9 +22225,9 @@ var HostClient = class _HostClient {
22091
22225
  timer,
22092
22226
  accept: (grant) => {
22093
22227
  addSensitiveValues(providerGrantSensitiveValues(grant));
22094
- resolve15({ grant });
22228
+ resolve16({ grant });
22095
22229
  },
22096
- deny: (retryable, reason, detail, retryAt, retryCode) => resolve15({
22230
+ deny: (retryable, reason, detail, retryAt, retryCode) => resolve16({
22097
22231
  grant: null,
22098
22232
  retryable,
22099
22233
  reason,
@@ -22107,7 +22241,7 @@ var HostClient = class _HostClient {
22107
22241
  } catch {
22108
22242
  clearTimeout(timer);
22109
22243
  this.operationGrantWaiters.delete(requestId);
22110
- resolve15({ grant: null, retryable: false, reason: "connection_unavailable" });
22244
+ resolve16({ grant: null, retryable: false, reason: "connection_unavailable" });
22111
22245
  }
22112
22246
  });
22113
22247
  if (outcome.grant) {
@@ -22163,7 +22297,7 @@ var HostClient = class _HostClient {
22163
22297
  )
22164
22298
  );
22165
22299
  }
22166
- return new Promise((resolve15, reject3) => {
22300
+ return new Promise((resolve16, reject3) => {
22167
22301
  const timer = setTimeout(() => {
22168
22302
  if (this.browserCredentialWaiters.delete(requestId)) {
22169
22303
  reject3(
@@ -22182,7 +22316,7 @@ var HostClient = class _HostClient {
22182
22316
  timer,
22183
22317
  accept: (credential) => {
22184
22318
  addSensitiveValues(webLoginSensitiveValues(credential));
22185
- resolve15(credential);
22319
+ resolve16(credential);
22186
22320
  },
22187
22321
  deny: (reason) => reject3(new Error(reason))
22188
22322
  });
@@ -22470,8 +22604,8 @@ function watchForUpdates(options) {
22470
22604
 
22471
22605
  // src/runners/process-tree.ts
22472
22606
  import { spawn as spawn2 } from "node:child_process";
22473
- import { readFile as readFile2 } from "node:fs/promises";
22474
- import { isAbsolute as isAbsolute4, join as join4 } from "node:path";
22607
+ import { readFile as readFile3 } from "node:fs/promises";
22608
+ import { isAbsolute as isAbsolute5, join as join4 } from "node:path";
22475
22609
  var windowsProcessTreeModule = process.platform === "win32" ? import("@vscode/windows-process-tree").catch(() => null) : null;
22476
22610
  var PROCESS_TERM_GRACE_MS = 500;
22477
22611
  var PROCESS_EXIT_POLL_MS = 20;
@@ -22503,14 +22637,14 @@ async function observeWindowsGuardianNonce(pid, nonce) {
22503
22637
  "Windows runner identity could not be observed"
22504
22638
  );
22505
22639
  }
22506
- return new Promise((resolve15, reject3) => {
22640
+ return new Promise((resolve16, reject3) => {
22507
22641
  let done = false;
22508
22642
  const finish = (result) => {
22509
22643
  if (done) return;
22510
22644
  done = true;
22511
22645
  clearTimeout(timeout);
22512
22646
  if (result instanceof Error) reject3(result);
22513
- else resolve15(result);
22647
+ else resolve16(result);
22514
22648
  };
22515
22649
  const timeout = setTimeout(
22516
22650
  () => finish(
@@ -22544,7 +22678,7 @@ async function observeWindowsGuardianNonce(pid, nonce) {
22544
22678
  async function observePosixGuardianNonce(pid, nonce) {
22545
22679
  if (process.platform === "linux") {
22546
22680
  try {
22547
- const command = await readFile2(`/proc/${pid}/cmdline`);
22681
+ const command = await readFile3(`/proc/${pid}/cmdline`);
22548
22682
  const args = command.toString("utf8").split("\0");
22549
22683
  return args.includes(nonce) ? "match" : "mismatch";
22550
22684
  } catch (error52) {
@@ -22555,7 +22689,7 @@ async function observePosixGuardianNonce(pid, nonce) {
22555
22689
  );
22556
22690
  }
22557
22691
  }
22558
- return new Promise((resolve15, reject3) => {
22692
+ return new Promise((resolve16, reject3) => {
22559
22693
  const observer = spawn2("/bin/ps", ["-ww", "-o", "command=", "-p", String(pid)], {
22560
22694
  stdio: ["ignore", "pipe", "ignore"]
22561
22695
  });
@@ -22566,7 +22700,7 @@ async function observePosixGuardianNonce(pid, nonce) {
22566
22700
  done = true;
22567
22701
  clearTimeout(timeout);
22568
22702
  if (result instanceof Error) reject3(result);
22569
- else resolve15(result);
22703
+ else resolve16(result);
22570
22704
  };
22571
22705
  const timeout = setTimeout(() => {
22572
22706
  observer.kill("SIGKILL");
@@ -22613,7 +22747,7 @@ async function observeGuardianIdentity(pid, identity) {
22613
22747
  return process.platform === "win32" ? observeWindowsGuardianNonce(pid, identity.nonce) : observePosixGuardianNonce(pid, identity.nonce);
22614
22748
  }
22615
22749
  function delay(ms) {
22616
- return new Promise((resolve15) => setTimeout(resolve15, ms));
22750
+ return new Promise((resolve16) => setTimeout(resolve16, ms));
22617
22751
  }
22618
22752
  function posixProcessRecordsFromPs(output) {
22619
22753
  const records = [];
@@ -22646,7 +22780,7 @@ function posixProcessRecordsFromPs(output) {
22646
22780
  return records;
22647
22781
  }
22648
22782
  async function snapshotPosixProcesses() {
22649
- return new Promise((resolve15, reject3) => {
22783
+ return new Promise((resolve16, reject3) => {
22650
22784
  const observer = spawn2("/bin/ps", ["-axo", "uid=,pid=,ppid=,pgid=,stat="], {
22651
22785
  stdio: ["ignore", "pipe", "ignore"]
22652
22786
  });
@@ -22659,7 +22793,7 @@ async function snapshotPosixProcesses() {
22659
22793
  if (error52) reject3(error52);
22660
22794
  else {
22661
22795
  try {
22662
- resolve15(posixProcessRecordsFromPs(output));
22796
+ resolve16(posixProcessRecordsFromPs(output));
22663
22797
  } catch (caught) {
22664
22798
  reject3(caught);
22665
22799
  }
@@ -22927,7 +23061,7 @@ async function observePosixGroupIdentity(records, pgid, identity) {
22927
23061
  }
22928
23062
  function defaultTaskkillCommand() {
22929
23063
  const windowsRoot = process.env.SystemRoot ?? process.env.WINDIR;
22930
- if (!windowsRoot || !isAbsolute4(windowsRoot)) {
23064
+ if (!windowsRoot || !isAbsolute5(windowsRoot)) {
22931
23065
  throw new ProcessTreeTerminationError(
22932
23066
  "termination_failed",
22933
23067
  "Windows runner tree termination authority is unavailable"
@@ -22994,7 +23128,7 @@ async function snapshotWindowsDescendants(rootPid) {
22994
23128
  "Windows process-tree observation could not start"
22995
23129
  );
22996
23130
  }
22997
- return new Promise((resolve15, reject3) => {
23131
+ return new Promise((resolve16, reject3) => {
22998
23132
  let done = false;
22999
23133
  const timeout = setTimeout(() => {
23000
23134
  if (done) return;
@@ -23021,7 +23155,7 @@ async function snapshotWindowsDescendants(rootPid) {
23021
23155
  return;
23022
23156
  }
23023
23157
  try {
23024
- resolve15(completeWindowsDescendantPids(rootPid, processes));
23158
+ resolve16(completeWindowsDescendantPids(rootPid, processes));
23025
23159
  } catch (caught) {
23026
23160
  reject3(caught);
23027
23161
  }
@@ -23068,7 +23202,7 @@ async function waitForProcessesExit(pids, timeoutMs) {
23068
23202
  }
23069
23203
  async function runTaskkill(pid, command, timeoutMs = TASKKILL_TIMEOUT_MS, independentlyTrackedPids = []) {
23070
23204
  const trustedCommand = command ?? defaultTaskkillCommand();
23071
- const result = await new Promise((resolve15, reject3) => {
23205
+ const result = await new Promise((resolve16, reject3) => {
23072
23206
  const killer = spawn2(trustedCommand, ["/PID", String(pid), "/T", "/F"], {
23073
23207
  stdio: ["ignore", "pipe", "pipe"],
23074
23208
  windowsHide: true
@@ -23103,7 +23237,7 @@ async function runTaskkill(pid, command, timeoutMs = TASKKILL_TIMEOUT_MS, indepe
23103
23237
  done = true;
23104
23238
  clearTimeout(timeout);
23105
23239
  if (error52) reject3(error52);
23106
- else resolve15({ code: killer.exitCode, output, outputTruncated });
23240
+ else resolve16({ code: killer.exitCode, output, outputTruncated });
23107
23241
  };
23108
23242
  killer.once(
23109
23243
  "error",
@@ -23315,7 +23449,7 @@ async function terminateProcessTree(child, childExited, options = {}) {
23315
23449
  }
23316
23450
 
23317
23451
  // src/release-state.ts
23318
- import { lstat as lstat2, mkdir as mkdir2, open as open2, readFile as readFile3, rename, rm as rm2 } from "node:fs/promises";
23452
+ import { lstat as lstat3, mkdir as mkdir2, open as open2, readFile as readFile4, rename, rm as rm2 } from "node:fs/promises";
23319
23453
  import { dirname as dirname2, join as join5 } from "node:path";
23320
23454
  var STATE_FILE = "release-state.json";
23321
23455
  var STATE_SCHEMA = 1;
@@ -23355,7 +23489,7 @@ function createReleaseStateStore(root) {
23355
23489
  const path = releaseStatePath(root);
23356
23490
  return {
23357
23491
  async load() {
23358
- const metadata = await lstat2(path).catch((error52) => {
23492
+ const metadata = await lstat3(path).catch((error52) => {
23359
23493
  if (error52.code === "ENOENT") return null;
23360
23494
  throw error52;
23361
23495
  });
@@ -23365,7 +23499,7 @@ function createReleaseStateStore(root) {
23365
23499
  }
23366
23500
  let value;
23367
23501
  try {
23368
- value = JSON.parse(await readFile3(path, "utf8"));
23502
+ value = JSON.parse(await readFile4(path, "utf8"));
23369
23503
  } catch {
23370
23504
  throw new Error("Host release state cannot be read");
23371
23505
  }
@@ -23390,7 +23524,7 @@ function createReleaseStateStore(root) {
23390
23524
  }
23391
23525
  },
23392
23526
  async clear() {
23393
- const present = await lstat2(path).then(
23527
+ const present = await lstat3(path).then(
23394
23528
  () => true,
23395
23529
  (error52) => {
23396
23530
  if (error52.code === "ENOENT") return false;
@@ -23407,7 +23541,7 @@ function createReleaseStateStore(root) {
23407
23541
  // src/windows-job.ts
23408
23542
  import { spawn as spawn3 } from "node:child_process";
23409
23543
  import { randomUUID as randomUUID2 } from "node:crypto";
23410
- import { isAbsolute as isAbsolute5, win32 } from "node:path";
23544
+ import { isAbsolute as isAbsolute6, win32 } from "node:path";
23411
23545
  var WINDOWS_CONTAINMENT_GATE_ENV = "ZIXT_WINDOWS_CONTAINMENT_GATE";
23412
23546
  var WINDOWS_CONTAINMENT_GATE_PREFIX = "__ZIXT_WINDOWS_CONTAINMENT_READY__";
23413
23547
  var WINDOWS_POST_CONTAINMENT_CWD_ENV = "ZIXT_WINDOWS_POST_CONTAINMENT_CWD";
@@ -23780,12 +23914,12 @@ async function createWindowsJobContainment(pid, options) {
23780
23914
  stderr = `${stderr}${String(chunk)}`.slice(-HELPER_OUTPUT_LIMIT);
23781
23915
  });
23782
23916
  const helperEvents = helper;
23783
- const exited = new Promise((resolve15) => {
23917
+ const exited = new Promise((resolve16) => {
23784
23918
  let completed = false;
23785
23919
  const complete = (code, signal) => {
23786
23920
  if (completed) return;
23787
23921
  completed = true;
23788
- resolve15({ code, signal });
23922
+ resolve16({ code, signal });
23789
23923
  };
23790
23924
  helperEvents.once("error", () => {
23791
23925
  failProtocol(new Error("Windows Job Object helper could not start"));
@@ -23798,7 +23932,7 @@ async function createWindowsJobContainment(pid, options) {
23798
23932
  });
23799
23933
  const nextLine = async (expected) => {
23800
23934
  if (protocolFailure) throw protocolFailure;
23801
- const line = lines.shift() ?? await new Promise((resolve15, reject3) => {
23935
+ const line = lines.shift() ?? await new Promise((resolve16, reject3) => {
23802
23936
  const timer = setTimeout(
23803
23937
  () => reject3(timeoutError("Windows Job Object helper did not answer in time")),
23804
23938
  timeoutMs
@@ -23806,7 +23940,7 @@ async function createWindowsJobContainment(pid, options) {
23806
23940
  timer.unref?.();
23807
23941
  lineWaiters.push((value) => {
23808
23942
  clearTimeout(timer);
23809
- resolve15(value);
23943
+ resolve16(value);
23810
23944
  });
23811
23945
  });
23812
23946
  if (protocolFailure) throw protocolFailure;
@@ -23819,8 +23953,8 @@ async function createWindowsJobContainment(pid, options) {
23819
23953
  }
23820
23954
  const stopped = await Promise.race([
23821
23955
  exited.then(() => true),
23822
- new Promise((resolve15) => {
23823
- const timer = setTimeout(() => resolve15(false), timeoutMs);
23956
+ new Promise((resolve16) => {
23957
+ const timer = setTimeout(() => resolve16(false), timeoutMs);
23824
23958
  timer.unref?.();
23825
23959
  })
23826
23960
  ]);
@@ -23879,7 +24013,7 @@ async function awaitWindowsContainmentGate(env = process.env, input = process.st
23879
24013
  if (nonce === void 0) return true;
23880
24014
  if (!SAFE_NONCE2.test(nonce)) return false;
23881
24015
  const expected = windowsContainmentGate(nonce).trimEnd();
23882
- return new Promise((resolve15) => {
24016
+ return new Promise((resolve16) => {
23883
24017
  let pending = Buffer.alloc(0);
23884
24018
  let settled = false;
23885
24019
  const finish = (result) => {
@@ -23890,7 +24024,7 @@ async function awaitWindowsContainmentGate(env = process.env, input = process.st
23890
24024
  input.off("end", onEnd);
23891
24025
  input.off("error", onEnd);
23892
24026
  if (result) input.pause();
23893
- resolve15(result);
24027
+ resolve16(result);
23894
24028
  };
23895
24029
  const onData = (chunk) => {
23896
24030
  pending = Buffer.concat([pending, chunk]);
@@ -23903,7 +24037,7 @@ async function awaitWindowsContainmentGate(env = process.env, input = process.st
23903
24037
  const postContainmentCwd = env[WINDOWS_POST_CONTAINMENT_CWD_ENV];
23904
24038
  delete env[WINDOWS_POST_CONTAINMENT_CWD_ENV];
23905
24039
  if (postContainmentCwd !== void 0) {
23906
- if (!isAbsolute5(postContainmentCwd)) return finish(false);
24040
+ if (!isAbsolute6(postContainmentCwd)) return finish(false);
23907
24041
  try {
23908
24042
  process.chdir(postContainmentCwd);
23909
24043
  } catch {
@@ -23979,8 +24113,8 @@ function releaseManifestAtPrefix(prefix) {
23979
24113
  async function validReleaseAtPrefix(prefix, version2) {
23980
24114
  try {
23981
24115
  const [entry, manifestText] = await Promise.all([
23982
- lstat3(releaseEntryAtPrefix(prefix)),
23983
- readFile4(releaseManifestAtPrefix(prefix), "utf8")
24116
+ lstat4(releaseEntryAtPrefix(prefix)),
24117
+ readFile5(releaseManifestAtPrefix(prefix), "utf8")
23984
24118
  ]);
23985
24119
  if (!entry.isFile()) return false;
23986
24120
  const manifest = JSON.parse(manifestText);
@@ -23999,14 +24133,14 @@ async function syncDirectory3(path) {
23999
24133
  }
24000
24134
  }
24001
24135
  function installedReleaseVersion(entry, root = versionsRoot()) {
24002
- if (!isAbsolute6(entry)) return null;
24003
- const relativeEntry = relative2(resolve3(root), resolve3(entry));
24004
- if (!relativeEntry || relativeEntry.startsWith(`..${sep2}`) || isAbsolute6(relativeEntry)) {
24136
+ if (!isAbsolute7(entry)) return null;
24137
+ const relativeEntry = relative3(resolve4(root), resolve4(entry));
24138
+ if (!relativeEntry || relativeEntry.startsWith(`..${sep3}`) || isAbsolute7(relativeEntry)) {
24005
24139
  return null;
24006
24140
  }
24007
- const version2 = relativeEntry.split(sep2)[0];
24141
+ const version2 = relativeEntry.split(sep3)[0];
24008
24142
  if (!version2 || !VERSION_DIR.test(version2)) return null;
24009
- return resolve3(entry) === resolve3(installedReleaseEntry(version2, root)) ? version2 : null;
24143
+ return resolve4(entry) === resolve4(installedReleaseEntry(version2, root)) ? version2 : null;
24010
24144
  }
24011
24145
  function currentReleaseEntry(root = versionsRoot(), platform = process.platform) {
24012
24146
  return join6(root, platform === "win32" ? "current-launcher.cjs" : CURRENT_RELEASE_ENTRY);
@@ -24071,7 +24205,7 @@ async function activateInstalledRelease(entry, root = versionsRoot(), platform =
24071
24205
  if (platform === "win32") {
24072
24206
  await mkdir3(root, { recursive: true, mode: 448 });
24073
24207
  const launcher = currentReleaseEntry(root, platform);
24074
- const existingLauncher = await lstat3(launcher).catch((error52) => {
24208
+ const existingLauncher = await lstat4(launcher).catch((error52) => {
24075
24209
  if (error52.code === "ENOENT") return null;
24076
24210
  throw error52;
24077
24211
  });
@@ -24079,7 +24213,7 @@ async function activateInstalledRelease(entry, root = versionsRoot(), platform =
24079
24213
  if (!existingLauncher.isFile()) {
24080
24214
  throw new Error("the Zixt Host Windows launcher is not a regular file");
24081
24215
  }
24082
- const contents = await readFile4(launcher, "utf8");
24216
+ const contents = await readFile5(launcher, "utf8");
24083
24217
  if (!contents.startsWith(WINDOWS_LAUNCHER_OWNED_MARKER)) {
24084
24218
  throw new Error("the Zixt Host Windows launcher is not owned by Zixt");
24085
24219
  }
@@ -24090,7 +24224,7 @@ async function activateInstalledRelease(entry, root = versionsRoot(), platform =
24090
24224
  await replaceDurableFile(launcher, WINDOWS_STABLE_LAUNCHER, sync);
24091
24225
  }
24092
24226
  const pointerPath = windowsReleasePointer(root);
24093
- const existingPointer = await lstat3(pointerPath).catch((error52) => {
24227
+ const existingPointer = await lstat4(pointerPath).catch((error52) => {
24094
24228
  if (error52.code === "ENOENT") return null;
24095
24229
  throw error52;
24096
24230
  });
@@ -24100,7 +24234,7 @@ async function activateInstalledRelease(entry, root = versionsRoot(), platform =
24100
24234
  }
24101
24235
  let prior;
24102
24236
  try {
24103
- prior = JSON.parse(await readFile4(pointerPath, "utf8"));
24237
+ prior = JSON.parse(await readFile5(pointerPath, "utf8"));
24104
24238
  } catch {
24105
24239
  throw new Error("the Zixt Host Windows release pointer is invalid");
24106
24240
  }
@@ -24111,7 +24245,7 @@ async function activateInstalledRelease(entry, root = versionsRoot(), platform =
24111
24245
  }
24112
24246
  await replaceDurableFile(
24113
24247
  pointerPath,
24114
- `${JSON.stringify({ schema: 1, entry: resolve3(entry) })}
24248
+ `${JSON.stringify({ schema: 1, entry: resolve4(entry) })}
24115
24249
  `,
24116
24250
  sync
24117
24251
  );
@@ -24120,7 +24254,7 @@ async function activateInstalledRelease(entry, root = versionsRoot(), platform =
24120
24254
  if (platform !== "linux" && platform !== "darwin") return entry;
24121
24255
  await mkdir3(root, { recursive: true, mode: 448 });
24122
24256
  const current = currentReleaseEntry(root, platform);
24123
- const existing = await lstat3(current).catch((error52) => {
24257
+ const existing = await lstat4(current).catch((error52) => {
24124
24258
  if (error52.code === "ENOENT") return null;
24125
24259
  throw error52;
24126
24260
  });
@@ -24142,9 +24276,9 @@ async function activatedReleaseVersion(root = versionsRoot(), platform = process
24142
24276
  if (platform === "win32") {
24143
24277
  try {
24144
24278
  const pointerPath = windowsReleasePointer(root);
24145
- const metadata = await lstat3(pointerPath);
24279
+ const metadata = await lstat4(pointerPath);
24146
24280
  if (!metadata.isFile() || metadata.size > 4 * 1024) return null;
24147
- const value = JSON.parse(await readFile4(pointerPath, "utf8"));
24281
+ const value = JSON.parse(await readFile5(pointerPath, "utf8"));
24148
24282
  return value.schema === 1 && typeof value.entry === "string" ? installedReleaseVersion(value.entry, root) : null;
24149
24283
  } catch {
24150
24284
  return null;
@@ -24154,7 +24288,7 @@ async function activatedReleaseVersion(root = versionsRoot(), platform = process
24154
24288
  try {
24155
24289
  const current = currentReleaseEntry(root, platform);
24156
24290
  const target = await readlink(current);
24157
- return installedReleaseVersion(resolve3(dirname3(current), target), root);
24291
+ return installedReleaseVersion(resolve4(dirname3(current), target), root);
24158
24292
  } catch {
24159
24293
  return null;
24160
24294
  }
@@ -24315,7 +24449,7 @@ async function installRelease(version2, options = {}) {
24315
24449
  installerContainmentSetupError = error52;
24316
24450
  return null;
24317
24451
  }) : Promise.resolve(null);
24318
- const installed = await new Promise((resolve15, reject3) => {
24452
+ const installed = await new Promise((resolve16, reject3) => {
24319
24453
  let finished = false;
24320
24454
  let cleanupStarted = false;
24321
24455
  let exitObserved = false;
@@ -24331,7 +24465,7 @@ async function installRelease(version2, options = {}) {
24331
24465
  finished = true;
24332
24466
  clearTimeout(timer);
24333
24467
  options.signal?.removeEventListener("abort", requestCleanup);
24334
- resolve15(result);
24468
+ resolve16(result);
24335
24469
  };
24336
24470
  const requestCleanup = () => {
24337
24471
  if (cleanupStarted || finished) return;
@@ -24428,7 +24562,7 @@ async function installRelease(version2, options = {}) {
24428
24562
  return null;
24429
24563
  }
24430
24564
  if (await validReleaseAtPrefix(prefix, version2)) return entry;
24431
- const existing = await lstat3(prefix).catch((error52) => {
24565
+ const existing = await lstat4(prefix).catch((error52) => {
24432
24566
  if (error52.code === "ENOENT") return null;
24433
24567
  throw error52;
24434
24568
  });
@@ -24447,7 +24581,7 @@ async function installRelease(version2, options = {}) {
24447
24581
  }
24448
24582
  async function pruneInstalledVersions(keep, root = versionsRoot()) {
24449
24583
  const protectedDirs = new Set(keep);
24450
- const running = process.argv[1] ? resolve3(process.argv[1]) : null;
24584
+ const running = process.argv[1] ? resolve4(process.argv[1]) : null;
24451
24585
  let entries;
24452
24586
  try {
24453
24587
  entries = await readdir2(root);
@@ -24458,7 +24592,7 @@ async function pruneInstalledVersions(keep, root = versionsRoot()) {
24458
24592
  for (const name of entries) {
24459
24593
  if (protectedDirs.has(name) || !VERSION_DIR.test(name)) continue;
24460
24594
  const dir = join6(root, name);
24461
- if (running && running.startsWith(`${dir}${sep2}`)) continue;
24595
+ if (running && running.startsWith(`${dir}${sep3}`)) continue;
24462
24596
  try {
24463
24597
  await rm3(dir, { recursive: true, force: true });
24464
24598
  removed.push(name);
@@ -24619,7 +24753,7 @@ async function runWorkerCompatibilityProxy(env = process.env, argv = process.arg
24619
24753
  const ownership = consumeWorkerOwnershipArguments(argv, env);
24620
24754
  const nonce = env[WORKER_WATCHDOG_NONCE_ENV];
24621
24755
  const ownershipFile = env[WORKER_OWNERSHIP_FILE_ENV];
24622
- if (typeof target !== "string" || !isAbsolute6(target) || typeof nonce !== "string" || typeof ownershipFile !== "string" || !ownership.requested || !ownership.valid) {
24756
+ if (typeof target !== "string" || !isAbsolute7(target) || typeof nonce !== "string" || typeof ownershipFile !== "string" || !ownership.requested || !ownership.valid) {
24623
24757
  return 1;
24624
24758
  }
24625
24759
  if (!recordWorkerOwnership(ownershipFile, nonce)) return 1;
@@ -24644,11 +24778,11 @@ async function runWorkerCompatibilityProxy(env = process.env, argv = process.arg
24644
24778
  child.stdin?.on("error", () => {
24645
24779
  });
24646
24780
  process.stdin.pipe(child.stdin);
24647
- return new Promise((resolve15) => {
24648
- child.once("error", () => resolve15(1));
24781
+ return new Promise((resolve16) => {
24782
+ child.once("error", () => resolve16(1));
24649
24783
  child.once("exit", (code) => {
24650
24784
  process.stdin.unpipe(child.stdin);
24651
- resolve15(code ?? 1);
24785
+ resolve16(code ?? 1);
24652
24786
  });
24653
24787
  });
24654
24788
  }
@@ -24686,7 +24820,7 @@ async function launchHostSupervisor(options = {}) {
24686
24820
  delete env[WORKER_WATCHDOG_FILE_ENV];
24687
24821
  delete env[WORKER_OWNERSHIP_FILE_ENV];
24688
24822
  delete env[SUPERVISOR_OWNERSHIP_FILE_ENV];
24689
- const generationNonce = ownershipDirectory ? basename2(ownershipDirectory) : null;
24823
+ const generationNonce = ownershipDirectory ? basename3(ownershipDirectory) : null;
24690
24824
  if (ownershipDirectory && generationNonce) {
24691
24825
  env[LAUNCHER_OWNERSHIP_DIR_ENV] = ownershipDirectory;
24692
24826
  env[SUPERVISOR_OWNERSHIP_FILE_ENV] = join6(ownershipDirectory, `${generationNonce}.json`);
@@ -24726,11 +24860,11 @@ async function launchHostSupervisor(options = {}) {
24726
24860
  const waitOrStop = async (ms) => {
24727
24861
  if (stopping) return false;
24728
24862
  if (!customDelay) {
24729
- await new Promise((resolve15) => {
24863
+ await new Promise((resolve16) => {
24730
24864
  const finish = () => {
24731
24865
  clearTimeout(timer);
24732
24866
  stopController.signal.removeEventListener("abort", finish);
24733
- resolve15();
24867
+ resolve16();
24734
24868
  };
24735
24869
  const timer = setTimeout(finish, ms);
24736
24870
  stopController.signal.addEventListener("abort", finish, { once: true });
@@ -24738,8 +24872,8 @@ async function launchHostSupervisor(options = {}) {
24738
24872
  return !stopping;
24739
24873
  }
24740
24874
  let finishStop;
24741
- const stopped = new Promise((resolve15) => {
24742
- finishStop = () => resolve15();
24875
+ const stopped = new Promise((resolve16) => {
24876
+ finishStop = () => resolve16();
24743
24877
  stopController.signal.addEventListener("abort", finishStop, { once: true });
24744
24878
  });
24745
24879
  await Promise.race([customDelay(ms), stopped]);
@@ -24764,7 +24898,7 @@ async function launchHostSupervisor(options = {}) {
24764
24898
  return false;
24765
24899
  };
24766
24900
  const cleanupOwnershipGeneration = async (directory) => {
24767
- const generationNonce = basename2(directory);
24901
+ const generationNonce = basename3(directory);
24768
24902
  const firstRecords = await readWorkerOwnershipRecords(directory);
24769
24903
  const supervisorRecord = firstRecords.find((record2) => record2.nonce === generationNonce);
24770
24904
  if (firstRecords.length > 0 && !supervisorRecord) {
@@ -24862,19 +24996,19 @@ async function launchHostSupervisor(options = {}) {
24862
24996
  child = spawnSupervisor(entry, version2, ownershipDirectory, containmentGateNonce);
24863
24997
  const launchedSupervisor = child;
24864
24998
  let resolveChildExited;
24865
- const childExited = new Promise((resolve15) => {
24866
- resolveChildExited = resolve15;
24999
+ const childExited = new Promise((resolve16) => {
25000
+ resolveChildExited = resolve16;
24867
25001
  });
24868
25002
  const supervisorContainmentAbort = new AbortController();
24869
25003
  void childExited.then(() => supervisorContainmentAbort.abort());
24870
25004
  const outcomePromise = new Promise(
24871
- (resolve15) => {
25005
+ (resolve16) => {
24872
25006
  let observed = false;
24873
25007
  const finish = (code, signal) => {
24874
25008
  if (observed) return;
24875
25009
  observed = true;
24876
25010
  resolveChildExited();
24877
- resolve15({ code, signal });
25011
+ resolve16({ code, signal });
24878
25012
  };
24879
25013
  child.once("error", () => finish(1, null));
24880
25014
  child.once("exit", finish);
@@ -24883,7 +25017,7 @@ async function launchHostSupervisor(options = {}) {
24883
25017
  let supervisorContainment = null;
24884
25018
  try {
24885
25019
  if (containmentGateNonce) {
24886
- const supervisorIdentity = ownershipDirectory ? basename2(ownershipDirectory) : null;
25020
+ const supervisorIdentity = ownershipDirectory ? basename3(ownershipDirectory) : null;
24887
25021
  if (!supervisorIdentity) {
24888
25022
  throw new Error("supervisor containment identity is unavailable");
24889
25023
  }
@@ -24895,12 +25029,12 @@ async function launchHostSupervisor(options = {}) {
24895
25029
  if (!supervisorContainment || !launchedSupervisor.stdin) {
24896
25030
  throw new Error("supervisor Job Object gate is unavailable");
24897
25031
  }
24898
- await new Promise((resolve15, reject3) => {
25032
+ await new Promise((resolve16, reject3) => {
24899
25033
  launchedSupervisor.stdin.write(
24900
25034
  windowsContainmentGate(containmentGateNonce),
24901
25035
  (error52) => {
24902
25036
  if (error52) reject3(error52);
24903
- else resolve15();
25037
+ else resolve16();
24904
25038
  }
24905
25039
  );
24906
25040
  });
@@ -24972,9 +25106,9 @@ async function superviseHost(options = {}) {
24972
25106
  const log2 = options.log ?? ((message) => console.error(message));
24973
25107
  const signalWorker = options.signalWorker ?? signalWorkerGroup;
24974
25108
  const inheritedOwnershipDirectory = process.env[LAUNCHER_OWNERSHIP_DIR_ENV];
24975
- const launcherOwnershipDirectory = productionLifecycle && typeof inheritedOwnershipDirectory === "string" && isAbsolute6(inheritedOwnershipDirectory) ? inheritedOwnershipDirectory : null;
25109
+ const launcherOwnershipDirectory = productionLifecycle && typeof inheritedOwnershipDirectory === "string" && isAbsolute7(inheritedOwnershipDirectory) ? inheritedOwnershipDirectory : null;
24976
25110
  if (productionLifecycle && isSupervisorRole() && launcherOwnershipDirectory) {
24977
- const generationNonce = basename2(launcherOwnershipDirectory);
25111
+ const generationNonce = basename3(launcherOwnershipDirectory);
24978
25112
  const expectedOwnershipFile = join6(launcherOwnershipDirectory, `${generationNonce}.json`);
24979
25113
  const configuredOwnershipFile = process.env[SUPERVISOR_OWNERSHIP_FILE_ENV];
24980
25114
  if (process.argv0 !== generationNonce || configuredOwnershipFile !== expectedOwnershipFile || !recordWorkerOwnership(expectedOwnershipFile, generationNonce)) {
@@ -25042,18 +25176,18 @@ async function superviseHost(options = {}) {
25042
25176
  }
25043
25177
  }
25044
25178
  let announceShutdown;
25045
- const shutdownAnnounced = new Promise((resolve15) => {
25046
- announceShutdown = resolve15;
25179
+ const shutdownAnnounced = new Promise((resolve16) => {
25180
+ announceShutdown = resolve16;
25047
25181
  });
25048
25182
  const attempted = /* @__PURE__ */ new Set();
25049
25183
  const waitOrShutdown = async (ms) => {
25050
25184
  if (shuttingDown2) return false;
25051
25185
  if (!customDelay) {
25052
- await new Promise((resolve15) => {
25186
+ await new Promise((resolve16) => {
25053
25187
  const finish = () => {
25054
25188
  clearTimeout(timer);
25055
25189
  shutdownController.signal.removeEventListener("abort", finish);
25056
- resolve15();
25190
+ resolve16();
25057
25191
  };
25058
25192
  const timer = setTimeout(finish, ms);
25059
25193
  shutdownController.signal.addEventListener("abort", finish, { once: true });
@@ -25196,19 +25330,19 @@ async function superviseHost(options = {}) {
25196
25330
  child = spawnWorker(command, watchdogLaunch, compatibilityOwnership, containmentGateNonce);
25197
25331
  const watchedChild = child;
25198
25332
  let resolveChildExited;
25199
- const childExited = new Promise((resolve15) => {
25200
- resolveChildExited = resolve15;
25333
+ const childExited = new Promise((resolve16) => {
25334
+ resolveChildExited = resolve16;
25201
25335
  });
25202
25336
  const workerContainmentAbort = new AbortController();
25203
25337
  void childExited.then(() => workerContainmentAbort.abort());
25204
25338
  const outcomePromise = new Promise(
25205
- (resolve15) => {
25339
+ (resolve16) => {
25206
25340
  let observed = false;
25207
25341
  const finish = (result) => {
25208
25342
  if (observed) return;
25209
25343
  observed = true;
25210
25344
  resolveChildExited();
25211
- resolve15(result);
25345
+ resolve16(result);
25212
25346
  };
25213
25347
  watchedChild.once("error", () => finish({ code: 1, signal: null }));
25214
25348
  watchedChild.once(
@@ -25230,10 +25364,10 @@ async function superviseHost(options = {}) {
25230
25364
  if (!workerContainment || !watchedChild.stdin) {
25231
25365
  throw new Error("worker Job Object gate is unavailable");
25232
25366
  }
25233
- await new Promise((resolve15, reject3) => {
25367
+ await new Promise((resolve16, reject3) => {
25234
25368
  watchedChild.stdin.write(windowsContainmentGate(containmentGateNonce), (error52) => {
25235
25369
  if (error52) reject3(error52);
25236
- else resolve15();
25370
+ else resolve16();
25237
25371
  });
25238
25372
  });
25239
25373
  }
@@ -25686,9 +25820,9 @@ function createDemoBrowserAdapterFactory() {
25686
25820
  }
25687
25821
 
25688
25822
  // src/browser/manager.ts
25689
- import { lstat as lstat4, mkdir as mkdir4, open as open4, opendir, readFile as readFile5, rename as rename3, rm as rm4 } from "node:fs/promises";
25823
+ import { lstat as lstat5, mkdir as mkdir4, open as open4, opendir, readFile as readFile6, rename as rename3, rm as rm4 } from "node:fs/promises";
25690
25824
  import { homedir as homedir2 } from "node:os";
25691
- import { dirname as dirname4, join as join7, resolve as resolve4 } from "node:path";
25825
+ import { dirname as dirname4, join as join7, resolve as resolve5 } from "node:path";
25692
25826
  var SAFE_SEGMENT = /^[A-Za-z0-9_-]{1,200}$/;
25693
25827
  var FRAME_MIN_INTERVAL_MS = 100;
25694
25828
  var IDLE_TIMEOUT_MS = 15 * 6e4;
@@ -25786,8 +25920,8 @@ var BrowserManager = class {
25786
25920
  }
25787
25921
  }
25788
25922
  exactChild(root, child) {
25789
- const canonicalRoot = resolve4(root);
25790
- const target = resolve4(canonicalRoot, child);
25923
+ const canonicalRoot = resolve5(root);
25924
+ const target = resolve5(canonicalRoot, child);
25791
25925
  if (dirname4(target) !== canonicalRoot) {
25792
25926
  throw new Error("browser profile path escaped its owned root");
25793
25927
  }
@@ -25795,7 +25929,7 @@ var BrowserManager = class {
25795
25929
  }
25796
25930
  async ensureOwnedDirectory(path) {
25797
25931
  await mkdir4(path, { recursive: true, mode: 448 });
25798
- const stat3 = await lstat4(path);
25932
+ const stat3 = await lstat5(path);
25799
25933
  if (!stat3.isDirectory() || stat3.isSymbolicLink()) {
25800
25934
  throw new Error("browser profile root must be an owned directory, not a symbolic link");
25801
25935
  }
@@ -25830,7 +25964,7 @@ var BrowserManager = class {
25830
25964
  }
25831
25965
  async readProfileState(agentId) {
25832
25966
  try {
25833
- const raw = JSON.parse(await readFile5(this.statePath(agentId), "utf8"));
25967
+ const raw = JSON.parse(await readFile6(this.statePath(agentId), "utf8"));
25834
25968
  if (typeof raw !== "object" || raw === null || !Number.isInteger(raw.revision) || Number(raw.revision) < 0 || !["allowed", "purged"].includes(String(raw.state))) {
25835
25969
  throw new Error("browser profile lifecycle marker is invalid");
25836
25970
  }
@@ -25929,7 +26063,7 @@ var BrowserManager = class {
25929
26063
  await this.ensureOwnedDirectory(this.profileRoot);
25930
26064
  const profileDir = this.profilePath(agentId);
25931
26065
  try {
25932
- const existingProfile = await lstat4(profileDir);
26066
+ const existingProfile = await lstat5(profileDir);
25933
26067
  if (existingProfile.isSymbolicLink() || !existingProfile.isDirectory()) {
25934
26068
  throw new Error("browser profile path is not an owned directory");
25935
26069
  }
@@ -26696,9 +26830,9 @@ function createPlaywrightBrowserAdapterFactory(dependencies = {}) {
26696
26830
  // src/runners/cli-runner.ts
26697
26831
  import { spawn as spawn8 } from "node:child_process";
26698
26832
  import { randomUUID as randomUUID10 } from "node:crypto";
26699
- import { lstat as lstat10, mkdir as mkdir10, realpath as realpath7 } from "node:fs/promises";
26833
+ import { lstat as lstat11, mkdir as mkdir10, realpath as realpath8 } from "node:fs/promises";
26700
26834
  import { homedir as homedir4 } from "node:os";
26701
- import { dirname as dirname7, isAbsolute as isAbsolute13, join as join14, resolve as resolve8 } from "node:path";
26835
+ import { dirname as dirname7, isAbsolute as isAbsolute14, join as join14, resolve as resolve9 } from "node:path";
26702
26836
 
26703
26837
  // src/tool-packs/browser/tool-definitions.ts
26704
26838
  function definition(name, description, properties, required2 = []) {
@@ -26953,7 +27087,7 @@ function createBrowserToolPack(deps) {
26953
27087
  }
26954
27088
 
26955
27089
  // src/tool-packs/provider-intents.ts
26956
- import { createHash, randomUUID as randomUUID3 } from "node:crypto";
27090
+ import { createHash as createHash2, randomUUID as randomUUID3 } from "node:crypto";
26957
27091
 
26958
27092
  // src/tool-packs/github/rest-transport.ts
26959
27093
  var MAX_RESPONSE_BYTES = 2 * 1024 * 1024;
@@ -27199,7 +27333,7 @@ function canonicalJson(value) {
27199
27333
  return `{${Object.entries(value).sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0).map(([key, child]) => `${JSON.stringify(key)}:${canonicalJson(child)}`).join(",")}}`;
27200
27334
  }
27201
27335
  function payloadFingerprint(value) {
27202
- return createHash("sha256").update(canonicalJson(value)).digest("hex");
27336
+ return createHash2("sha256").update(canonicalJson(value)).digest("hex");
27203
27337
  }
27204
27338
  function claimResult(result) {
27205
27339
  if (!result.ok || !result.result || typeof result.result !== "object") return null;
@@ -29391,14 +29525,14 @@ function createGithubPushOrchestrator(input) {
29391
29525
  // src/tool-packs/github/git-bridge.ts
29392
29526
  import { spawn as spawn5 } from "node:child_process";
29393
29527
  import { randomUUID as randomUUID7 } from "node:crypto";
29394
- import { chmod as chmod3, lstat as lstat6, mkdir as mkdir5, realpath as realpath3, rm as rm5 } from "node:fs/promises";
29395
- import { dirname as dirname5, isAbsolute as isAbsolute8, join as join9, relative as relative4 } from "node:path";
29528
+ import { chmod as chmod3, lstat as lstat7, mkdir as mkdir5, realpath as realpath4, rm as rm5 } from "node:fs/promises";
29529
+ import { dirname as dirname5, isAbsolute as isAbsolute9, join as join9, relative as relative5 } from "node:path";
29396
29530
 
29397
29531
  // src/tool-packs/github/git-credential-broker.ts
29398
29532
  import { createServer } from "node:http";
29399
29533
  import { randomBytes, randomUUID as randomUUID6, timingSafeEqual } from "node:crypto";
29400
- import { chmod as chmod2, lstat as lstat5, realpath as realpath2, writeFile } from "node:fs/promises";
29401
- import { isAbsolute as isAbsolute7, join as join8, relative as relative3 } from "node:path";
29534
+ import { chmod as chmod2, lstat as lstat6, realpath as realpath3, writeFile } from "node:fs/promises";
29535
+ import { isAbsolute as isAbsolute8, join as join8, relative as relative4 } from "node:path";
29402
29536
  var MAX_REQUEST_BYTES = 16 * 1024;
29403
29537
  var FILE_MODE = 384;
29404
29538
  var HELPER_SOURCE = String.raw`'use strict';
@@ -29511,8 +29645,8 @@ async function readBoundedBody2(request) {
29511
29645
  return Buffer.concat(chunks, size);
29512
29646
  }
29513
29647
  function assertChildPath(parent, child) {
29514
- const path = relative3(parent, child);
29515
- if (!path || path === ".." || path.startsWith("../") || path.startsWith("..\\") || isAbsolute7(path)) {
29648
+ const path = relative4(parent, child);
29649
+ if (!path || path === ".." || path.startsWith("../") || path.startsWith("..\\") || isAbsolute8(path)) {
29516
29650
  throw new Error("Git credential helper path escaped its private run directory");
29517
29651
  }
29518
29652
  }
@@ -29522,11 +29656,11 @@ async function createGithubGitCredentialBroker(input) {
29522
29656
  throw new Error("GitHub credential authority has expired");
29523
29657
  }
29524
29658
  assertRepositoryFullName(input.repositoryFullName);
29525
- const rootEntry = await lstat5(input.runArtifactsRoot);
29659
+ const rootEntry = await lstat6(input.runArtifactsRoot);
29526
29660
  if (!rootEntry.isDirectory() || rootEntry.isSymbolicLink()) {
29527
29661
  throw new Error("Git credential broker requires a private real run directory");
29528
29662
  }
29529
- const runRoot = await realpath2(input.runArtifactsRoot);
29663
+ const runRoot = await realpath3(input.runArtifactsRoot);
29530
29664
  const helperPath = join8(runRoot, `git-credential-${randomUUID6()}.cjs`);
29531
29665
  assertChildPath(runRoot, helperPath);
29532
29666
  await writeFile(helperPath, HELPER_SOURCE, { flag: "wx", mode: FILE_MODE });
@@ -29626,26 +29760,26 @@ ${stderr}`;
29626
29760
  return explicitGithubRefusal ? "provider_rejected" : "command_failed";
29627
29761
  }
29628
29762
  function assertBelow(parent, child, label) {
29629
- const path = relative4(parent, child);
29630
- if (!path || path === ".." || path.startsWith("../") || path.startsWith("..\\") || isAbsolute8(path)) {
29763
+ const path = relative5(parent, child);
29764
+ if (!path || path === ".." || path.startsWith("../") || path.startsWith("..\\") || isAbsolute9(path)) {
29631
29765
  throw new GithubGitProcessError("invalid_input");
29632
29766
  }
29633
29767
  void label;
29634
29768
  }
29635
29769
  async function requireRealDirectory(path, label) {
29636
- const entry = await lstat6(path).catch(() => null);
29770
+ const entry = await lstat7(path).catch(() => null);
29637
29771
  if (!entry || !entry.isDirectory() || entry.isSymbolicLink()) {
29638
29772
  void label;
29639
29773
  throw new GithubGitProcessError("invalid_input");
29640
29774
  }
29641
- return realpath3(path);
29775
+ return realpath4(path);
29642
29776
  }
29643
29777
  async function validateTokenlessPaths(command) {
29644
29778
  if (command.kind === "clone-from-bridge") {
29645
- if (!isAbsolute8(command.destination)) throw new GithubGitProcessError("invalid_input");
29779
+ if (!isAbsolute9(command.destination)) throw new GithubGitProcessError("invalid_input");
29646
29780
  const parent = await requireRealDirectory(dirname5(command.destination), "clone parent");
29647
29781
  assertBelow(parent, command.destination, "clone destination");
29648
- const destination = await lstat6(command.destination).catch((error52) => {
29782
+ const destination = await lstat7(command.destination).catch((error52) => {
29649
29783
  if (error52.code === "ENOENT") return null;
29650
29784
  throw error52;
29651
29785
  });
@@ -29653,7 +29787,7 @@ async function validateTokenlessPaths(command) {
29653
29787
  return;
29654
29788
  }
29655
29789
  if ("repositoryPath" in command) {
29656
- if (!isAbsolute8(command.repositoryPath)) throw new GithubGitProcessError("invalid_input");
29790
+ if (!isAbsolute9(command.repositoryPath)) throw new GithubGitProcessError("invalid_input");
29657
29791
  const repositoryPath5 = await requireRealDirectory(command.repositoryPath, "repository path");
29658
29792
  if (repositoryPath5 !== command.repositoryPath) throw new GithubGitProcessError("invalid_input");
29659
29793
  }
@@ -29733,7 +29867,7 @@ async function runGit(input, args, env) {
29733
29867
  if (input.authoritySignal.aborted || input.cancelledNow()) {
29734
29868
  throw new GithubGitProcessError("cancelled");
29735
29869
  }
29736
- if (!isAbsolute8(input.executablePath)) throw new GithubGitProcessError("invalid_input");
29870
+ if (!isAbsolute9(input.executablePath)) throw new GithubGitProcessError("invalid_input");
29737
29871
  const timeoutMs = input.timeoutMs ?? DEFAULT_TIMEOUT_MS2;
29738
29872
  if (!Number.isInteger(timeoutMs) || timeoutMs < 1 || timeoutMs > DEFAULT_TIMEOUT_MS2) {
29739
29873
  throw new GithubGitProcessError("invalid_input");
@@ -29753,8 +29887,8 @@ async function runGit(input, args, env) {
29753
29887
  let settled = false;
29754
29888
  let stopping = false;
29755
29889
  let resolveExited;
29756
- const exited = new Promise((resolve15) => {
29757
- resolveExited = resolve15;
29890
+ const exited = new Promise((resolve16) => {
29891
+ resolveExited = resolve16;
29758
29892
  });
29759
29893
  child.once("exit", resolveExited);
29760
29894
  const cleanup = () => {
@@ -29839,7 +29973,7 @@ function tokenlessArgs(command) {
29839
29973
  switch (command.kind) {
29840
29974
  case "clone-from-bridge":
29841
29975
  assertRef(command.branch);
29842
- if (!isAbsolute8(command.destination)) throw new GithubGitProcessError("invalid_input");
29976
+ if (!isAbsolute9(command.destination)) throw new GithubGitProcessError("invalid_input");
29843
29977
  return [
29844
29978
  "clone",
29845
29979
  "--no-recurse-submodules",
@@ -29851,7 +29985,7 @@ function tokenlessArgs(command) {
29851
29985
  ];
29852
29986
  case "fetch-from-bridge":
29853
29987
  assertFetchRefspecs(command.refspecs);
29854
- if (!isAbsolute8(command.repositoryPath)) throw new GithubGitProcessError("invalid_input");
29988
+ if (!isAbsolute9(command.repositoryPath)) throw new GithubGitProcessError("invalid_input");
29855
29989
  return [
29856
29990
  "-C",
29857
29991
  command.repositoryPath,
@@ -29863,7 +29997,7 @@ function tokenlessArgs(command) {
29863
29997
  ...command.refspecs
29864
29998
  ];
29865
29999
  case "copy-commit-to-bridge":
29866
- if (!isAbsolute8(command.repositoryPath) || !SHA.test(command.sha)) {
30000
+ if (!isAbsolute9(command.repositoryPath) || !SHA.test(command.sha)) {
29867
30001
  throw new GithubGitProcessError("invalid_input");
29868
30002
  }
29869
30003
  return [
@@ -29875,11 +30009,11 @@ function tokenlessArgs(command) {
29875
30009
  `${command.sha}:refs/zixt/push-source`
29876
30010
  ];
29877
30011
  case "rev-parse":
29878
- if (!isAbsolute8(command.repositoryPath)) throw new GithubGitProcessError("invalid_input");
30012
+ if (!isAbsolute9(command.repositoryPath)) throw new GithubGitProcessError("invalid_input");
29879
30013
  assertRef(command.ref);
29880
30014
  return ["-C", command.repositoryPath, "rev-parse", "--verify", `${command.ref}^{commit}`];
29881
30015
  case "remote-configure":
29882
- if (!isAbsolute8(command.repositoryPath) || !REPOSITORY.test(command.repositoryFullName)) {
30016
+ if (!isAbsolute9(command.repositoryPath) || !REPOSITORY.test(command.repositoryFullName)) {
29883
30017
  throw new GithubGitProcessError("invalid_input");
29884
30018
  }
29885
30019
  return [
@@ -29891,7 +30025,7 @@ function tokenlessArgs(command) {
29891
30025
  `https://github.com/${command.repositoryFullName}.git`
29892
30026
  ];
29893
30027
  case "status":
29894
- if (!isAbsolute8(command.repositoryPath)) throw new GithubGitProcessError("invalid_input");
30028
+ if (!isAbsolute9(command.repositoryPath)) throw new GithubGitProcessError("invalid_input");
29895
30029
  return [
29896
30030
  "-C",
29897
30031
  command.repositoryPath,
@@ -29921,7 +30055,7 @@ function createGithubGitBridge(input) {
29921
30055
  })();
29922
30056
  const requireBridge = async (value) => {
29923
30057
  const current = await roots();
29924
- if (!isAbsolute8(value) || !active.has(value)) throw new GithubGitProcessError("invalid_input");
30058
+ if (!isAbsolute9(value) || !active.has(value)) throw new GithubGitProcessError("invalid_input");
29925
30059
  const real = await requireRealDirectory(value, "git bridge");
29926
30060
  assertBelow(current.bridges, real, "git bridge");
29927
30061
  if (real !== value) throw new GithubGitProcessError("invalid_input");
@@ -30401,8 +30535,8 @@ function createRepositoryTools(runtime) {
30401
30535
 
30402
30536
  // src/tool-packs/github/workspace.ts
30403
30537
  import { randomUUID as randomUUID8 } from "node:crypto";
30404
- import { chmod as chmod4, lstat as lstat7, mkdir as mkdir6, readFile as readFile6, realpath as realpath4, rename as rename4, rm as rm6, writeFile as writeFile2 } from "node:fs/promises";
30405
- import { isAbsolute as isAbsolute9, join as join10, relative as relative5, resolve as resolve5 } from "node:path";
30538
+ import { chmod as chmod4, lstat as lstat8, mkdir as mkdir6, readFile as readFile7, realpath as realpath5, rename as rename4, rm as rm6, writeFile as writeFile2 } from "node:fs/promises";
30539
+ import { isAbsolute as isAbsolute10, join as join10, relative as relative6, resolve as resolve6 } from "node:path";
30406
30540
  var SAFE_LOCAL_ID = /^[A-Za-z0-9_-]{1,200}$/;
30407
30541
  var FULL_NAME2 = /^[A-Za-z0-9_.-]{1,100}\/[A-Za-z0-9_.-]{1,100}$/;
30408
30542
  var DIRECTORY_MODE2 = 448;
@@ -30419,20 +30553,20 @@ function hasControlCharacter2(value) {
30419
30553
  });
30420
30554
  }
30421
30555
  function assertBelow2(parent, child, label) {
30422
- const path = relative5(parent, child);
30423
- if (!path || path === ".." || path.startsWith("../") || path.startsWith("..\\") || isAbsolute9(path)) {
30556
+ const path = relative6(parent, child);
30557
+ if (!path || path === ".." || path.startsWith("../") || path.startsWith("..\\") || isAbsolute10(path)) {
30424
30558
  throw new Error(`${label} escaped the task workspace`);
30425
30559
  }
30426
30560
  }
30427
30561
  function samePath(left, right) {
30428
- return process.platform === "win32" ? resolve5(left).toLowerCase() === resolve5(right).toLowerCase() : resolve5(left) === resolve5(right);
30562
+ return process.platform === "win32" ? resolve6(left).toLowerCase() === resolve6(right).toLowerCase() : resolve6(left) === resolve6(right);
30429
30563
  }
30430
30564
  async function requireRealDirectory2(path, label) {
30431
- const entry = await lstat7(path).catch(() => null);
30565
+ const entry = await lstat8(path).catch(() => null);
30432
30566
  if (!entry || !entry.isDirectory() || entry.isSymbolicLink()) {
30433
30567
  throw new Error(`${label} must be a real directory, not a symbolic link or junction`);
30434
30568
  }
30435
- const real = await realpath4(path);
30569
+ const real = await realpath5(path);
30436
30570
  if (!samePath(real, path)) {
30437
30571
  throw new Error(`${label} must not traverse a symbolic link or junction`);
30438
30572
  }
@@ -30465,7 +30599,7 @@ function parseMetadata(text) {
30465
30599
  }
30466
30600
  async function pathExists(path) {
30467
30601
  try {
30468
- await lstat7(path);
30602
+ await lstat8(path);
30469
30603
  return true;
30470
30604
  } catch (error52) {
30471
30605
  if (error52.code === "ENOENT") return false;
@@ -30527,11 +30661,11 @@ async function createGithubWorkspaceService(input) {
30527
30661
  if (!await pathExists(destination) || !await pathExists(metadataPath)) {
30528
30662
  throw new Error("GitHub repository workspace has not been prepared");
30529
30663
  }
30530
- const metadataEntry = await lstat7(metadataPath);
30664
+ const metadataEntry = await lstat8(metadataPath);
30531
30665
  if (!metadataEntry.isFile() || metadataEntry.isSymbolicLink()) {
30532
30666
  throw new Error("GitHub workspace metadata is invalid");
30533
30667
  }
30534
- const metadata = parseMetadata(await readFile6(metadataPath, "utf8"));
30668
+ const metadata = parseMetadata(await readFile7(metadataPath, "utf8"));
30535
30669
  if (metadata.repositoryId !== parsed.data || metadata.fullName !== repository.fullName || !samePath(metadata.path, destination)) {
30536
30670
  throw new Error("GitHub workspace metadata does not match this repository");
30537
30671
  }
@@ -30629,11 +30763,11 @@ async function createGithubWorkspaceService(input) {
30629
30763
  expiresAt: authority.expiresAt
30630
30764
  });
30631
30765
  }
30632
- const metadataEntry = await lstat7(metadataPath);
30766
+ const metadataEntry = await lstat8(metadataPath);
30633
30767
  if (!metadataEntry.isFile() || metadataEntry.isSymbolicLink()) {
30634
30768
  throw new Error("GitHub workspace metadata is invalid");
30635
30769
  }
30636
- const metadata = parseMetadata(await readFile6(metadataPath, "utf8"));
30770
+ const metadata = parseMetadata(await readFile7(metadataPath, "utf8"));
30637
30771
  if (metadata.repositoryId !== repository.repositoryId || metadata.fullName !== repository.fullName || !samePath(metadata.path, destination)) {
30638
30772
  throw new Error("GitHub workspace metadata does not match this repository");
30639
30773
  }
@@ -31180,7 +31314,7 @@ function createGithubToolPackFactory(options = {}) {
31180
31314
  var githubToolPackFactory = createGithubToolPackFactory();
31181
31315
 
31182
31316
  // src/runners/linear-api.ts
31183
- import { createHash as createHash2, randomUUID as randomUUID9 } from "node:crypto";
31317
+ import { createHash as createHash3, randomUUID as randomUUID9 } from "node:crypto";
31184
31318
  var MAX_RESPONSE_BYTES2 = 2 * 1024 * 1024;
31185
31319
  var MAX_RESULT_STRING = 1e5;
31186
31320
  var MAX_RESULT_ARRAY = 100;
@@ -31751,7 +31885,7 @@ function operationFor(name, args, appUserId, heldBy) {
31751
31885
  }
31752
31886
  }
31753
31887
  function fingerprint(value) {
31754
- return createHash2("sha256").update(canonicalLinearMutationPayload(value)).digest("hex");
31888
+ return createHash3("sha256").update(canonicalLinearMutationPayload(value)).digest("hex");
31755
31889
  }
31756
31890
  function providerIntentFor(mutation, payloadFingerprint2) {
31757
31891
  const common = {
@@ -32242,8 +32376,8 @@ var linearToolPackFactory = {
32242
32376
  async create(grant, context) {
32243
32377
  let resolveCancelled;
32244
32378
  let closed = false;
32245
- const cancelled = new Promise((resolve15) => {
32246
- resolveCancelled = resolve15;
32379
+ const cancelled = new Promise((resolve16) => {
32380
+ resolveCancelled = resolve16;
32247
32381
  });
32248
32382
  const cancel = () => {
32249
32383
  if (closed) return;
@@ -32433,6 +32567,56 @@ var TOOLS = [
32433
32567
  additionalProperties: false
32434
32568
  }
32435
32569
  },
32570
+ {
32571
+ name: "publish_file",
32572
+ 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.",
32573
+ inputSchema: {
32574
+ type: "object",
32575
+ properties: {
32576
+ path: { type: "string", description: "Workspace-relative or absolute path to the file." },
32577
+ media_type: {
32578
+ type: "string",
32579
+ description: "Optional MIME content type; inferred from the filename when omitted."
32580
+ }
32581
+ },
32582
+ required: ["path"],
32583
+ additionalProperties: false
32584
+ }
32585
+ },
32586
+ {
32587
+ name: "list_file_capabilities",
32588
+ description: "List the file actions currently available for this Task in Zixt, Slack, and Linear, including any missing connection or OAuth scope.",
32589
+ inputSchema: { type: "object", properties: {}, additionalProperties: false }
32590
+ },
32591
+ {
32592
+ name: "send_file_to_slack",
32593
+ description: "After publish_file, ask the user for approval and upload that immutable Zixt file to one Slack member or channel. Use ids returned by find_person or list_channels.",
32594
+ inputSchema: {
32595
+ type: "object",
32596
+ properties: {
32597
+ artifact_id: { type: "string" },
32598
+ to: { type: "string", description: "Slack U\u2026, C\u2026, or G\u2026 id." },
32599
+ comment: { type: "string", description: "Optional message accompanying the file." },
32600
+ thread_ts: { type: "string", description: "Optional existing Slack thread timestamp." }
32601
+ },
32602
+ required: ["artifact_id", "to"],
32603
+ additionalProperties: false
32604
+ }
32605
+ },
32606
+ {
32607
+ name: "attach_file_to_linear",
32608
+ description: "After publish_file, ask the user for approval, upload that immutable Zixt file to Linear private storage, and attach its private asset URL to one issue.",
32609
+ inputSchema: {
32610
+ type: "object",
32611
+ properties: {
32612
+ artifact_id: { type: "string" },
32613
+ issue_id: { type: "string", description: "Stable Linear issue id." },
32614
+ title: { type: "string", description: "Optional attachment title." }
32615
+ },
32616
+ required: ["artifact_id", "issue_id"],
32617
+ additionalProperties: false
32618
+ }
32619
+ },
32436
32620
  {
32437
32621
  name: "schedule_task",
32438
32622
  description: 'Create a durable Zixt Automation for YOURSELF: every tick runs the given instructions as a new task. The Automation survives runner sessions and Machine restarts and has no end unless you explicitly provide ends_at because the user requested a limit. Use this tool for every request to schedule recurring Zixt work. If a tick finds nothing to do, end that run with "nothing to do"; never invent work.',
@@ -32911,6 +33095,23 @@ function opFor(name, args) {
32911
33095
  };
32912
33096
  case "list_channels":
32913
33097
  return { kind: "comm.list_channels", provider: "slack" };
33098
+ case "list_file_capabilities":
33099
+ return { kind: "artifact.capabilities" };
33100
+ case "send_file_to_slack":
33101
+ return {
33102
+ kind: "artifact.deliver.slack",
33103
+ artifactId: str("artifact_id"),
33104
+ to: str("to"),
33105
+ ...typeof args["comment"] === "string" && args["comment"] ? { comment: args["comment"] } : {},
33106
+ ...typeof args["thread_ts"] === "string" && args["thread_ts"] ? { threadTs: args["thread_ts"] } : {}
33107
+ };
33108
+ case "attach_file_to_linear":
33109
+ return {
33110
+ kind: "artifact.deliver.linear",
33111
+ artifactId: str("artifact_id"),
33112
+ issueId: str("issue_id"),
33113
+ ...typeof args["title"] === "string" && args["title"] ? { title: args["title"] } : {}
33114
+ };
32914
33115
  case "send_message":
32915
33116
  return {
32916
33117
  kind: "comm.send",
@@ -32929,7 +33130,7 @@ function createAskUserServer() {
32929
33130
  let server;
32930
33131
  let listening;
32931
33132
  function ensureListening() {
32932
- listening ??= new Promise((resolve15, reject3) => {
33133
+ listening ??= new Promise((resolve16, reject3) => {
32933
33134
  server = createServer2((req, res) => {
32934
33135
  res.on("error", () => {
32935
33136
  });
@@ -32945,7 +33146,7 @@ function createAskUserServer() {
32945
33146
  server.on("error", reject3);
32946
33147
  server.listen(0, "127.0.0.1", () => {
32947
33148
  const address = server.address();
32948
- if (address && typeof address === "object") resolve15(address.port);
33149
+ if (address && typeof address === "object") resolve16(address.port);
32949
33150
  else reject3(new Error("ask_user server failed to bind"));
32950
33151
  });
32951
33152
  server.unref();
@@ -33046,6 +33247,26 @@ function createAskUserServer() {
33046
33247
  }
33047
33248
  return;
33048
33249
  }
33250
+ if (name === "publish_file") {
33251
+ if (!handlers.publishFile) {
33252
+ toolText("file publishing is unavailable for this runner", true);
33253
+ return;
33254
+ }
33255
+ try {
33256
+ const path = typeof args["path"] === "string" ? args["path"] : "";
33257
+ if (!path) {
33258
+ toolText("missing required argument `path`", true);
33259
+ return;
33260
+ }
33261
+ const mediaType = typeof args["media_type"] === "string" && args["media_type"] ? args["media_type"] : void 0;
33262
+ const outcome = await handlers.publishFile(path, mediaType);
33263
+ if (outcome.ok) toolText(JSON.stringify(outcome.result ?? { ok: true }, null, 2));
33264
+ else toolText(outcome.error ?? "the file could not be published", true);
33265
+ } catch {
33266
+ toolText("the file could not be read safely", true);
33267
+ }
33268
+ return;
33269
+ }
33049
33270
  const toolPack = run3.toolOwners.get(name);
33050
33271
  if (toolPack) {
33051
33272
  try {
@@ -33084,7 +33305,40 @@ function createAskUserServer() {
33084
33305
  return;
33085
33306
  }
33086
33307
  try {
33087
- const outcome = await handlers.agentOp(opFor(name, args));
33308
+ const op = opFor(name, args);
33309
+ if (op.kind === "artifact.deliver.slack" || op.kind === "artifact.deliver.linear") {
33310
+ if (!handlers.requestApproval) {
33311
+ toolText("file delivery requires user approval, but approval is unavailable", true);
33312
+ return;
33313
+ }
33314
+ const preview = await handlers.agentOp({
33315
+ kind: "artifact.delivery.preview",
33316
+ target: op.kind === "artifact.deliver.slack" ? "slack" : "linear",
33317
+ artifactId: op.artifactId,
33318
+ destinationId: op.kind === "artifact.deliver.slack" ? op.to : op.issueId
33319
+ });
33320
+ if (!preview.ok || !preview.result || typeof preview.result !== "object") {
33321
+ toolText(preview.error ?? "The file or destination is no longer available.", true);
33322
+ return;
33323
+ }
33324
+ const artifactName = preview.result["artifactName"];
33325
+ const destinationLabel = preview.result["destinationLabel"];
33326
+ if (typeof artifactName !== "string" || typeof destinationLabel !== "string") {
33327
+ toolText("Zixt could not verify the file and destination.", true);
33328
+ return;
33329
+ }
33330
+ const destination = op.kind === "artifact.deliver.slack" ? `Slack destination ${destinationLabel}` : `Linear issue ${destinationLabel}`;
33331
+ const decision = await handlers.requestApproval(
33332
+ "content.publish",
33333
+ `Send \u201C${artifactName}\u201D to ${destination}`,
33334
+ JSON.stringify({ file: artifactName, destination })
33335
+ );
33336
+ if (!decision.approved) {
33337
+ toolText(decision.guidance ?? "The user did not approve this file delivery.", true);
33338
+ return;
33339
+ }
33340
+ }
33341
+ const outcome = await handlers.agentOp(op);
33088
33342
  if (outcome.ok) toolText(JSON.stringify(outcome.result ?? { ok: true }, null, 2));
33089
33343
  else toolText(outcome.error ?? "the operation failed", true);
33090
33344
  } catch (err) {
@@ -33106,6 +33360,8 @@ function createAskUserServer() {
33106
33360
  const handlers = {
33107
33361
  askUser: input.askUser,
33108
33362
  agentOp: input.agentOp,
33363
+ ..."requestApproval" in input && input.requestApproval ? { requestApproval: input.requestApproval } : {},
33364
+ ..."publishFile" in input && input.publishFile ? { publishFile: input.publishFile } : {},
33109
33365
  ...toolPacks.length > 0 ? { toolPacks } : {}
33110
33366
  };
33111
33367
  const toolOwners = /* @__PURE__ */ new Map();
@@ -33137,7 +33393,7 @@ function createAskUserServer() {
33137
33393
  }
33138
33394
 
33139
33395
  // src/runners/runner-env.ts
33140
- import { delimiter as delimiter2, isAbsolute as isAbsolute10 } from "node:path";
33396
+ import { delimiter as delimiter2, isAbsolute as isAbsolute11 } from "node:path";
33141
33397
  var PROVIDER_AUTHORITY_PREFIXES = ["GH_", "GITHUB_", "GIT_", "SSH_"];
33142
33398
  var HOST_AUTHORITY_PREFIXES = [
33143
33399
  "ZIXT_",
@@ -33196,7 +33452,7 @@ function inheritedValue(env, name) {
33196
33452
  }
33197
33453
  function sanitizeInheritedSearchPath(path) {
33198
33454
  if (!path) return "";
33199
- return path.split(delimiter2).filter((entry) => entry !== "" && isAbsolute10(entry)).join(delimiter2);
33455
+ return path.split(delimiter2).filter((entry) => entry !== "" && isAbsolute11(entry)).join(delimiter2);
33200
33456
  }
33201
33457
  function buildRunnerEnv(input) {
33202
33458
  const env = {};
@@ -33277,9 +33533,9 @@ function buildRunnerEnv(input) {
33277
33533
  // src/runners/github-shell-auth.ts
33278
33534
  import { execFile } from "node:child_process";
33279
33535
  import { randomBytes as randomBytes2, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
33280
- import { chmod as chmod5, lstat as lstat8, mkdir as mkdir8, realpath as realpath5, writeFile as writeFile4 } from "node:fs/promises";
33536
+ import { chmod as chmod5, lstat as lstat9, mkdir as mkdir8, realpath as realpath6, writeFile as writeFile4 } from "node:fs/promises";
33281
33537
  import { createServer as createServer3 } from "node:http";
33282
- import { isAbsolute as isAbsolute11, join as join12, relative as relative6 } from "node:path";
33538
+ import { isAbsolute as isAbsolute12, join as join12, relative as relative7 } from "node:path";
33283
33539
  var MAX_REQUEST_BYTES2 = 16 * 1024;
33284
33540
  var DIRECTORY_MODE3 = 448;
33285
33541
  var PRIVATE_FILE_MODE = 384;
@@ -33485,7 +33741,7 @@ function parseGhInvocation(body) {
33485
33741
  }
33486
33742
  if (!value || typeof value !== "object" || Array.isArray(value)) return null;
33487
33743
  const { args, cwd } = value;
33488
- if (!Array.isArray(args) || args.length > 256 || args.some((argument) => typeof argument !== "string" || argument.length > 4096) || typeof cwd !== "string" || cwd.length === 0 || cwd.length > 4096 || !isAbsolute11(cwd)) {
33744
+ if (!Array.isArray(args) || args.length > 256 || args.some((argument) => typeof argument !== "string" || argument.length > 4096) || typeof cwd !== "string" || cwd.length === 0 || cwd.length > 4096 || !isAbsolute12(cwd)) {
33489
33745
  return null;
33490
33746
  }
33491
33747
  return { args, cwd };
@@ -33643,8 +33899,8 @@ function activationCredential(grant, now = Date.now()) {
33643
33899
  return expiresAt.getTime() <= now ? null : { accessToken: grant.accessToken, expiresAt };
33644
33900
  }
33645
33901
  function assertChildPath2(parent, child) {
33646
- const path = relative6(parent, child);
33647
- if (!path || path === ".." || path.startsWith("../") || path.startsWith("..\\") || isAbsolute11(path)) {
33902
+ const path = relative7(parent, child);
33903
+ if (!path || path === ".." || path.startsWith("../") || path.startsWith("..\\") || isAbsolute12(path)) {
33648
33904
  throw new Error("GitHub shell helper path escaped its private run directory");
33649
33905
  }
33650
33906
  }
@@ -33662,11 +33918,11 @@ async function writePrivate(path, content, executable = false) {
33662
33918
  await chmod5(path, executable ? EXECUTABLE_FILE_MODE : PRIVATE_FILE_MODE);
33663
33919
  }
33664
33920
  async function prepareHelpers(input) {
33665
- const rootEntry = await lstat8(input.runRoot);
33921
+ const rootEntry = await lstat9(input.runRoot);
33666
33922
  if (!rootEntry.isDirectory() || rootEntry.isSymbolicLink()) {
33667
33923
  throw new Error("GitHub shell authentication requires a private real run directory");
33668
33924
  }
33669
- const runRoot = await realpath5(input.runRoot);
33925
+ const runRoot = await realpath6(input.runRoot);
33670
33926
  const helperPath = join12(runRoot, "github-shell-git-credential.cjs");
33671
33927
  assertChildPath2(runRoot, helperPath);
33672
33928
  await writePrivate(helperPath, GIT_HELPER_SOURCE);
@@ -33909,7 +34165,7 @@ password=${credential.accessToken}
33909
34165
 
33910
34166
  // src/runners/working-context.ts
33911
34167
  import { spawn as spawn6 } from "node:child_process";
33912
- import { resolve as resolve6 } from "node:path";
34168
+ import { resolve as resolve7 } from "node:path";
33913
34169
  var COMMAND_TIMEOUT_MS = 5e3;
33914
34170
  var OUTPUT_LIMIT_BYTES = 128 * 1024;
33915
34171
  var COMMAND_STOP_TIMEOUT_MS = 2e4;
@@ -34267,8 +34523,8 @@ async function repositoryState(directory, git, env, signal) {
34267
34523
  const pathLines = paths.trim().split(/\r?\n/);
34268
34524
  if (pathLines.length < 3 || !pathLines[0] || !pathLines[1] || !pathLines[2]) return null;
34269
34525
  const root = pathLines[0];
34270
- const gitDirectory = resolve6(directory, pathLines[1]);
34271
- const commonDirectory = resolve6(directory, pathLines[2]);
34526
+ const gitDirectory = resolve7(directory, pathLines[1]);
34527
+ const commonDirectory = resolve7(directory, pathLines[2]);
34272
34528
  const records = status.split(/\0|\r?\n/).filter(Boolean);
34273
34529
  const rawBranch = statusField(records, "branch.head");
34274
34530
  if (!rawBranch || rawBranch.length > 512 || !isSafeSingleLineDisplayText(rawBranch)) return null;
@@ -34415,18 +34671,18 @@ var WorkingContextPullRequestCache = class {
34415
34671
  import { spawn as spawn7 } from "node:child_process";
34416
34672
  import {
34417
34673
  chmod as chmod6,
34418
- lstat as lstat9,
34674
+ lstat as lstat10,
34419
34675
  mkdir as mkdir9,
34420
34676
  open as open5,
34421
34677
  readdir as readdir3,
34422
- readFile as readFile7,
34423
- realpath as realpath6,
34678
+ readFile as readFile8,
34679
+ realpath as realpath7,
34424
34680
  rename as rename5,
34425
34681
  rm as rm7,
34426
34682
  writeFile as writeFile5
34427
34683
  } from "node:fs/promises";
34428
34684
  import { homedir as homedir3 } from "node:os";
34429
- import { dirname as dirname6, isAbsolute as isAbsolute12, join as join13, relative as relative7, resolve as resolve7, sep as sep3, win32 as win322 } from "node:path";
34685
+ import { dirname as dirname6, isAbsolute as isAbsolute13, join as join13, relative as relative8, resolve as resolve8, sep as sep4, win32 as win322 } from "node:path";
34430
34686
  var SAFE_SEGMENT2 = /^[A-Za-z0-9_-]{1,200}$/;
34431
34687
  var DIRECTORY_MODE4 = 448;
34432
34688
  var FILE_MODE3 = 384;
@@ -34654,15 +34910,15 @@ function isMissing(error52) {
34654
34910
  return error52.code === "ENOENT";
34655
34911
  }
34656
34912
  function assertBelow3(parent, child) {
34657
- const path = relative7(parent, child);
34658
- const escapes = path === "" || path === ".." || path.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) || isAbsolute12(path);
34913
+ const path = relative8(parent, child);
34914
+ const escapes = path === "" || path === ".." || path.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) || isAbsolute13(path);
34659
34915
  if (escapes) throw new Error("run artifact path escapes its private root");
34660
34916
  }
34661
34917
  async function requireRealDirectory3(path, label) {
34662
- const entry = await lstat9(path);
34918
+ const entry = await lstat10(path);
34663
34919
  if (entry.isSymbolicLink()) throw new Error(`${label} must not be a symbolic link`);
34664
34920
  if (!entry.isDirectory()) throw new Error(`${label} must be a directory`);
34665
- return realpath6(path);
34921
+ return realpath7(path);
34666
34922
  }
34667
34923
  function assertWindowsProfileBoundary(profile, target) {
34668
34924
  const path = win322.relative(win322.resolve(profile), win322.resolve(target));
@@ -34676,7 +34932,7 @@ async function rejectWindowsSymlinkAncestors(profile, target) {
34676
34932
  for (const segment of path.split("\\").filter(Boolean)) {
34677
34933
  current = win322.join(current, segment);
34678
34934
  try {
34679
- const entry = await lstat9(current);
34935
+ const entry = await lstat10(current);
34680
34936
  if (entry.isSymbolicLink()) {
34681
34937
  throw new Error("run artifact path must not contain symbolic links or junctions");
34682
34938
  }
@@ -34687,16 +34943,16 @@ async function rejectWindowsSymlinkAncestors(profile, target) {
34687
34943
  }
34688
34944
  }
34689
34945
  async function prepareRoot(root) {
34690
- const absolute = resolve7(root);
34946
+ const absolute = resolve8(root);
34691
34947
  let realProfile;
34692
34948
  if (process.platform === "win32") {
34693
- const profile = resolve7(homedir3());
34949
+ const profile = resolve8(homedir3());
34694
34950
  assertWindowsProfileBoundary(profile, absolute);
34695
34951
  await rejectWindowsSymlinkAncestors(profile, absolute);
34696
- realProfile = await realpath6(profile);
34952
+ realProfile = await realpath7(profile);
34697
34953
  }
34698
34954
  try {
34699
- await lstat9(absolute);
34955
+ await lstat10(absolute);
34700
34956
  } catch (error52) {
34701
34957
  if (!isMissing(error52)) throw error52;
34702
34958
  await mkdir9(absolute, { recursive: true, mode: DIRECTORY_MODE4 });
@@ -34710,7 +34966,7 @@ async function prepareAgentRoot(root, agentId) {
34710
34966
  const path = join13(root, agentId);
34711
34967
  assertBelow3(root, path);
34712
34968
  try {
34713
- await lstat9(path);
34969
+ await lstat10(path);
34714
34970
  } catch (error52) {
34715
34971
  if (!isMissing(error52)) throw error52;
34716
34972
  try {
@@ -34776,7 +35032,7 @@ async function createPrivateDirectory(parent, name) {
34776
35032
  assertBelow3(parent, path);
34777
35033
  await mkdir9(path, { mode: DIRECTORY_MODE4 });
34778
35034
  await chmod6(path, DIRECTORY_MODE4);
34779
- const real = await realpath6(path);
35035
+ const real = await realpath7(path);
34780
35036
  assertBelow3(parent, real);
34781
35037
  return real;
34782
35038
  }
@@ -34810,7 +35066,7 @@ async function createRunArtifacts(input) {
34810
35066
  try {
34811
35067
  await mkdir9(runRoot, { mode: DIRECTORY_MODE4 });
34812
35068
  await chmod6(runRoot, DIRECTORY_MODE4);
34813
- const realRunRoot = await realpath6(runRoot);
35069
+ const realRunRoot = await realpath7(runRoot);
34814
35070
  assertBelow3(agentRoot, realRunRoot);
34815
35071
  const emptyGithubConfigDirectory = await createPrivateDirectory(realRunRoot, "gh-config");
34816
35072
  const emptyGitHooksDirectory = await createPrivateDirectory(realRunRoot, "git-hooks");
@@ -34860,13 +35116,13 @@ async function removePrivateTreeWithRetries(path, removeTree, retryDelayMs) {
34860
35116
  }
34861
35117
  }
34862
35118
  async function sweepOrphanedRunArtifacts(root) {
34863
- const absolute = resolve7(root);
35119
+ const absolute = resolve8(root);
34864
35120
  let realProfile;
34865
35121
  if (process.platform === "win32") {
34866
- const profile = resolve7(homedir3());
35122
+ const profile = resolve8(homedir3());
34867
35123
  assertWindowsProfileBoundary(profile, absolute);
34868
35124
  await rejectWindowsSymlinkAncestors(profile, absolute);
34869
- realProfile = await realpath6(profile);
35125
+ realProfile = await realpath7(profile);
34870
35126
  }
34871
35127
  let realRoot;
34872
35128
  try {
@@ -34908,11 +35164,11 @@ async function syncRunRegistryDirectory(path) {
34908
35164
  async function ensureDurableRunRegistryRoot(registryRoot, syncDirectory7) {
34909
35165
  const firstCreated = await mkdir9(registryRoot, { recursive: true, mode: DIRECTORY_MODE4 });
34910
35166
  if (firstCreated && process.platform !== "win32") {
34911
- const first = resolve7(firstCreated);
34912
- const target = resolve7(registryRoot);
35167
+ const first = resolve8(firstCreated);
35168
+ const target = resolve8(registryRoot);
34913
35169
  await syncDirectory7(dirname6(first));
34914
35170
  let current = first;
34915
- for (const part of relative7(first, target).split(sep3).filter(Boolean)) {
35171
+ for (const part of relative8(first, target).split(sep4).filter(Boolean)) {
34916
35172
  await syncDirectory7(current);
34917
35173
  current = join13(current, part);
34918
35174
  }
@@ -34999,7 +35255,7 @@ async function readRecordedRunAssignmentEntries(registryRoot = defaultRunRegistr
34999
35255
  if (!SAFE_SEGMENT2.test(runToken)) continue;
35000
35256
  let text;
35001
35257
  try {
35002
- text = await readFile7(join13(registryRoot, entry.name), "utf8");
35258
+ text = await readFile8(join13(registryRoot, entry.name), "utf8");
35003
35259
  } catch {
35004
35260
  continue;
35005
35261
  }
@@ -35011,7 +35267,7 @@ async function readRecordedRunAssignmentEntries(registryRoot = defaultRunRegistr
35011
35267
  async function readRecordedRunAssignmentEntriesStrict(registryRoot = defaultRunRegistryRoot()) {
35012
35268
  let rootStat;
35013
35269
  try {
35014
- rootStat = await lstat9(registryRoot);
35270
+ rootStat = await lstat10(registryRoot);
35015
35271
  } catch (error52) {
35016
35272
  if (isMissing(error52)) return [];
35017
35273
  throw new Error("run registry state could not be observed");
@@ -35035,7 +35291,7 @@ async function readRecordedRunAssignmentEntriesStrict(registryRoot = defaultRunR
35035
35291
  }
35036
35292
  let text;
35037
35293
  try {
35038
- text = await readFile7(join13(registryRoot, entry.name), "utf8");
35294
+ text = await readFile8(join13(registryRoot, entry.name), "utf8");
35039
35295
  } catch {
35040
35296
  throw new Error("committed run registry witness could not be read");
35041
35297
  }
@@ -35129,11 +35385,11 @@ function truncateThought(text) {
35129
35385
  }
35130
35386
  var MAX_APPROVAL_PAYLOAD = 5e4;
35131
35387
  async function requireRealDirectory4(path, label) {
35132
- const entry = await lstat10(path).catch(() => null);
35388
+ const entry = await lstat11(path).catch(() => null);
35133
35389
  if (!entry) throw new Error(`${label} does not exist`);
35134
35390
  if (entry.isSymbolicLink()) throw new Error(`${label} must not be a symbolic link`);
35135
35391
  if (!entry.isDirectory()) throw new Error(`${label} must be a directory`);
35136
- return realpath7(path);
35392
+ return realpath8(path);
35137
35393
  }
35138
35394
  function createCliRunner(adapter, opts = {}) {
35139
35395
  const command = opts.command ?? adapter.defaultCommand;
@@ -35352,6 +35608,21 @@ function createCliRunner(adapter, opts = {}) {
35352
35608
  pendingAsks--;
35353
35609
  }
35354
35610
  },
35611
+ requestApproval: async (category, summary, payload) => {
35612
+ pendingAsks++;
35613
+ try {
35614
+ return await task.requestApproval(category, summary, payload);
35615
+ } finally {
35616
+ pendingAsks--;
35617
+ }
35618
+ },
35619
+ publishFile: (path, mediaType) => publishTaskFile({
35620
+ path,
35621
+ ...mediaType ? { mediaType } : {},
35622
+ cwd,
35623
+ allowedRoots: [taskRoot, cwd],
35624
+ agentOp: (op) => task.agentOp(op)
35625
+ }),
35355
35626
  agentOp: (op) => task.agentOp(op),
35356
35627
  // GitHub repository work belongs in the installed `git` and `gh`
35357
35628
  // commands backed by GithubShellAuth. Do not advertise the bundled
@@ -35483,7 +35754,7 @@ ${attachmentSection}` : prompt;
35483
35754
  let changed = false;
35484
35755
  for (const path of paths) {
35485
35756
  if (!path || path.length > 4096) continue;
35486
- const absolutePath = isAbsolute13(path) ? path : resolve8(cwd, path);
35757
+ const absolutePath = isAbsolute14(path) ? path : resolve9(cwd, path);
35487
35758
  const directory = dirname7(absolutePath);
35488
35759
  observedWorkingDirectories.delete(directory);
35489
35760
  observedWorkingDirectories.add(directory);
@@ -35906,7 +36177,7 @@ function runCliProcess(options) {
35906
36177
  usage: { inputTokens: 0, outputTokens: 0 }
35907
36178
  });
35908
36179
  }
35909
- return new Promise((resolve15) => {
36180
+ return new Promise((resolve16) => {
35910
36181
  const platform = options.platform ?? process.platform;
35911
36182
  const containmentGateNonce = options.guardian && platform === "win32" ? randomUUID10() : void 0;
35912
36183
  const child = options.guardian ? spawn8(
@@ -35967,7 +36238,7 @@ function runCliProcess(options) {
35967
36238
  clearInterval(timer);
35968
36239
  unregisterFollowUps?.();
35969
36240
  parser.stop?.();
35970
- resolve15(result);
36241
+ resolve16(result);
35971
36242
  };
35972
36243
  const terminate = (result) => {
35973
36244
  if (settled || forcedResult) return;
@@ -36198,7 +36469,7 @@ function runCliProcess(options) {
36198
36469
  import { randomUUID as randomUUID11 } from "node:crypto";
36199
36470
 
36200
36471
  // src/runners/runtime-observation.ts
36201
- import { open as open6, readdir as readdir4, realpath as realpath8 } from "node:fs/promises";
36472
+ import { open as open6, readdir as readdir4, realpath as realpath9 } from "node:fs/promises";
36202
36473
  import { homedir as homedir5 } from "node:os";
36203
36474
  import { join as join15 } from "node:path";
36204
36475
  var READ_WINDOW_BYTES = 1024 * 1024;
@@ -36265,7 +36536,7 @@ function claudeTranscriptPath(input) {
36265
36536
  return join15(configDir, "projects", slug, `${input.sessionId}.jsonl`);
36266
36537
  }
36267
36538
  async function readClaudeSessionEffort(input) {
36268
- const resolvedCwd = await realpath8(input.cwd).catch(() => input.cwd);
36539
+ const resolvedCwd = await realpath9(input.cwd).catch(() => input.cwd);
36269
36540
  const path = claudeTranscriptPath({ env: input.env, resolvedCwd, sessionId: input.sessionId });
36270
36541
  const records = parseLines(await readTail(path));
36271
36542
  for (let index = records.length - 1; index >= 0; index -= 1) {
@@ -36312,7 +36583,7 @@ async function readCodexSessionRuntime(input) {
36312
36583
  }
36313
36584
  var codexCatalogCache = /* @__PURE__ */ new Map();
36314
36585
  async function loadCodexModelCatalog(command, prefixArgs, env) {
36315
- const output = await new Promise((resolve15) => {
36586
+ const output = await new Promise((resolve16) => {
36316
36587
  const child = spawnCli(command, [...prefixArgs, "debug", "models"], {
36317
36588
  stdio: ["ignore", "pipe", "ignore"],
36318
36589
  windowsHide: true,
@@ -36327,7 +36598,7 @@ async function loadCodexModelCatalog(command, prefixArgs, env) {
36327
36598
  if (settled) return;
36328
36599
  settled = true;
36329
36600
  clearTimeout(timer);
36330
- resolve15(value);
36601
+ resolve16(value);
36331
36602
  };
36332
36603
  const timer = setTimeout(() => {
36333
36604
  child.kill();
@@ -36432,8 +36703,8 @@ function createRuntimeReporter(input, sessionId) {
36432
36703
  var EFFORT_READ_ATTEMPTS = 5;
36433
36704
  var EFFORT_READ_INTERVAL_MS = 3e3;
36434
36705
  function delay2(ms) {
36435
- return new Promise((resolve15) => {
36436
- const timer = setTimeout(resolve15, ms);
36706
+ return new Promise((resolve16) => {
36707
+ const timer = setTimeout(resolve16, ms);
36437
36708
  timer.unref?.();
36438
36709
  });
36439
36710
  }
@@ -36510,10 +36781,10 @@ function createClaudeLiveParser(onStream, onSessionModel) {
36510
36781
  },
36511
36782
  async steer(followUp) {
36512
36783
  if (!write) return false;
36513
- return await new Promise((resolve15) => {
36514
- acknowledgements.set(followUp.inputId, resolve15);
36784
+ return await new Promise((resolve16) => {
36785
+ acknowledgements.set(followUp.inputId, resolve16);
36515
36786
  void write(input(followUp.inputId, followUp.text)).catch(() => {
36516
- if (acknowledgements.delete(followUp.inputId)) resolve15(false);
36787
+ if (acknowledgements.delete(followUp.inputId)) resolve16(false);
36517
36788
  });
36518
36789
  });
36519
36790
  },
@@ -36673,7 +36944,7 @@ function improveErrorMessage(error52) {
36673
36944
  }
36674
36945
 
36675
36946
  // src/runners/codex.ts
36676
- import { mkdir as mkdir11, readFile as readFile8, writeFile as writeFile6 } from "node:fs/promises";
36947
+ import { mkdir as mkdir11, readFile as readFile9, writeFile as writeFile6 } from "node:fs/promises";
36677
36948
  import { randomUUID as randomUUID12 } from "node:crypto";
36678
36949
  import { homedir as homedir6 } from "node:os";
36679
36950
  import { join as join16 } from "node:path";
@@ -36688,7 +36959,7 @@ function threadIndexPath(root, agentId, sessionKey) {
36688
36959
  }
36689
36960
  async function readThreadId(path) {
36690
36961
  try {
36691
- const parsed = JSON.parse(await readFile8(path, "utf8"));
36962
+ const parsed = JSON.parse(await readFile9(path, "utf8"));
36692
36963
  return typeof parsed.threadId === "string" && /^[A-Za-z0-9-]{1,120}$/.test(parsed.threadId) ? parsed.threadId : null;
36693
36964
  } catch {
36694
36965
  return null;
@@ -36820,8 +37091,8 @@ ${value}` : value;
36820
37091
  var RUNTIME_READ_ATTEMPTS = 5;
36821
37092
  var RUNTIME_READ_INTERVAL_MS = 2e3;
36822
37093
  function delay3(ms) {
36823
- return new Promise((resolve15) => {
36824
- const timer = setTimeout(resolve15, ms);
37094
+ return new Promise((resolve16) => {
37095
+ const timer = setTimeout(resolve16, ms);
36825
37096
  timer.unref?.();
36826
37097
  });
36827
37098
  }
@@ -36860,7 +37131,7 @@ function createCodexAppServerParser(onStream, options) {
36860
37131
  const turnReadyWaiters = /* @__PURE__ */ new Set();
36861
37132
  const usage = () => ({ inputTokens, outputTokens });
36862
37133
  const settleTurnReadiness = (ready) => {
36863
- for (const resolve15 of turnReadyWaiters) resolve15(ready);
37134
+ for (const resolve16 of turnReadyWaiters) resolve16(ready);
36864
37135
  turnReadyWaiters.clear();
36865
37136
  };
36866
37137
  const send = async (message) => {
@@ -37041,12 +37312,12 @@ function createCodexAppServerParser(onStream, options) {
37041
37312
  async steer(input) {
37042
37313
  if (stopped) return false;
37043
37314
  if (!activeTurnId) {
37044
- const ready = await new Promise((resolve15) => turnReadyWaiters.add(resolve15));
37315
+ const ready = await new Promise((resolve16) => turnReadyWaiters.add(resolve16));
37045
37316
  if (!ready || stopped) return false;
37046
37317
  }
37047
37318
  if (!threadId || !activeTurnId) return false;
37048
- return await new Promise((resolve15) => {
37049
- steerWaiters.set(input.inputId, resolve15);
37319
+ return await new Promise((resolve16) => {
37320
+ steerWaiters.set(input.inputId, resolve16);
37050
37321
  void send({
37051
37322
  id: `steer:${input.inputId}`,
37052
37323
  method: "turn/steer",
@@ -37057,7 +37328,7 @@ function createCodexAppServerParser(onStream, options) {
37057
37328
  clientUserMessageId: input.inputId
37058
37329
  }
37059
37330
  }).catch(() => {
37060
- if (steerWaiters.delete(input.inputId)) resolve15(false);
37331
+ if (steerWaiters.delete(input.inputId)) resolve16(false);
37061
37332
  });
37062
37333
  });
37063
37334
  },
@@ -37065,7 +37336,7 @@ function createCodexAppServerParser(onStream, options) {
37065
37336
  stopped = true;
37066
37337
  write = null;
37067
37338
  settleTurnReadiness(false);
37068
- for (const resolve15 of steerWaiters.values()) resolve15(false);
37339
+ for (const resolve16 of steerWaiters.values()) resolve16(false);
37069
37340
  steerWaiters.clear();
37070
37341
  },
37071
37342
  push(chunk) {
@@ -37243,8 +37514,8 @@ function improveCodexErrorMessage(error52) {
37243
37514
 
37244
37515
  // src/runners/git-preflight.ts
37245
37516
  import { spawn as spawn9 } from "node:child_process";
37246
- import { realpath as realpath9 } from "node:fs/promises";
37247
- import { isAbsolute as isAbsolute14, resolve as resolve9 } from "node:path";
37517
+ import { realpath as realpath10 } from "node:fs/promises";
37518
+ import { isAbsolute as isAbsolute15, resolve as resolve10 } from "node:path";
37248
37519
  var OUTPUT_LIMIT = 8192;
37249
37520
  var DEFAULT_TIMEOUT_MS4 = 1e4;
37250
37521
  var VERSION_PATTERN = /^git version [^\r\n]{1,108}$/;
@@ -37260,10 +37531,10 @@ function unavailable(error52, checkedAt, executablePath = null) {
37260
37531
  async function preflightGit(options = {}) {
37261
37532
  const checkedAt = (options.now?.() ?? /* @__PURE__ */ new Date()).toISOString();
37262
37533
  const configured = options.command;
37263
- if (configured !== void 0 && !isAbsolute14(configured)) {
37534
+ if (configured !== void 0 && !isAbsolute15(configured)) {
37264
37535
  return unavailable("configured git command must be an absolute file", checkedAt);
37265
37536
  }
37266
- const trustedCwd = await realpath9(resolve9(options.trustedCwd ?? process.cwd())).catch(() => null);
37537
+ const trustedCwd = await realpath10(resolve10(options.trustedCwd ?? process.cwd())).catch(() => null);
37267
37538
  if (!trustedCwd)
37268
37539
  return unavailable("Host-owned git preflight directory is unavailable", checkedAt);
37269
37540
  const executablePath = await resolveTrustedCliCommand(configured ?? "git", {
@@ -37485,7 +37756,7 @@ function parseAuth(result) {
37485
37756
  return "unknown";
37486
37757
  }
37487
37758
  function run2(command, args) {
37488
- return new Promise((resolve15) => {
37759
+ return new Promise((resolve16) => {
37489
37760
  const child = spawnCli(command, args, {
37490
37761
  stdio: ["ignore", "pipe", "pipe"],
37491
37762
  windowsHide: true
@@ -37501,7 +37772,7 @@ function run2(command, args) {
37501
37772
  if (settled) return;
37502
37773
  settled = true;
37503
37774
  clearTimeout(timeout);
37504
- resolve15(result);
37775
+ resolve16(result);
37505
37776
  };
37506
37777
  const timeout = setTimeout(() => {
37507
37778
  child.kill();
@@ -37517,7 +37788,7 @@ import { spawn as spawn10 } from "node:child_process";
37517
37788
  import { constants as constants2 } from "node:fs";
37518
37789
  import { access as access4, chmod as chmod7, mkdir as mkdir12, open as open7, rename as rename6, rm as rm8 } from "node:fs/promises";
37519
37790
  import { homedir as homedir7, userInfo } from "node:os";
37520
- import { basename as basename3, dirname as dirname8, join as join17, relative as relative8, resolve as resolve10, sep as sep4 } from "node:path";
37791
+ import { basename as basename4, dirname as dirname8, join as join17, relative as relative9, resolve as resolve11, sep as sep5 } from "node:path";
37521
37792
  var SERVICE_NAME = "zixt-host.service";
37522
37793
  var SYSTEM_SERVICE_COMMAND_TIMEOUT_MS = 7e4;
37523
37794
  var SERVICE_STABILITY_DELAY_MS = 2e3;
@@ -37545,7 +37816,7 @@ function boundedAppend(current, chunk) {
37545
37816
  }
37546
37817
  async function defaultRunCommand(command, args) {
37547
37818
  const commandEnvironment3 = systemServiceCommandEnvironment();
37548
- return new Promise((resolve15) => {
37819
+ return new Promise((resolve16) => {
37549
37820
  const child = spawn10(command, [...args], {
37550
37821
  stdio: ["ignore", "pipe", "pipe"],
37551
37822
  env: commandEnvironment3,
@@ -37559,7 +37830,7 @@ async function defaultRunCommand(command, args) {
37559
37830
  if (settled) return;
37560
37831
  settled = true;
37561
37832
  if (timer) clearTimeout(timer);
37562
- resolve15(result);
37833
+ resolve16(result);
37563
37834
  };
37564
37835
  child.stdout?.on("data", (chunk) => {
37565
37836
  stdout = boundedAppend(stdout, chunk);
@@ -37620,12 +37891,12 @@ async function defaultSyncDirectory(path) {
37620
37891
  async function ensureDirectory(path, mode, syncDirectory7) {
37621
37892
  const firstCreated = await mkdir12(path, { recursive: true, mode });
37622
37893
  if (!firstCreated) return;
37623
- const first = resolve10(firstCreated);
37624
- const target = resolve10(path);
37894
+ const first = resolve11(firstCreated);
37895
+ const target = resolve11(path);
37625
37896
  await syncDirectory7(dirname8(first));
37626
37897
  let current = first;
37627
- const descendants = relative8(first, target);
37628
- for (const part of descendants ? descendants.split(sep4) : []) {
37898
+ const descendants = relative9(first, target);
37899
+ for (const part of descendants ? descendants.split(sep5) : []) {
37629
37900
  await syncDirectory7(current);
37630
37901
  current = join17(current, part);
37631
37902
  }
@@ -37633,7 +37904,7 @@ async function ensureDirectory(path, mode, syncDirectory7) {
37633
37904
  async function replacePrivateFile(path, contents, mode, syncDirectory7) {
37634
37905
  const parent = dirname8(path);
37635
37906
  await ensureDirectory(parent, 448, syncDirectory7);
37636
- const temporary = join17(parent, `.${basename3(path)}.${process.pid}.${crypto.randomUUID()}.tmp`);
37907
+ const temporary = join17(parent, `.${basename4(path)}.${process.pid}.${crypto.randomUUID()}.tmp`);
37637
37908
  const handle = await open7(temporary, "wx", mode);
37638
37909
  try {
37639
37910
  await handle.writeFile(contents, "utf8");
@@ -37695,7 +37966,7 @@ async function installLinuxService(options) {
37695
37966
  const resolveCommand = options.resolveCommand ?? defaultResolveCommand;
37696
37967
  const run3 = options.runCommand ?? defaultRunCommand;
37697
37968
  const syncDirectory7 = options.syncDirectory ?? defaultSyncDirectory;
37698
- const stabilityDelay = options.delay ?? ((ms) => new Promise((resolve15) => setTimeout(resolve15, ms)));
37969
+ const stabilityDelay = options.delay ?? ((ms) => new Promise((resolve16) => setTimeout(resolve16, ms)));
37699
37970
  const [systemctl, loginctl] = await Promise.all([
37700
37971
  resolveCommand("systemctl"),
37701
37972
  resolveCommand("loginctl")
@@ -37810,7 +38081,7 @@ import { spawn as spawn11 } from "node:child_process";
37810
38081
  import { constants as constants3 } from "node:fs";
37811
38082
  import { access as access5, chmod as chmod8, mkdir as mkdir13, open as open8, rename as rename7, rm as rm9 } from "node:fs/promises";
37812
38083
  import { homedir as homedir8, userInfo as userInfo2 } from "node:os";
37813
- import { basename as basename4, dirname as dirname9, join as join18, relative as relative9, resolve as resolve11, sep as sep5 } from "node:path";
38084
+ import { basename as basename5, dirname as dirname9, join as join18, relative as relative10, resolve as resolve12, sep as sep6 } from "node:path";
37814
38085
  var LAUNCH_AGENT_LABEL = "ai.zixt.host";
37815
38086
  var SERVICE_STABILITY_DELAY_MS2 = 2e3;
37816
38087
  var COMMAND_TIMEOUT_MS2 = 7e4;
@@ -37836,11 +38107,11 @@ async function syncDirectory4(path) {
37836
38107
  async function ensureDirectory2(path, sync) {
37837
38108
  const firstCreated = await mkdir13(path, { recursive: true, mode: 448 });
37838
38109
  if (!firstCreated) return;
37839
- const first = resolve11(firstCreated);
37840
- const target = resolve11(path);
38110
+ const first = resolve12(firstCreated);
38111
+ const target = resolve12(path);
37841
38112
  await sync(dirname9(first));
37842
38113
  let current = first;
37843
- for (const part of relative9(first, target).split(sep5).filter(Boolean)) {
38114
+ for (const part of relative10(first, target).split(sep6).filter(Boolean)) {
37844
38115
  await sync(current);
37845
38116
  current = join18(current, part);
37846
38117
  }
@@ -37848,7 +38119,7 @@ async function ensureDirectory2(path, sync) {
37848
38119
  async function replacePrivateFile2(path, contents, mode, sync) {
37849
38120
  const parent = dirname9(path);
37850
38121
  await ensureDirectory2(parent, sync);
37851
- const temporary = join18(parent, `.${basename4(path)}.${process.pid}.${crypto.randomUUID()}.tmp`);
38122
+ const temporary = join18(parent, `.${basename5(path)}.${process.pid}.${crypto.randomUUID()}.tmp`);
37852
38123
  const handle = await open8(temporary, "wx", mode);
37853
38124
  try {
37854
38125
  await handle.writeFile(contents, "utf8");
@@ -38039,9 +38310,9 @@ async function installMacosService(options) {
38039
38310
  // src/windows-service.ts
38040
38311
  import { spawn as spawn12 } from "node:child_process";
38041
38312
  import { constants as constants4 } from "node:fs";
38042
- import { access as access6, mkdir as mkdir14, open as open9, readFile as readFile9, rename as rename8, rm as rm10 } from "node:fs/promises";
38313
+ import { access as access6, mkdir as mkdir14, open as open9, readFile as readFile10, rename as rename8, rm as rm10 } from "node:fs/promises";
38043
38314
  import { homedir as homedir9 } from "node:os";
38044
- import { basename as basename5, dirname as dirname10, isAbsolute as isAbsolute15, join as join19, relative as relative10, resolve as resolve12, sep as sep6 } from "node:path";
38315
+ import { basename as basename6, dirname as dirname10, isAbsolute as isAbsolute16, join as join19, relative as relative11, resolve as resolve13, sep as sep7 } from "node:path";
38045
38316
  var TASK_NAME = "Zixt Host";
38046
38317
  var COMMAND_TIMEOUT_MS3 = 7e4;
38047
38318
  var SERVICE_STABILITY_DELAY_MS3 = 2e3;
@@ -38069,11 +38340,11 @@ async function syncDirectory5(path) {
38069
38340
  async function ensureDirectory3(path, sync) {
38070
38341
  const firstCreated = await mkdir14(path, { recursive: true, mode: 448 });
38071
38342
  if (!firstCreated) return;
38072
- const first = resolve12(firstCreated);
38073
- const target = resolve12(path);
38343
+ const first = resolve13(firstCreated);
38344
+ const target = resolve13(path);
38074
38345
  await sync(dirname10(first));
38075
38346
  let current = first;
38076
- for (const part of relative10(first, target).split(sep6).filter(Boolean)) {
38347
+ for (const part of relative11(first, target).split(sep7).filter(Boolean)) {
38077
38348
  await sync(current);
38078
38349
  current = join19(current, part);
38079
38350
  }
@@ -38081,7 +38352,7 @@ async function ensureDirectory3(path, sync) {
38081
38352
  async function replacePrivateFile3(path, contents, sync) {
38082
38353
  const parent = dirname10(path);
38083
38354
  await ensureDirectory3(parent, sync);
38084
- const temporary = join19(parent, `.${basename5(path)}.${process.pid}.${crypto.randomUUID()}.tmp`);
38355
+ const temporary = join19(parent, `.${basename6(path)}.${process.pid}.${crypto.randomUUID()}.tmp`);
38085
38356
  const handle = await open9(temporary, "wx", 384);
38086
38357
  try {
38087
38358
  await handle.writeFile(contents, "utf8");
@@ -38135,7 +38406,7 @@ async function runChild(command, args, env, input) {
38135
38406
  }
38136
38407
  async function defaultResolveCommand3(name, env) {
38137
38408
  const root = env.SYSTEMROOT ?? env.WINDIR;
38138
- if (!root || !isAbsolute15(root)) return null;
38409
+ if (!root || !isAbsolute16(root)) return null;
38139
38410
  const candidate = name === "powershell" ? join19(root, "System32", "WindowsPowerShell", "v1.0", "powershell.exe") : join19(root, "System32", `${name}.exe`);
38140
38411
  return access6(candidate, constants4.X_OK).then(
38141
38412
  () => candidate,
@@ -38224,7 +38495,7 @@ exit $code
38224
38495
  }
38225
38496
  async function defaultObserveStatus(path, generation) {
38226
38497
  try {
38227
- const text = (await readFile9(path, "utf8")).replace(/^\uFEFF/, "");
38498
+ const text = (await readFile10(path, "utf8")).replace(/^\uFEFF/, "");
38228
38499
  const value = JSON.parse(text);
38229
38500
  if (value.schema !== 1 || value.generation !== generation || typeof value.pid !== "number" || !Number.isSafeInteger(value.pid) || value.pid <= 0) {
38230
38501
  return null;
@@ -38267,7 +38538,7 @@ async function installWindowsService(options) {
38267
38538
  const env = options.env ?? process.env;
38268
38539
  const home = options.home ?? homedir9();
38269
38540
  const localAppData = options.localAppData ?? env.LOCALAPPDATA;
38270
- if (!localAppData || !isAbsolute15(localAppData)) {
38541
+ if (!localAppData || !isAbsolute16(localAppData)) {
38271
38542
  throw new Error("Windows local application data path is unavailable.");
38272
38543
  }
38273
38544
  const token2 = oneLine3(options.token, "pairing code");
@@ -38378,9 +38649,9 @@ async function installSystemService(options) {
38378
38649
  }
38379
38650
 
38380
38651
  // src/terminal-outcomes.ts
38381
- import { chmod as chmod9, lstat as lstat11, mkdir as mkdir15, open as open10, readdir as readdir5, readFile as readFile10, rename as rename9, rm as rm11 } from "node:fs/promises";
38652
+ import { chmod as chmod9, lstat as lstat12, mkdir as mkdir15, open as open10, readdir as readdir5, readFile as readFile11, rename as rename9, rm as rm11 } from "node:fs/promises";
38382
38653
  import { homedir as homedir10 } from "node:os";
38383
- import { dirname as dirname11, join as join20, relative as relative11, resolve as resolve13, sep as sep7 } from "node:path";
38654
+ import { dirname as dirname11, join as join20, relative as relative12, resolve as resolve14, sep as sep8 } from "node:path";
38384
38655
  var DIRECTORY_MODE5 = 448;
38385
38656
  var FILE_MODE4 = 384;
38386
38657
  var MAX_OUTCOME_BYTES = 4 * 1024 * 1024;
@@ -38408,16 +38679,16 @@ async function syncDirectory6(root) {
38408
38679
  async function requirePrivateRoot(root, sync = syncDirectory6) {
38409
38680
  const firstCreated = await mkdir15(root, { recursive: true, mode: DIRECTORY_MODE5 });
38410
38681
  if (firstCreated) {
38411
- const first = resolve13(firstCreated);
38412
- const target = resolve13(root);
38682
+ const first = resolve14(firstCreated);
38683
+ const target = resolve14(root);
38413
38684
  await sync(dirname11(first));
38414
38685
  let current = first;
38415
- for (const part of relative11(first, target).split(sep7).filter(Boolean)) {
38686
+ for (const part of relative12(first, target).split(sep8).filter(Boolean)) {
38416
38687
  await sync(current);
38417
38688
  current = join20(current, part);
38418
38689
  }
38419
38690
  }
38420
- const stat3 = await lstat11(root);
38691
+ const stat3 = await lstat12(root);
38421
38692
  if (stat3.isSymbolicLink() || !stat3.isDirectory()) {
38422
38693
  throw new Error("terminal outcome journal root is not a trusted directory");
38423
38694
  }
@@ -38445,7 +38716,7 @@ async function recordTerminalOutcome(hostId, input, root = defaultTerminalOutcom
38445
38716
  const destination = outcomePath(root, hostId, outcome.taskId, outcome.epoch);
38446
38717
  try {
38447
38718
  const existing = parseCommittedOutcome(
38448
- await readFile10(destination, { encoding: "utf8", flag: "r" }),
38719
+ await readFile11(destination, { encoding: "utf8", flag: "r" }),
38449
38720
  outcome.taskId,
38450
38721
  outcome.epoch
38451
38722
  );
@@ -38478,7 +38749,7 @@ async function recordTerminalOutcome(hostId, input, root = defaultTerminalOutcom
38478
38749
  async function readTerminalOutcomesStrict(root = defaultTerminalOutcomeRoot()) {
38479
38750
  let rootStat;
38480
38751
  try {
38481
- rootStat = await lstat11(root);
38752
+ rootStat = await lstat12(root);
38482
38753
  } catch (error52) {
38483
38754
  if (error52.code === "ENOENT") return [];
38484
38755
  throw new Error("terminal outcome journal could not be observed");
@@ -38495,7 +38766,7 @@ async function readTerminalOutcomesStrict(root = defaultTerminalOutcomeRoot()) {
38495
38766
  throw new Error("terminal outcome Host scope is not a trusted directory");
38496
38767
  }
38497
38768
  const scopedRoot = hostOutcomeRoot(root, hostEntry.name);
38498
- const scopedStat = await lstat11(scopedRoot);
38769
+ const scopedStat = await lstat12(scopedRoot);
38499
38770
  if (scopedStat.isSymbolicLink() || !scopedStat.isDirectory()) {
38500
38771
  throw new Error("terminal outcome Host scope is not a trusted directory");
38501
38772
  }
@@ -38508,12 +38779,12 @@ async function readTerminalOutcomesStrict(root = defaultTerminalOutcomeRoot()) {
38508
38779
  throw new Error("committed terminal outcome is not a trusted regular file");
38509
38780
  }
38510
38781
  const path = join20(scopedRoot, entry.name);
38511
- const stat3 = await lstat11(path);
38782
+ const stat3 = await lstat12(path);
38512
38783
  if (!stat3.isFile() || stat3.isSymbolicLink() || stat3.size > MAX_OUTCOME_BYTES) {
38513
38784
  throw new Error("committed terminal outcome is not a trusted regular file");
38514
38785
  }
38515
38786
  const outcome = parseCommittedOutcome(
38516
- await readFile10(path, "utf8"),
38787
+ await readFile11(path, "utf8"),
38517
38788
  match[1],
38518
38789
  Number(match[2])
38519
38790
  );
@@ -38660,13 +38931,13 @@ function createHostLogger(options = {}) {
38660
38931
  }
38661
38932
 
38662
38933
  // src/demo-state.ts
38663
- import { isAbsolute as isAbsolute16, join as join21, parse as parse3, resolve as resolve14 } from "node:path";
38934
+ import { isAbsolute as isAbsolute17, join as join21, parse as parse3, resolve as resolve15 } from "node:path";
38664
38935
  var DEMO_STATE_ROOT_ENV = "ZIXT_DEMO_STATE_ROOT";
38665
38936
  function resolveDemoHostStatePaths(env = process.env) {
38666
38937
  const configured = env.ZIXT_RUNNER === "demo" ? env[DEMO_STATE_ROOT_ENV] : void 0;
38667
38938
  if (!configured) return null;
38668
- const root = resolve14(configured);
38669
- if (!isAbsolute16(configured) || root === parse3(root).root) {
38939
+ const root = resolve15(configured);
38940
+ if (!isAbsolute17(configured) || root === parse3(root).root) {
38670
38941
  throw new Error(`${DEMO_STATE_ROOT_ENV} must be a dedicated absolute directory`);
38671
38942
  }
38672
38943
  return {