@ai-development-environment/control-agent 0.0.53 → 0.0.55

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.
@@ -1,4 +1,6 @@
1
1
  #!/usr/bin/env node
2
+ import { createRequire } from "node:module";
3
+ const require = createRequire(import.meta.url);
2
4
  var __create = Object.create;
3
5
  var __defProp = Object.defineProperty;
4
6
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -3728,15 +3730,15 @@ var require_windows = __commonJS({
3728
3730
  }
3729
3731
  return false;
3730
3732
  }
3731
- function checkStat(stat9, path, options) {
3732
- if (!stat9.isSymbolicLink() && !stat9.isFile()) {
3733
+ function checkStat(stat10, path, options) {
3734
+ if (!stat10.isSymbolicLink() && !stat10.isFile()) {
3733
3735
  return false;
3734
3736
  }
3735
3737
  return checkPathExt(path, options);
3736
3738
  }
3737
3739
  function isexe(path, options, cb2) {
3738
- fs.stat(path, function(er2, stat9) {
3739
- cb2(er2, er2 ? false : checkStat(stat9, path, options));
3740
+ fs.stat(path, function(er2, stat10) {
3741
+ cb2(er2, er2 ? false : checkStat(stat10, path, options));
3740
3742
  });
3741
3743
  }
3742
3744
  function sync(path, options) {
@@ -3752,20 +3754,20 @@ var require_mode = __commonJS({
3752
3754
  isexe.sync = sync;
3753
3755
  var fs = __require("fs");
3754
3756
  function isexe(path, options, cb2) {
3755
- fs.stat(path, function(er2, stat9) {
3756
- cb2(er2, er2 ? false : checkStat(stat9, options));
3757
+ fs.stat(path, function(er2, stat10) {
3758
+ cb2(er2, er2 ? false : checkStat(stat10, options));
3757
3759
  });
3758
3760
  }
3759
3761
  function sync(path, options) {
3760
3762
  return checkStat(fs.statSync(path), options);
3761
3763
  }
3762
- function checkStat(stat9, options) {
3763
- return stat9.isFile() && checkMode(stat9, options);
3764
+ function checkStat(stat10, options) {
3765
+ return stat10.isFile() && checkMode(stat10, options);
3764
3766
  }
3765
- function checkMode(stat9, options) {
3766
- var mod = stat9.mode;
3767
- var uid = stat9.uid;
3768
- var gid = stat9.gid;
3767
+ function checkMode(stat10, options) {
3768
+ var mod = stat10.mode;
3769
+ var uid = stat10.uid;
3770
+ var gid = stat10.gid;
3769
3771
  var myUid = options.uid !== void 0 ? options.uid : process.getuid && process.getuid();
3770
3772
  var myGid = options.gid !== void 0 ? options.gid : process.getgid && process.getgid();
3771
3773
  var u = parseInt("100", 8);
@@ -4182,7 +4184,7 @@ var require_cross_spawn = __commonJS({
4182
4184
  var cp3 = __require("child_process");
4183
4185
  var parse2 = require_parse();
4184
4186
  var enoent = require_enoent();
4185
- function spawn7(command3, args, options) {
4187
+ function spawn8(command3, args, options) {
4186
4188
  const parsed = parse2(command3, args, options);
4187
4189
  const spawned = cp3.spawn(parsed.command, parsed.args, parsed.options);
4188
4190
  enoent.hookChildProcess(spawned, parsed);
@@ -4194,18 +4196,14 @@ var require_cross_spawn = __commonJS({
4194
4196
  result.error = result.error || enoent.verifyENOENTSync(result.status, parsed);
4195
4197
  return result;
4196
4198
  }
4197
- module.exports = spawn7;
4198
- module.exports.spawn = spawn7;
4199
+ module.exports = spawn8;
4200
+ module.exports.spawn = spawn8;
4199
4201
  module.exports.sync = spawnSync2;
4200
4202
  module.exports._parse = parse2;
4201
4203
  module.exports._enoent = enoent;
4202
4204
  }
4203
4205
  });
4204
4206
 
4205
- // src/index.ts
4206
- import { execFile as execFile5 } from "node:child_process";
4207
- import { promisify as promisify5 } from "node:util";
4208
-
4209
4207
  // src/config.ts
4210
4208
  import { chmod, mkdir, readFile, rename, writeFile } from "node:fs/promises";
4211
4209
  import { homedir } from "node:os";
@@ -4252,8 +4250,6 @@ async function saveConfig(config, path = configPath()) {
4252
4250
  }
4253
4251
 
4254
4252
  // ../agent-contract/src/index.ts
4255
- var TUNNEL_NAME_PATTERN = "[A-Za-z0-9][A-Za-z0-9_-]{0,127}";
4256
- var TUNNEL_NAME_REGEX = new RegExp(`^${TUNNEL_NAME_PATTERN}$`);
4257
4253
  var CCUSAGE_REPORT_JOB_KIND = "ccusage.report";
4258
4254
  var DEFAULT_AGENT_HEARTBEAT_INTERVAL_SECONDS = 15;
4259
4255
  var MIN_AGENT_HEARTBEAT_INTERVAL_SECONDS = 5;
@@ -5170,6 +5166,24 @@ var AgentGraphQLClient = class {
5170
5166
  }
5171
5167
  );
5172
5168
  }
5169
+ async diskSpaceConfiguration() {
5170
+ const data = await this.request(`query AgentDiskSpaceConfiguration {
5171
+ agentDiskSpaceConfiguration {
5172
+ enabled pollIntervalSeconds baseRepoDirectory
5173
+ derivedDataLocationMode derivedDataPath
5174
+ worktrees { id folder }
5175
+ }
5176
+ }`);
5177
+ return data.agentDiskSpaceConfiguration;
5178
+ }
5179
+ reportDiskSpace(input) {
5180
+ return this.request(
5181
+ `mutation ReportAgentDiskSpace($input: AgentDiskSpaceReportInput!) {
5182
+ reportAgentDiskSpace(input: $input)
5183
+ }`,
5184
+ { input }
5185
+ );
5186
+ }
5173
5187
  async pendingJobs(agentId) {
5174
5188
  const data = await this.request(
5175
5189
  `query PendingJobs($agentId: ID!) {
@@ -5180,7 +5194,7 @@ var AgentGraphQLClient = class {
5180
5194
  { agentId }
5181
5195
  );
5182
5196
  return data.agentJobs.filter(
5183
- (job) => job.status === "QUEUED" || job.status === "RUNNING" || job.status === "CANCELLED"
5197
+ (job) => job.status === "QUEUED" || job.status === "RUNNING" || job.status === "CANCELLING" || job.status === "CANCELLED"
5184
5198
  );
5185
5199
  }
5186
5200
  async cadenceSettings(agentId) {
@@ -5236,6 +5250,14 @@ var AgentGraphQLClient = class {
5236
5250
  { jobId, logs: [log] }
5237
5251
  );
5238
5252
  }
5253
+ appendCommandOutput(jobId, attemptId, chunks) {
5254
+ return this.request(
5255
+ `mutation AppendCommandRunOutput($jobId: ID!, $attemptId: ID!, $chunks: [CommandRunOutputInput!]!) {
5256
+ appendCommandRunOutput(jobId: $jobId, attemptId: $attemptId, chunks: $chunks) { id }
5257
+ }`,
5258
+ { jobId, attemptId, chunks }
5259
+ );
5260
+ }
5239
5261
  reportBuildProgress(input) {
5240
5262
  return this.request(
5241
5263
  `mutation ReportBuildProgress($input: BuildProgressInput!) {
@@ -5244,12 +5266,12 @@ var AgentGraphQLClient = class {
5244
5266
  { input }
5245
5267
  );
5246
5268
  }
5247
- appendBuildLogs(buildId, events) {
5269
+ appendBuildLogChunks(buildId, chunks) {
5248
5270
  return this.request(
5249
- `mutation AppendBuildLogs($buildId: ID!, $events: [BuildLogEventInput!]!) {
5250
- appendBuildLogEvents(buildId: $buildId, events: $events) { id }
5271
+ `mutation AppendBuildLogChunks($buildId: ID!, $chunks: [BuildLogChunkInput!]!) {
5272
+ appendBuildLogChunks(buildId: $buildId, chunks: $chunks) { id }
5251
5273
  }`,
5252
- { buildId, events }
5274
+ { buildId, chunks }
5253
5275
  );
5254
5276
  }
5255
5277
  async uploadBuildArtifact(input) {
@@ -5590,6 +5612,10 @@ function nullableString(value, name) {
5590
5612
  if (value === null) return null;
5591
5613
  return stringValue2(value, name);
5592
5614
  }
5615
+ function optionalNullableString(value, name) {
5616
+ if (value === void 0 || value === null) return null;
5617
+ return stringValue2(value, name);
5618
+ }
5593
5619
  function exactKeys(value, allowed, name) {
5594
5620
  const unexpected = Object.keys(value).find((key) => !allowed.includes(key));
5595
5621
  if (unexpected) throw new Error(`Unexpected ${name} field: ${unexpected}`);
@@ -5619,6 +5645,44 @@ function target(value, index) {
5619
5645
  )
5620
5646
  };
5621
5647
  }
5648
+ function deleteTarget(value, index) {
5649
+ const item = objectValue2(value, `build data delete targets[${index}]`);
5650
+ exactKeys(
5651
+ item,
5652
+ ["path", "rootPath", "name", "kind", "worktreeId", "worktreePath"],
5653
+ "build data delete target"
5654
+ );
5655
+ const kind = item.kind;
5656
+ if (kind !== void 0 && !["PROJECT", "PENDING", "SHARED_CACHE", "DEVICE_SUPPORT"].includes(kind)) {
5657
+ throw new Error(`build data delete targets[${index}].kind is invalid`);
5658
+ }
5659
+ return {
5660
+ path: stringValue2(item.path, `build data delete targets[${index}].path`),
5661
+ rootPath: stringValue2(
5662
+ item.rootPath,
5663
+ `build data delete targets[${index}].rootPath`
5664
+ ),
5665
+ ...item.name === void 0 ? {} : {
5666
+ name: stringValue2(
5667
+ item.name,
5668
+ `build data delete targets[${index}].name`
5669
+ )
5670
+ },
5671
+ ...kind === void 0 ? {} : { kind },
5672
+ ...item.worktreeId === void 0 ? {} : {
5673
+ worktreeId: optionalNullableString(
5674
+ item.worktreeId,
5675
+ `build data delete targets[${index}].worktreeId`
5676
+ )
5677
+ },
5678
+ ...item.worktreePath === void 0 ? {} : {
5679
+ worktreePath: optionalNullableString(
5680
+ item.worktreePath,
5681
+ `build data delete targets[${index}].worktreePath`
5682
+ )
5683
+ }
5684
+ };
5685
+ }
5622
5686
  function buildDataScanPayload(value) {
5623
5687
  const payload = objectValue2(value, "build data scan payload");
5624
5688
  exactKeys(payload, ["mode", "path", "worktrees"], "build data scan payload");
@@ -5649,6 +5713,23 @@ function buildDataTargetsPayload(value) {
5649
5713
  }
5650
5714
  return { targets: payload.targets.map(target) };
5651
5715
  }
5716
+ function buildDataDeletePayload(value) {
5717
+ const payload = objectValue2(value, "build data delete payload");
5718
+ exactKeys(payload, ["targets", "source"], "build data delete payload");
5719
+ if (!Array.isArray(payload.targets) || payload.targets.length > 1e4) {
5720
+ throw new Error(
5721
+ "build data delete targets must be an array of at most 10,000 items"
5722
+ );
5723
+ }
5724
+ const source = payload.source ?? "USER";
5725
+ if (source !== "USER" && source !== "AUTOMATIC") {
5726
+ throw new Error("build data delete source is invalid");
5727
+ }
5728
+ return {
5729
+ targets: payload.targets.map(deleteTarget),
5730
+ source
5731
+ };
5732
+ }
5652
5733
 
5653
5734
  // ../agent-contract/src/codebases.ts
5654
5735
  var CODEBASE_BROWSE_JOB_KIND = "codebase.browse";
@@ -7782,10 +7863,58 @@ function parseWorkflowGitCheckpointPayload(value) {
7782
7863
  };
7783
7864
  }
7784
7865
 
7866
+ // ../agent-contract/src/commands.ts
7867
+ var COMMAND_RUN_JOB_KIND = "command.run";
7868
+ function objectValue10(value, name) {
7869
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
7870
+ throw new Error(`${name} must be an object`);
7871
+ }
7872
+ return value;
7873
+ }
7874
+ function stringValue10(value, name, maximum) {
7875
+ if (typeof value !== "string" || !value.length || value.length > maximum) {
7876
+ throw new Error(
7877
+ `${name} must be a non-empty string of at most ${maximum} characters`
7878
+ );
7879
+ }
7880
+ return value;
7881
+ }
7882
+ function parseCommandRunPayload(value) {
7883
+ const payload = objectValue10(value, "command run payload");
7884
+ const targetKind = stringValue10(payload.targetKind, "targetKind", 20);
7885
+ if (targetKind !== "AGENT_HOME" && targetKind !== "WORKTREE") {
7886
+ throw new Error("targetKind must be AGENT_HOME or WORKTREE");
7887
+ }
7888
+ const cwd = payload.cwd === null || payload.cwd === void 0 ? null : stringValue10(payload.cwd, "cwd", 1e4);
7889
+ if (targetKind === "WORKTREE" && !cwd) {
7890
+ throw new Error("Worktree commands require cwd");
7891
+ }
7892
+ if (targetKind === "AGENT_HOME" && cwd !== null) {
7893
+ throw new Error("Agent-home commands cannot provide cwd");
7894
+ }
7895
+ const allowed = /* @__PURE__ */ new Set([
7896
+ "commandRunId",
7897
+ "attemptId",
7898
+ "targetKind",
7899
+ "cwd",
7900
+ "script"
7901
+ ]);
7902
+ const unexpected = Object.keys(payload).find((key) => !allowed.has(key));
7903
+ if (unexpected)
7904
+ throw new Error(`Unsupported command payload field: ${unexpected}`);
7905
+ return {
7906
+ commandRunId: stringValue10(payload.commandRunId, "commandRunId", 200),
7907
+ attemptId: stringValue10(payload.attemptId, "attemptId", 200),
7908
+ targetKind,
7909
+ cwd,
7910
+ script: stringValue10(payload.script, "script", 1e6)
7911
+ };
7912
+ }
7913
+
7785
7914
  // src/inventory.ts
7786
7915
  var AGENT_VERSION = "0.1.0";
7787
7916
  var AGENT_CAPABILITIES = [
7788
- "cloudflared.runTunnel",
7917
+ COMMAND_RUN_JOB_KIND,
7789
7918
  CCUSAGE_REPORT_JOB_KIND,
7790
7919
  ...BUILD_DATA_JOB_KINDS,
7791
7920
  ...CODEBASE_JOB_KINDS,
@@ -7817,148 +7946,186 @@ function collectInventory() {
7817
7946
  };
7818
7947
  }
7819
7948
 
7820
- // src/process-runner.ts
7949
+ // src/handlers/commands.ts
7821
7950
  import { spawn } from "node:child_process";
7822
- async function runProcess(options) {
7823
- return new Promise((resolve7, reject) => {
7824
- let sequence = 0;
7825
- let timedOut = false;
7826
- let cancelled = false;
7827
- let settled = false;
7828
- let logChain = Promise.resolve();
7829
- const detached = process.platform !== "win32";
7830
- const child = spawn(options.command, options.args, {
7831
- shell: false,
7832
- stdio: ["ignore", "pipe", "pipe"],
7833
- cwd: options.cwd,
7834
- env: options.env ?? process.env,
7835
- // A separate process group lets cancellation terminate scripts and all
7836
- // descendants instead of leaving a child holding stdout/stderr open.
7837
- detached
7838
- });
7839
- const emit = (stream, message) => {
7840
- const log = {
7841
- sequence: sequence++,
7842
- stream,
7843
- message,
7844
- createdAt: (/* @__PURE__ */ new Date()).toISOString()
7845
- };
7846
- logChain = logChain.then(async () => {
7951
+ import { chmod as chmod2, mkdtemp, realpath, rm as rm2, writeFile as writeFile2 } from "node:fs/promises";
7952
+ import { homedir as homedir2, tmpdir } from "node:os";
7953
+ import { join as join2 } from "node:path";
7954
+ var MAX_BATCH_BYTES = 128 * 1024;
7955
+ var FLUSH_DELAY_MS = 25;
7956
+ var runCommand = async (rawPayload, _timeoutMs, signal, _onLog, context) => {
7957
+ const payload = parseCommandRunPayload(rawPayload);
7958
+ if (!context?.appendCommandOutput) {
7959
+ throw new Error("Command output uploader is unavailable");
7960
+ }
7961
+ const directory = await mkdtemp(join2(tmpdir(), "aide-command-"));
7962
+ const scriptPath = join2(directory, "command.sh");
7963
+ await writeFile2(scriptPath, payload.script, {
7964
+ encoding: "utf8",
7965
+ mode: 384
7966
+ });
7967
+ await chmod2(scriptPath, 384);
7968
+ const cwd = payload.targetKind === "AGENT_HOME" ? homedir2() : await realpath(payload.cwd);
7969
+ let sequence = 0;
7970
+ let queuedBytes = 0;
7971
+ let pending = [];
7972
+ let timer;
7973
+ let uploadChain = Promise.resolve();
7974
+ const upload = (chunks) => {
7975
+ if (!chunks.length) return;
7976
+ const bytes = chunks.reduce((total, chunk) => total + chunk.byteLength, 0);
7977
+ uploadChain = uploadChain.then(async () => {
7978
+ let retry = 0;
7979
+ while (true) {
7847
7980
  try {
7848
- await options.onLog(log);
7981
+ await context.appendCommandOutput?.(payload.attemptId, chunks);
7982
+ queuedBytes -= bytes;
7983
+ return;
7849
7984
  } catch (error) {
7985
+ if (signal.aborted) return;
7986
+ const delay = Math.min(3e4, 500 * 2 ** Math.min(retry++, 6));
7850
7987
  console.error(
7851
- `Could not append process log ${log.sequence}:`,
7988
+ `Could not append command output; retrying in ${delay}ms:`,
7852
7989
  error instanceof Error ? error.message : error
7853
7990
  );
7991
+ await new Promise((resolve7) => {
7992
+ const onAbort = () => {
7993
+ clearTimeout(retryTimer);
7994
+ resolve7();
7995
+ };
7996
+ const retryTimer = setTimeout(() => {
7997
+ signal.removeEventListener("abort", onAbort);
7998
+ resolve7();
7999
+ }, delay);
8000
+ retryTimer.unref();
8001
+ signal.addEventListener("abort", onAbort, { once: true });
8002
+ if (signal.aborted) onAbort();
8003
+ });
8004
+ if (signal.aborted) return;
7854
8005
  }
7855
- });
8006
+ }
8007
+ });
8008
+ };
8009
+ const flush = () => {
8010
+ if (timer) clearTimeout(timer);
8011
+ timer = void 0;
8012
+ const batch = pending;
8013
+ pending = [];
8014
+ upload(batch);
8015
+ };
8016
+ const enqueue = (stream, bytes) => {
8017
+ const chunk = {
8018
+ sequence: sequence++,
8019
+ stream,
8020
+ dataBase64: bytes.toString("base64"),
8021
+ byteLength: bytes.length,
8022
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
7856
8023
  };
7857
- const attach = (stream, kind) => {
7858
- let remainder = "";
7859
- stream.setEncoding("utf8");
7860
- stream.on("data", (chunk) => {
7861
- const parts = `${remainder}${chunk}`.split(/\r?\n/);
7862
- remainder = parts.pop() ?? "";
7863
- for (const line of parts) emit(kind, line);
8024
+ pending.push(chunk);
8025
+ queuedBytes += bytes.length;
8026
+ if (pending.reduce((total, item) => total + item.byteLength, 0) >= MAX_BATCH_BYTES) {
8027
+ flush();
8028
+ } else if (!timer) {
8029
+ timer = setTimeout(flush, FLUSH_DELAY_MS);
8030
+ timer.unref();
8031
+ }
8032
+ };
8033
+ try {
8034
+ return await new Promise((resolve7, reject) => {
8035
+ let cancelled = false;
8036
+ let settled = false;
8037
+ const child = spawn(process.env.SHELL || "/bin/sh", ["-l", scriptPath], {
8038
+ cwd,
8039
+ detached: process.platform !== "win32",
8040
+ env: {
8041
+ ...process.env,
8042
+ TERM: "xterm-256color",
8043
+ COLORTERM: "truecolor",
8044
+ FORCE_COLOR: "1",
8045
+ CLICOLOR_FORCE: "1"
8046
+ },
8047
+ shell: false,
8048
+ stdio: ["ignore", "pipe", "pipe"]
7864
8049
  });
7865
- stream.on("end", () => {
7866
- if (remainder) emit(kind, remainder);
8050
+ const pauseForPressure = () => {
8051
+ if (queuedBytes < 4 * 1024 * 1024) return;
8052
+ child.stdout.pause();
8053
+ child.stderr.pause();
8054
+ void uploadChain.finally(() => {
8055
+ child.stdout.resume();
8056
+ child.stderr.resume();
8057
+ });
8058
+ };
8059
+ child.stdout.on("data", (bytes) => {
8060
+ enqueue("STDOUT", bytes);
8061
+ pauseForPressure();
7867
8062
  });
7868
- };
7869
- attach(child.stdout, "STDOUT");
7870
- attach(child.stderr, "STDERR");
7871
- const sendSignal = (signal) => {
7872
- if (detached && child.pid) {
8063
+ child.stderr.on("data", (bytes) => {
8064
+ enqueue("STDERR", bytes);
8065
+ pauseForPressure();
8066
+ });
8067
+ const sendSignal = (name) => {
8068
+ if (child.exitCode !== null) return;
7873
8069
  try {
7874
- process.kill(-child.pid, signal);
7875
- return;
8070
+ if (process.platform !== "win32" && child.pid)
8071
+ process.kill(-child.pid, name);
8072
+ else child.kill(name);
7876
8073
  } catch (error) {
7877
8074
  if (!(error instanceof Error) || !("code" in error) || error.code !== "ESRCH") {
7878
8075
  throw error;
7879
8076
  }
7880
8077
  }
7881
- }
7882
- child.kill(signal);
7883
- };
7884
- const terminate = () => {
7885
- if (child.exitCode !== null || child.killed) return;
7886
- sendSignal("SIGTERM");
7887
- const killTimer = setTimeout(() => sendSignal("SIGKILL"), 5e3);
7888
- killTimer.unref();
7889
- };
7890
- const timeout = setTimeout(() => {
7891
- timedOut = true;
7892
- emit(
7893
- "SYSTEM",
7894
- `Process exceeded its ${Math.round(options.timeoutMs / 1e3)} second timeout`
7895
- );
7896
- terminate();
7897
- }, options.timeoutMs);
7898
- timeout.unref();
7899
- const abort = () => {
7900
- cancelled = true;
7901
- emit("SYSTEM", "Cancellation requested");
7902
- terminate();
7903
- };
7904
- options.signal.addEventListener("abort", abort, { once: true });
7905
- child.once("error", (error) => {
7906
- if (settled) return;
7907
- settled = true;
7908
- clearTimeout(timeout);
7909
- options.signal.removeEventListener("abort", abort);
7910
- reject(error);
7911
- });
7912
- child.once("close", (exitCode, signal) => {
7913
- if (settled) return;
7914
- settled = true;
7915
- clearTimeout(timeout);
7916
- options.signal.removeEventListener("abort", abort);
7917
- void logChain.then(
7918
- () => resolve7({ exitCode, signal, timedOut, cancelled })
7919
- );
8078
+ };
8079
+ const abort = () => {
8080
+ if (cancelled) return;
8081
+ cancelled = true;
8082
+ enqueue("SYSTEM", Buffer.from("\r\nCancellation requested\r\n"));
8083
+ sendSignal("SIGTERM");
8084
+ const killTimer = setTimeout(() => sendSignal("SIGKILL"), 5e3);
8085
+ killTimer.unref();
8086
+ };
8087
+ signal.addEventListener("abort", abort, { once: true });
8088
+ if (signal.aborted) abort();
8089
+ child.once("error", (error) => {
8090
+ if (settled) return;
8091
+ settled = true;
8092
+ signal.removeEventListener("abort", abort);
8093
+ reject(error);
8094
+ });
8095
+ child.once("close", (exitCode, closeSignal) => {
8096
+ if (settled) return;
8097
+ settled = true;
8098
+ signal.removeEventListener("abort", abort);
8099
+ flush();
8100
+ void uploadChain.then(
8101
+ () => resolve7({
8102
+ exitCode,
8103
+ signal: closeSignal,
8104
+ timedOut: false,
8105
+ cancelled
8106
+ })
8107
+ );
8108
+ });
7920
8109
  });
7921
- });
7922
- }
7923
-
7924
- // src/handlers/cloudflared.ts
7925
- function validateCloudflaredPayload(payload) {
7926
- if (!payload || typeof payload !== "object" || Array.isArray(payload)) {
7927
- throw new Error("Cloudflared payload must be an object");
7928
- }
7929
- const value = payload;
7930
- if (typeof value.tunnelName !== "string" || !TUNNEL_NAME_REGEX.test(value.tunnelName)) {
7931
- throw new Error("Invalid Cloudflared tunnel name");
7932
- }
7933
- if (Object.keys(value).some((key) => key !== "tunnelName")) {
7934
- throw new Error("Cloudflared payload contains an unsupported field");
8110
+ } finally {
8111
+ if (timer) clearTimeout(timer);
8112
+ await rm2(directory, { force: true, recursive: true });
7935
8113
  }
7936
- return { tunnelName: value.tunnelName };
7937
- }
7938
- function runCloudflared(payload, timeoutMs, signal, onLog) {
7939
- const { tunnelName } = validateCloudflaredPayload(payload);
7940
- return runProcess({
7941
- command: "cloudflared",
7942
- args: ["tunnel", "run", tunnelName],
7943
- timeoutMs,
7944
- signal,
7945
- onLog
7946
- });
7947
- }
8114
+ };
7948
8115
 
7949
8116
  // src/handlers/signing.ts
7950
8117
  import { createHash as createHash3, randomUUID, X509Certificate } from "node:crypto";
7951
8118
  import {
7952
8119
  mkdir as mkdir2,
7953
- mkdtemp,
8120
+ mkdtemp as mkdtemp2,
7954
8121
  readFile as readFile2,
7955
8122
  readdir,
7956
- rm as rm2,
8123
+ rm as rm3,
7957
8124
  stat as stat2,
7958
- writeFile as writeFile2
8125
+ writeFile as writeFile3
7959
8126
  } from "node:fs/promises";
7960
- import { homedir as homedir2, tmpdir } from "node:os";
7961
- import { basename, join as join2, relative, sep } from "node:path";
8127
+ import { homedir as homedir3, tmpdir as tmpdir2 } from "node:os";
8128
+ import { basename, join as join3, relative, sep } from "node:path";
7962
8129
 
7963
8130
  // ../agent-contract/src/plist.ts
7964
8131
  function xmlEscape(value) {
@@ -8193,15 +8360,15 @@ function captureCommand(options) {
8193
8360
 
8194
8361
  // src/handlers/signing.ts
8195
8362
  var PROFILE_DIRECTORIES = [
8196
- join2(
8197
- homedir2(),
8363
+ join3(
8364
+ homedir3(),
8198
8365
  "Library",
8199
8366
  "Developer",
8200
8367
  "Xcode",
8201
8368
  "UserData",
8202
8369
  "Provisioning Profiles"
8203
8370
  ),
8204
- join2(homedir2(), "Library", "MobileDevice", "Provisioning Profiles")
8371
+ join3(homedir3(), "Library", "MobileDevice", "Provisioning Profiles")
8205
8372
  ];
8206
8373
  var PROFILE_EXTENSIONS = [".mobileprovision", ".provisionprofile"];
8207
8374
  function text(value) {
@@ -8294,7 +8461,7 @@ async function readProfiles(timeoutMs, signal) {
8294
8461
  continue;
8295
8462
  signal.throwIfAborted();
8296
8463
  const raw = await decodeProfile(
8297
- join2(directory, entry),
8464
+ join3(directory, entry),
8298
8465
  timeoutMs,
8299
8466
  signal
8300
8467
  );
@@ -8328,7 +8495,7 @@ async function decodedProfiles(timeoutMs, signal, strict = false) {
8328
8495
  continue;
8329
8496
  }
8330
8497
  signal.throwIfAborted();
8331
- const path = join2(directory, entry);
8498
+ const path = join3(directory, entry);
8332
8499
  const raw = await decodeProfile(path, timeoutMs, signal, strict);
8333
8500
  if (!raw) continue;
8334
8501
  let content;
@@ -8484,7 +8651,7 @@ async function readCertificates(timeoutMs, signal, strict = false) {
8484
8651
  );
8485
8652
  }
8486
8653
  async function readArchiveBundles(archivePath, timeoutMs, signal) {
8487
- const products = join2(archivePath, "Products");
8654
+ const products = join3(archivePath, "Products");
8488
8655
  const bundles = [];
8489
8656
  const queue = [products];
8490
8657
  while (queue.length) {
@@ -8498,7 +8665,7 @@ async function readArchiveBundles(archivePath, timeoutMs, signal) {
8498
8665
  }
8499
8666
  for (const entry of entries) {
8500
8667
  if (entry.isSymbolicLink() || !entry.isDirectory()) continue;
8501
- const path = join2(current, entry.name);
8668
+ const path = join3(current, entry.name);
8502
8669
  const signable = /\.(app|appex)$/.test(entry.name);
8503
8670
  if (!signable) {
8504
8671
  if (!/\.[A-Za-z0-9]+$/.test(entry.name)) queue.push(path);
@@ -8530,7 +8697,7 @@ async function bundleIdentifier(bundlePath, timeoutMs, signal) {
8530
8697
  "raw",
8531
8698
  "-o",
8532
8699
  "-",
8533
- join2(bundlePath, "Info.plist")
8700
+ join3(bundlePath, "Info.plist")
8534
8701
  ],
8535
8702
  timeoutMs: Math.min(timeoutMs, 5e3),
8536
8703
  signal
@@ -8546,7 +8713,7 @@ async function embeddedProfile(bundlePath, timeoutMs, signal) {
8546
8713
  "embedded.mobileprovision",
8547
8714
  "embedded.provisionprofile"
8548
8715
  ]) {
8549
- const path = join2(bundlePath, name);
8716
+ const path = join3(bundlePath, name);
8550
8717
  try {
8551
8718
  await stat2(path);
8552
8719
  } catch {
@@ -8593,7 +8760,7 @@ async function inspectSigningAssets(archivePath, timeoutMs, signal) {
8593
8760
  }
8594
8761
  var inspectIosSigning = async (payload, timeoutMs, signal) => {
8595
8762
  const input = parseBuildSigningInspectPayload(payload);
8596
- const archivePath = join2(input.artifactDirectory, input.archiveRelativePath);
8763
+ const archivePath = join3(input.artifactDirectory, input.archiveRelativePath);
8597
8764
  const inspection = await inspectSigningAssets(archivePath, timeoutMs, signal);
8598
8765
  return {
8599
8766
  exitCode: 0,
@@ -8655,21 +8822,21 @@ var installSigningProfile = async (payload, timeoutMs, signal) => {
8655
8822
  const { contentBase64 } = signingProfileInstallPayload(payload);
8656
8823
  const content = Buffer.from(contentBase64, "base64");
8657
8824
  if (!content.length) throw new Error("Provisioning profile is empty");
8658
- const temporaryRoot = await mkdtemp(join2(tmpdir(), "ade-profile-"));
8659
- const temporaryPath = join2(temporaryRoot, `${randomUUID()}.mobileprovision`);
8825
+ const temporaryRoot = await mkdtemp2(join3(tmpdir2(), "ade-profile-"));
8826
+ const temporaryPath = join3(temporaryRoot, `${randomUUID()}.mobileprovision`);
8660
8827
  try {
8661
- await writeFile2(temporaryPath, content, { mode: 384 });
8828
+ await writeFile3(temporaryPath, content, { mode: 384 });
8662
8829
  const raw = await decodeProfile(temporaryPath, timeoutMs, signal);
8663
8830
  if (!raw) throw new Error("Provisioning profile is invalid or unsigned");
8664
8831
  const uuid = text(raw.UUID);
8665
8832
  if (!uuid) throw new Error("Provisioning profile UUID is missing");
8666
8833
  const directory = PROFILE_DIRECTORIES[0];
8667
8834
  await mkdir2(directory, { recursive: true, mode: 448 });
8668
- const destination = join2(directory, `${uuid}.mobileprovision`);
8669
- await writeFile2(destination, content, { mode: 384 });
8835
+ const destination = join3(directory, `${uuid}.mobileprovision`);
8836
+ await writeFile3(destination, content, { mode: 384 });
8670
8837
  return { ...successfulProcess, uuid };
8671
8838
  } finally {
8672
- await rm2(temporaryRoot, { recursive: true, force: true });
8839
+ await rm3(temporaryRoot, { recursive: true, force: true });
8673
8840
  }
8674
8841
  };
8675
8842
  var deleteSigningProfile = async (payload, timeoutMs, signal) => {
@@ -8679,7 +8846,7 @@ var deleteSigningProfile = async (payload, timeoutMs, signal) => {
8679
8846
  );
8680
8847
  for (const profile of matches) {
8681
8848
  signal.throwIfAborted();
8682
- await rm2(profile.path, { force: false });
8849
+ await rm3(profile.path, { force: false });
8683
8850
  }
8684
8851
  return { ...successfulProcess, uuid, deleted: matches.length };
8685
8852
  };
@@ -8693,10 +8860,10 @@ var importSigningIdentity = async (payload, timeoutMs, signal, _onLog, context)
8693
8860
  const hash = createHash3("sha256").update(p12).digest("hex").toUpperCase();
8694
8861
  if (hash !== input.sha256)
8695
8862
  throw new Error("Signing identity transfer changed");
8696
- const temporaryRoot = await mkdtemp(join2(tmpdir(), "ade-identity-"));
8697
- const path = join2(temporaryRoot, "identity.p12");
8863
+ const temporaryRoot = await mkdtemp2(join3(tmpdir2(), "ade-identity-"));
8864
+ const path = join3(temporaryRoot, "identity.p12");
8698
8865
  try {
8699
- await writeFile2(path, p12, { mode: 384 });
8866
+ await writeFile3(path, p12, { mode: 384 });
8700
8867
  const result = await captureCommand({
8701
8868
  command: "/usr/bin/security",
8702
8869
  args: [
@@ -8719,7 +8886,7 @@ var importSigningIdentity = async (payload, timeoutMs, signal, _onLog, context)
8719
8886
  }
8720
8887
  return { ...successfulProcess, sha256: input.sha256 };
8721
8888
  } finally {
8722
- await rm2(temporaryRoot, { recursive: true, force: true });
8889
+ await rm3(temporaryRoot, { recursive: true, force: true });
8723
8890
  }
8724
8891
  };
8725
8892
  var deleteSigningIdentity = async (payload, timeoutMs, signal) => {
@@ -8740,6 +8907,112 @@ var deleteSigningIdentity = async (payload, timeoutMs, signal) => {
8740
8907
 
8741
8908
  // src/handlers/ccusage.ts
8742
8909
  import { Buffer as Buffer2 } from "node:buffer";
8910
+
8911
+ // src/process-runner.ts
8912
+ import { spawn as spawn3 } from "node:child_process";
8913
+ async function runProcess(options) {
8914
+ return new Promise((resolve7, reject) => {
8915
+ let sequence = 0;
8916
+ let timedOut = false;
8917
+ let cancelled = false;
8918
+ let settled = false;
8919
+ let logChain = Promise.resolve();
8920
+ const detached = process.platform !== "win32";
8921
+ const child = spawn3(options.command, options.args, {
8922
+ shell: false,
8923
+ stdio: ["ignore", "pipe", "pipe"],
8924
+ cwd: options.cwd,
8925
+ env: options.env ?? process.env,
8926
+ // A separate process group lets cancellation terminate scripts and all
8927
+ // descendants instead of leaving a child holding stdout/stderr open.
8928
+ detached
8929
+ });
8930
+ const emit = (stream, message) => {
8931
+ const log = {
8932
+ sequence: sequence++,
8933
+ stream,
8934
+ message,
8935
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
8936
+ };
8937
+ logChain = logChain.then(async () => {
8938
+ try {
8939
+ await options.onLog(log);
8940
+ } catch (error) {
8941
+ console.error(
8942
+ `Could not append process log ${log.sequence}:`,
8943
+ error instanceof Error ? error.message : error
8944
+ );
8945
+ }
8946
+ });
8947
+ };
8948
+ const attach = (stream, kind) => {
8949
+ let remainder = "";
8950
+ stream.setEncoding("utf8");
8951
+ stream.on("data", (chunk) => {
8952
+ const parts = `${remainder}${chunk}`.split(/\r?\n/);
8953
+ remainder = parts.pop() ?? "";
8954
+ for (const line of parts) emit(kind, line);
8955
+ });
8956
+ stream.on("end", () => {
8957
+ if (remainder) emit(kind, remainder);
8958
+ });
8959
+ };
8960
+ attach(child.stdout, "STDOUT");
8961
+ attach(child.stderr, "STDERR");
8962
+ const sendSignal = (signal) => {
8963
+ if (detached && child.pid) {
8964
+ try {
8965
+ process.kill(-child.pid, signal);
8966
+ return;
8967
+ } catch (error) {
8968
+ if (!(error instanceof Error) || !("code" in error) || error.code !== "ESRCH") {
8969
+ throw error;
8970
+ }
8971
+ }
8972
+ }
8973
+ child.kill(signal);
8974
+ };
8975
+ const terminate = () => {
8976
+ if (child.exitCode !== null || child.killed) return;
8977
+ sendSignal("SIGTERM");
8978
+ const killTimer = setTimeout(() => sendSignal("SIGKILL"), 5e3);
8979
+ killTimer.unref();
8980
+ };
8981
+ const timeout = setTimeout(() => {
8982
+ timedOut = true;
8983
+ emit(
8984
+ "SYSTEM",
8985
+ `Process exceeded its ${Math.round(options.timeoutMs / 1e3)} second timeout`
8986
+ );
8987
+ terminate();
8988
+ }, options.timeoutMs);
8989
+ timeout.unref();
8990
+ const abort = () => {
8991
+ cancelled = true;
8992
+ emit("SYSTEM", "Cancellation requested");
8993
+ terminate();
8994
+ };
8995
+ options.signal.addEventListener("abort", abort, { once: true });
8996
+ child.once("error", (error) => {
8997
+ if (settled) return;
8998
+ settled = true;
8999
+ clearTimeout(timeout);
9000
+ options.signal.removeEventListener("abort", abort);
9001
+ reject(error);
9002
+ });
9003
+ child.once("close", (exitCode, signal) => {
9004
+ if (settled) return;
9005
+ settled = true;
9006
+ clearTimeout(timeout);
9007
+ options.signal.removeEventListener("abort", abort);
9008
+ void logChain.then(
9009
+ () => resolve7({ exitCode, signal, timedOut, cancelled })
9010
+ );
9011
+ });
9012
+ });
9013
+ }
9014
+
9015
+ // src/handlers/ccusage.ts
8743
9016
  var MAX_CCUSAGE_STDOUT_BYTES = 16 * 1024 * 1024;
8744
9017
  function validateCcusagePayload(payload) {
8745
9018
  if (!payload || typeof payload !== "object" || Array.isArray(payload)) {
@@ -8793,9 +9066,17 @@ async function runCcusage(payload, timeoutMs, signal, onLog) {
8793
9066
  }
8794
9067
 
8795
9068
  // src/handlers/build-data.ts
8796
- import { lstat, opendir, readdir as readdir2, realpath, rm as rm3 } from "node:fs/promises";
8797
- import { homedir as homedir3 } from "node:os";
8798
- import { basename as basename2, dirname as dirname2, isAbsolute, join as join3, resolve } from "node:path";
9069
+ import {
9070
+ lstat,
9071
+ opendir,
9072
+ readdir as readdir2,
9073
+ realpath as realpath2,
9074
+ rm as rm4,
9075
+ stat as stat3,
9076
+ statfs
9077
+ } from "node:fs/promises";
9078
+ import { homedir as homedir4 } from "node:os";
9079
+ import { basename as basename2, dirname as dirname2, isAbsolute, join as join4, resolve } from "node:path";
8799
9080
  var successfulProcess2 = {
8800
9081
  exitCode: 0,
8801
9082
  signal: null,
@@ -8812,7 +9093,7 @@ function safeRelativePath3(value) {
8812
9093
  }
8813
9094
  async function configuredRoots(payload) {
8814
9095
  if (payload.mode === "DEFAULT") {
8815
- return [join3(homedir3(), "Library", "Developer", "Xcode", "DerivedData")];
9096
+ return [join4(homedir4(), "Library", "Developer", "Xcode", "DerivedData")];
8816
9097
  }
8817
9098
  if (payload.mode === "ABSOLUTE") {
8818
9099
  if (!payload.path || !isAbsolute(payload.path)) {
@@ -8849,7 +9130,7 @@ async function scanRoot(configuredRoot, timeoutMs, signal) {
8849
9130
  signal.throwIfAborted();
8850
9131
  let rootPath2;
8851
9132
  try {
8852
- rootPath2 = await realpath(configuredRoot);
9133
+ rootPath2 = await realpath2(configuredRoot);
8853
9134
  } catch (error) {
8854
9135
  if (error.code === "ENOENT") {
8855
9136
  return { entries: [], warning: null };
@@ -8869,12 +9150,15 @@ async function scanRoot(configuredRoot, timeoutMs, signal) {
8869
9150
  };
8870
9151
  }
8871
9152
  const entries = [];
9153
+ const rootStats = await stat3(rootPath2);
9154
+ const volumeId = String(rootStats.dev);
8872
9155
  for (const child of children) {
8873
9156
  signal.throwIfAborted();
8874
9157
  if (!child.isDirectory()) continue;
8875
- const path = join3(rootPath2, child.name);
9158
+ const path = join4(rootPath2, child.name);
9159
+ const information = await lstat(path);
8876
9160
  const projectPath = await workspacePath(
8877
- join3(path, "info.plist"),
9161
+ join4(path, "info.plist"),
8878
9162
  timeoutMs,
8879
9163
  signal
8880
9164
  );
@@ -8883,21 +9167,23 @@ async function scanRoot(configuredRoot, timeoutMs, signal) {
8883
9167
  rootPath: rootPath2,
8884
9168
  name: child.name,
8885
9169
  kind: projectPath ? "PROJECT" : child.name.toLocaleLowerCase().endsWith(".noindex") ? "SHARED_CACHE" : "PENDING",
8886
- workspacePath: projectPath
9170
+ workspacePath: projectPath,
9171
+ modifiedAt: information.mtime.toISOString(),
9172
+ volumeId
8887
9173
  });
8888
9174
  }
8889
9175
  entries.sort((first, second) => first.name.localeCompare(second.name));
8890
9176
  return { entries, warning: null };
8891
9177
  }
8892
9178
  async function scanDeviceSupport(signal) {
8893
- const configuredRoot = join3(
8894
- process.env.ADE_IOS_DEVICE_SUPPORT_DIRECTORY ?? homedir3(),
9179
+ const configuredRoot = join4(
9180
+ process.env.ADE_IOS_DEVICE_SUPPORT_DIRECTORY ?? homedir4(),
8895
9181
  ...process.env.ADE_IOS_DEVICE_SUPPORT_DIRECTORY ? [] : ["Library", "Developer", "Xcode", "iOS DeviceSupport"]
8896
9182
  );
8897
9183
  signal.throwIfAborted();
8898
9184
  let rootPath2;
8899
9185
  try {
8900
- rootPath2 = await realpath(configuredRoot);
9186
+ rootPath2 = await realpath2(configuredRoot);
8901
9187
  } catch (error) {
8902
9188
  if (error.code === "ENOENT") {
8903
9189
  return { entries: [], warning: null };
@@ -8911,11 +9197,13 @@ async function scanDeviceSupport(signal) {
8911
9197
  const children = await readdir2(rootPath2, { withFileTypes: true });
8912
9198
  return {
8913
9199
  entries: children.filter((child) => child.isDirectory() && !child.isSymbolicLink()).map((child) => ({
8914
- path: join3(rootPath2, child.name),
9200
+ path: join4(rootPath2, child.name),
8915
9201
  rootPath: rootPath2,
8916
9202
  name: child.name,
8917
9203
  kind: "DEVICE_SUPPORT",
8918
- workspacePath: null
9204
+ workspacePath: null,
9205
+ modifiedAt: null,
9206
+ volumeId: null
8919
9207
  })).sort((first, second) => first.name.localeCompare(second.name)),
8920
9208
  warning: null
8921
9209
  };
@@ -8936,7 +9224,7 @@ var scanBuildData = async (rawPayload, timeoutMs, signal) => {
8936
9224
  signal.throwIfAborted();
8937
9225
  let canonical = root;
8938
9226
  try {
8939
- canonical = await realpath(root);
9227
+ canonical = await realpath2(root);
8940
9228
  } catch {
8941
9229
  }
8942
9230
  if (canonicalRoots.has(canonical)) continue;
@@ -8970,7 +9258,7 @@ async function allocatedBytes(path, signal) {
8970
9258
  try {
8971
9259
  for await (const entry of directory) {
8972
9260
  signal.throwIfAborted();
8973
- total += await allocatedBytes(join3(path, entry.name), signal);
9261
+ total += await allocatedBytes(join4(path, entry.name), signal);
8974
9262
  }
8975
9263
  } finally {
8976
9264
  await directory.close().catch(() => void 0);
@@ -8984,7 +9272,7 @@ var sizeBuildData = async (rawPayload, _timeoutMs, signal) => {
8984
9272
  signal.throwIfAborted();
8985
9273
  try {
8986
9274
  assertDirectChild(target2.rootPath, target2.path);
8987
- const rootPath2 = await realpath(target2.rootPath);
9275
+ const rootPath2 = await realpath2(target2.rootPath);
8988
9276
  if (rootPath2 !== resolve(target2.rootPath) || dirname2(resolve(target2.path)) !== rootPath2) {
8989
9277
  throw new Error("Build Data root changed since the scan");
8990
9278
  }
@@ -9009,13 +9297,13 @@ var sizeBuildData = async (rawPayload, _timeoutMs, signal) => {
9009
9297
  return { ...successfulProcess2, sizes };
9010
9298
  };
9011
9299
  var deleteBuildData = async (rawPayload, _timeoutMs, signal) => {
9012
- const payload = buildDataTargetsPayload(rawPayload);
9300
+ const payload = buildDataDeletePayload(rawPayload);
9013
9301
  const deleted = [];
9014
9302
  for (const target2 of payload.targets) {
9015
9303
  signal.throwIfAborted();
9016
9304
  try {
9017
9305
  assertDirectChild(target2.rootPath, target2.path);
9018
- const rootPath2 = await realpath(target2.rootPath);
9306
+ const rootPath2 = await realpath2(target2.rootPath);
9019
9307
  if (rootPath2 !== resolve(target2.rootPath) || dirname2(resolve(target2.path)) !== rootPath2) {
9020
9308
  throw new Error("Build Data root changed since the scan");
9021
9309
  }
@@ -9023,7 +9311,7 @@ var deleteBuildData = async (rawPayload, _timeoutMs, signal) => {
9023
9311
  if (!stats.isDirectory() || stats.isSymbolicLink()) {
9024
9312
  throw new Error("Build Data target is not a directory");
9025
9313
  }
9026
- await rm3(target2.path, { recursive: true, force: false, maxRetries: 3 });
9314
+ await rm4(target2.path, { recursive: true, force: false, maxRetries: 3 });
9027
9315
  deleted.push({ path: target2.path, deleted: true, error: null });
9028
9316
  } catch (error) {
9029
9317
  signal.throwIfAborted();
@@ -9036,11 +9324,122 @@ var deleteBuildData = async (rawPayload, _timeoutMs, signal) => {
9036
9324
  }
9037
9325
  return { ...successfulProcess2, deleted };
9038
9326
  };
9327
+ async function sharedCapacityId(canonicalPath, volumeId, signal) {
9328
+ try {
9329
+ const result = await captureCommand({
9330
+ command: "/usr/sbin/diskutil",
9331
+ args: ["info", "-plist", canonicalPath],
9332
+ timeoutMs: 5e3,
9333
+ signal
9334
+ });
9335
+ signal.throwIfAborted();
9336
+ if (result.exitCode !== 0) return volumeId;
9337
+ const information = parsePlist(result.stdout);
9338
+ if (!information || typeof information !== "object") return volumeId;
9339
+ const container = information.APFSContainerReference;
9340
+ return typeof container === "string" && container.trim() ? `apfs:${container.trim()}` : volumeId;
9341
+ } catch {
9342
+ signal.throwIfAborted();
9343
+ return volumeId;
9344
+ }
9345
+ }
9346
+ async function inspectVolume(configuredPath, role, signal) {
9347
+ signal.throwIfAborted();
9348
+ const canonicalPath = await realpath2(configuredPath);
9349
+ const [information, filesystem] = await Promise.all([
9350
+ stat3(canonicalPath),
9351
+ statfs(canonicalPath, { bigint: true })
9352
+ ]);
9353
+ const id2 = String(information.dev);
9354
+ return {
9355
+ canonicalPath,
9356
+ volume: {
9357
+ id: id2,
9358
+ capacityId: id2,
9359
+ totalBytes: Number(filesystem.blocks * filesystem.bsize),
9360
+ freeBytes: Number(filesystem.bavail * filesystem.bsize),
9361
+ roles: /* @__PURE__ */ new Set([role]),
9362
+ paths: /* @__PURE__ */ new Set([canonicalPath])
9363
+ }
9364
+ };
9365
+ }
9366
+ async function collectAgentDiskSpace(configuration, signal) {
9367
+ const scanPayload = buildDataScanPayload({
9368
+ mode: configuration.derivedDataLocationMode,
9369
+ path: configuration.derivedDataPath,
9370
+ worktrees: configuration.worktrees
9371
+ });
9372
+ const roots = await configuredRoots(scanPayload);
9373
+ const requested = [
9374
+ { path: "/", role: "MAIN" },
9375
+ ...configuration.baseRepoDirectory ? [{ path: configuration.baseRepoDirectory, role: "BASE_REPO" }] : [],
9376
+ ...roots.map((path) => ({ path, role: "DERIVED_DATA" }))
9377
+ ];
9378
+ const warnings = [];
9379
+ const volumes = /* @__PURE__ */ new Map();
9380
+ for (const request of requested) {
9381
+ signal.throwIfAborted();
9382
+ try {
9383
+ const inspected = await inspectVolume(request.path, request.role, signal);
9384
+ const existing = volumes.get(inspected.volume.id);
9385
+ if (existing) {
9386
+ existing.roles.add(request.role);
9387
+ existing.paths.add(inspected.canonicalPath);
9388
+ existing.totalBytes = inspected.volume.totalBytes;
9389
+ existing.freeBytes = inspected.volume.freeBytes;
9390
+ } else {
9391
+ inspected.volume.capacityId = await sharedCapacityId(
9392
+ inspected.canonicalPath,
9393
+ inspected.volume.id,
9394
+ signal
9395
+ );
9396
+ volumes.set(inspected.volume.id, inspected.volume);
9397
+ }
9398
+ } catch (error) {
9399
+ warnings.push(`${request.path}: ${errorMessage(error)}`);
9400
+ }
9401
+ }
9402
+ const entries = [];
9403
+ const scannedRoots = /* @__PURE__ */ new Set();
9404
+ for (const root of roots) {
9405
+ signal.throwIfAborted();
9406
+ let canonical = root;
9407
+ try {
9408
+ canonical = await realpath2(root);
9409
+ } catch {
9410
+ }
9411
+ if (scannedRoots.has(canonical)) continue;
9412
+ scannedRoots.add(canonical);
9413
+ const result = await scanRoot(root, 45e3, signal);
9414
+ if (result.warning) warnings.push(result.warning);
9415
+ for (const entry of result.entries) {
9416
+ if (!entry.modifiedAt || !entry.volumeId) continue;
9417
+ entries.push({
9418
+ ...entry,
9419
+ modifiedAt: entry.modifiedAt,
9420
+ volumeId: entry.volumeId
9421
+ });
9422
+ }
9423
+ }
9424
+ return {
9425
+ observedAt: (/* @__PURE__ */ new Date()).toISOString(),
9426
+ volumes: [...volumes.values()].map((volume) => ({
9427
+ id: volume.id,
9428
+ capacityId: volume.capacityId,
9429
+ totalBytes: volume.totalBytes,
9430
+ freeBytes: volume.freeBytes,
9431
+ roles: [...volume.roles],
9432
+ paths: [...volume.paths]
9433
+ })),
9434
+ entries,
9435
+ warnings: [...new Set(warnings)]
9436
+ };
9437
+ }
9039
9438
 
9040
9439
  // src/handlers/codebases.ts
9041
- import { readdir as readdir3, realpath as realpath2, stat as stat3 } from "node:fs/promises";
9042
- import { homedir as homedir4 } from "node:os";
9043
- import { dirname as dirname3, join as join4, resolve as resolve2 } from "node:path";
9440
+ import { readdir as readdir3, realpath as realpath3, stat as stat4 } from "node:fs/promises";
9441
+ import { homedir as homedir5 } from "node:os";
9442
+ import { dirname as dirname3, join as join5, resolve as resolve2 } from "node:path";
9044
9443
  var successfulProcess3 = {
9045
9444
  exitCode: 0,
9046
9445
  signal: null,
@@ -9117,7 +9516,7 @@ function baseSnapshot(folder) {
9117
9516
  }
9118
9517
  async function fetchedAt(commonDirectory) {
9119
9518
  try {
9120
- return (await stat3(join4(commonDirectory, "FETCH_HEAD"))).mtime.toISOString();
9519
+ return (await stat4(join5(commonDirectory, "FETCH_HEAD"))).mtime.toISOString();
9121
9520
  } catch {
9122
9521
  return null;
9123
9522
  }
@@ -9127,8 +9526,8 @@ async function inspectCodebaseProcess(selectedFolder, timeoutMs, signal, expecte
9127
9526
  const base = baseSnapshot(fallbackFolder);
9128
9527
  let selected;
9129
9528
  try {
9130
- selected = await realpath2(fallbackFolder);
9131
- if (!(await stat3(selected)).isDirectory())
9529
+ selected = await realpath3(fallbackFolder);
9530
+ if (!(await stat4(selected)).isDirectory())
9132
9531
  throw new Error("Folder is not a directory");
9133
9532
  } catch (error) {
9134
9533
  return {
@@ -9160,7 +9559,7 @@ async function inspectCodebaseProcess(selectedFolder, timeoutMs, signal, expecte
9160
9559
  }
9161
9560
  };
9162
9561
  }
9163
- const folder = await realpath2(rootResult.stdout.trim());
9562
+ const folder = await realpath3(rootResult.stdout.trim());
9164
9563
  const bare = await git(
9165
9564
  folder,
9166
9565
  ["rev-parse", "--is-bare-repository"],
@@ -9211,8 +9610,8 @@ async function inspectCodebaseProcess(selectedFolder, timeoutMs, signal, expecte
9211
9610
  };
9212
9611
  }
9213
9612
  const origin2 = normalizeGitOrigin(originResult.stdout.trim());
9214
- const gitDirectory2 = await realpath2(gitDirectoryResult.stdout.trim());
9215
- const commonDirectory = await realpath2(commonDirectoryResult.stdout.trim());
9613
+ const gitDirectory2 = await realpath3(gitDirectoryResult.stdout.trim());
9614
+ const commonDirectory = await realpath3(commonDirectoryResult.stdout.trim());
9216
9615
  const linkedWorktree = gitDirectory2 !== commonDirectory;
9217
9616
  const branchResult = await git(
9218
9617
  folder,
@@ -9296,9 +9695,9 @@ async function inspectCodebase(selectedFolder, timeoutMs, signal, expectedOrigin
9296
9695
  }
9297
9696
  var browseCodebaseDirectories = async (payload) => {
9298
9697
  const input = codebaseBrowsePayload(payload);
9299
- const homePath = await realpath2(homedir4());
9300
- const path = await realpath2(input.path ? resolve2(input.path) : homePath);
9301
- if (!(await stat3(path)).isDirectory())
9698
+ const homePath = await realpath3(homedir5());
9699
+ const path = await realpath3(input.path ? resolve2(input.path) : homePath);
9700
+ if (!(await stat4(path)).isDirectory())
9302
9701
  throw new Error("Path is not a directory");
9303
9702
  const candidates = await readdir3(path, { withFileTypes: true });
9304
9703
  const entries = [];
@@ -9306,13 +9705,13 @@ var browseCodebaseDirectories = async (payload) => {
9306
9705
  if (candidate.isDirectory()) {
9307
9706
  entries.push({
9308
9707
  name: candidate.name,
9309
- path: join4(path, candidate.name),
9708
+ path: join5(path, candidate.name),
9310
9709
  hidden: candidate.name.startsWith(".")
9311
9710
  });
9312
9711
  } else if (candidate.isSymbolicLink()) {
9313
9712
  try {
9314
- const target2 = join4(path, candidate.name);
9315
- if ((await stat3(target2)).isDirectory()) {
9713
+ const target2 = join5(path, candidate.name);
9714
+ if ((await stat4(target2)).isDirectory()) {
9316
9715
  entries.push({
9317
9716
  name: candidate.name,
9318
9717
  path: target2,
@@ -9913,19 +10312,19 @@ import { execFile } from "node:child_process";
9913
10312
  import { randomUUID as randomUUID2 } from "node:crypto";
9914
10313
  import {
9915
10314
  access,
9916
- chmod as chmod2,
10315
+ chmod as chmod3,
9917
10316
  lstat as lstat2,
9918
10317
  mkdir as mkdir3,
9919
10318
  readFile as readFile3,
9920
- realpath as realpath3,
10319
+ realpath as realpath4,
9921
10320
  readdir as readdir4,
9922
10321
  rename as rename2,
9923
- rm as rm4,
9924
- stat as stat4,
9925
- writeFile as writeFile3
10322
+ rm as rm5,
10323
+ stat as stat5,
10324
+ writeFile as writeFile4
9926
10325
  } from "node:fs/promises";
9927
- import { homedir as homedir5 } from "node:os";
9928
- import { dirname as dirname4, isAbsolute as isAbsolute2, join as join5, relative as relative2, resolve as resolve3, sep as sep2 } from "node:path";
10326
+ import { homedir as homedir6 } from "node:os";
10327
+ import { dirname as dirname4, isAbsolute as isAbsolute2, join as join6, relative as relative2, resolve as resolve3, sep as sep2 } from "node:path";
9929
10328
  import { promisify } from "node:util";
9930
10329
  var executeFile = promisify(execFile);
9931
10330
  var successfulProcess4 = {
@@ -9980,23 +10379,23 @@ var PROJECT_ROOTS = {
9980
10379
  };
9981
10380
  async function directoryExists(path) {
9982
10381
  try {
9983
- return (await stat4(path)).isDirectory();
10382
+ return (await stat5(path)).isDirectory();
9984
10383
  } catch {
9985
10384
  return false;
9986
10385
  }
9987
10386
  }
9988
10387
  async function configuredTools(tools) {
9989
- const homePath = homedir5();
10388
+ const homePath = homedir6();
9990
10389
  return Promise.all(
9991
10390
  AI_TOOLS.filter((tool) => tools.includes(tool)).map(async (tool) => ({
9992
10391
  tool,
9993
- configured: await directoryExists(join5(homePath, ...CONFIG_PATHS[tool])),
10392
+ configured: await directoryExists(join6(homePath, ...CONFIG_PATHS[tool])),
9994
10393
  homePath
9995
10394
  }))
9996
10395
  );
9997
10396
  }
9998
10397
  function rootPath(location) {
9999
- const base = location.scope === "GLOBAL" ? homedir5() : location.folder;
10398
+ const base = location.scope === "GLOBAL" ? homedir6() : location.folder;
10000
10399
  const parts = location.scope === "GLOBAL" ? GLOBAL_ROOTS[location.rootKind] : PROJECT_ROOTS[location.rootKind];
10001
10400
  const path = resolve3(base, ...parts);
10002
10401
  const normalizedBase = resolve3(base);
@@ -10013,7 +10412,7 @@ async function listPackageFiles(skillDirectory) {
10013
10412
  let totalBytes = 0;
10014
10413
  const visit = async (directory) => {
10015
10414
  for (const entry of await readdir4(directory, { withFileTypes: true })) {
10016
- const path = join5(directory, entry.name);
10415
+ const path = join6(directory, entry.name);
10017
10416
  const metadata = await lstat2(path);
10018
10417
  if (metadata.isSymbolicLink()) {
10019
10418
  throw new Error(
@@ -10049,7 +10448,7 @@ async function readPackage(directory) {
10049
10448
  const metadata = await lstat2(directory);
10050
10449
  let resolvedDirectory = directory;
10051
10450
  if (metadata.isSymbolicLink()) {
10052
- resolvedDirectory = await realpath3(directory);
10451
+ resolvedDirectory = await realpath4(directory);
10053
10452
  } else if (!metadata.isDirectory()) {
10054
10453
  throw new Error("Skill path is not a directory");
10055
10454
  }
@@ -10102,7 +10501,7 @@ async function scanRoot2(location, configured, targets, warnings) {
10102
10501
  const installations = [];
10103
10502
  for (const entry of await readdir4(root, { withFileTypes: true })) {
10104
10503
  if (!entry.isDirectory() && !entry.isSymbolicLink()) continue;
10105
- const directory = join5(root, entry.name);
10504
+ const directory = join6(root, entry.name);
10106
10505
  try {
10107
10506
  const skillPackage = await readPackage(directory);
10108
10507
  const relativeDirectory = location.folder ? relative2(location.folder, directory).split(sep2).join("/") : "";
@@ -10181,7 +10580,7 @@ var readSkills = async (payload) => {
10181
10580
  }
10182
10581
  packages.push({
10183
10582
  ...request,
10184
- package: await readPackage(join5(root, request.skillName))
10583
+ package: await readPackage(join6(root, request.skillName))
10185
10584
  });
10186
10585
  }
10187
10586
  return { ...successfulProcess4, packages };
@@ -10222,7 +10621,7 @@ async function updateManagedExclude(folder, relativeSkillPath, present) {
10222
10621
  const block = managed.size ? `${MANAGED_EXCLUDE_START}
10223
10622
  ${[...managed].sort().join("\n")}
10224
10623
  ${MANAGED_EXCLUDE_END}` : "";
10225
- await writeFile3(
10624
+ await writeFile4(
10226
10625
  excludePath,
10227
10626
  `${[before, block, after].filter(Boolean).join("\n\n")}
10228
10627
  `,
@@ -10243,11 +10642,11 @@ async function writePackage(location, skillPackage) {
10243
10642
  throw new Error("New skill copies may only be written to shared roots");
10244
10643
  }
10245
10644
  const root = rootPath(location);
10246
- const destination = join5(root, skillPackage.name);
10645
+ const destination = join6(root, skillPackage.name);
10247
10646
  await assertUntracked(location, destination);
10248
10647
  await mkdir3(root, { recursive: true });
10249
- const temporary = join5(root, `.${skillPackage.name}.${randomUUID2()}.tmp`);
10250
- const backup = join5(root, `.${skillPackage.name}.${randomUUID2()}.bak`);
10648
+ const temporary = join6(root, `.${skillPackage.name}.${randomUUID2()}.tmp`);
10649
+ const backup = join6(root, `.${skillPackage.name}.${randomUUID2()}.bak`);
10251
10650
  await mkdir3(temporary, { recursive: true });
10252
10651
  try {
10253
10652
  for (const file of skillPackage.files) {
@@ -10255,8 +10654,8 @@ async function writePackage(location, skillPackage) {
10255
10654
  if (!path.startsWith(`${temporary}${sep2}`))
10256
10655
  throw new Error("Skill file escaped temporary directory");
10257
10656
  await mkdir3(dirname4(path), { recursive: true });
10258
- await writeFile3(path, Buffer.from(file.contentsBase64, "base64"));
10259
- await chmod2(path, file.executable ? 493 : 420);
10657
+ await writeFile4(path, Buffer.from(file.contentsBase64, "base64"));
10658
+ await chmod3(path, file.executable ? 493 : 420);
10260
10659
  }
10261
10660
  let hadDestination = false;
10262
10661
  try {
@@ -10268,14 +10667,14 @@ async function writePackage(location, skillPackage) {
10268
10667
  }
10269
10668
  try {
10270
10669
  await rename2(temporary, destination);
10271
- if (hadDestination) await rm4(backup, { recursive: true, force: true });
10670
+ if (hadDestination) await rm5(backup, { recursive: true, force: true });
10272
10671
  } catch (error) {
10273
10672
  if (hadDestination) await rename2(backup, destination);
10274
10673
  throw error;
10275
10674
  }
10276
10675
  } finally {
10277
- await rm4(temporary, { recursive: true, force: true });
10278
- await rm4(backup, { recursive: true, force: true });
10676
+ await rm5(temporary, { recursive: true, force: true });
10677
+ await rm5(backup, { recursive: true, force: true });
10279
10678
  }
10280
10679
  return destination;
10281
10680
  }
@@ -10285,7 +10684,7 @@ var applySkills = async (payload) => {
10285
10684
  for (const operation of operations) {
10286
10685
  const root = rootPath(operation);
10287
10686
  const skillName = operation.kind === "WRITE" ? operation.package.name : operation.skillName;
10288
- const destination = join5(root, skillName);
10687
+ const destination = join6(root, skillName);
10289
10688
  await assertUntracked(operation, destination);
10290
10689
  if (operation.kind === "WRITE") {
10291
10690
  await writePackage(operation, operation.package);
@@ -10295,7 +10694,7 @@ var applySkills = async (payload) => {
10295
10694
  packageHash: operation.package.packageHash
10296
10695
  });
10297
10696
  } else {
10298
- await rm4(destination, { recursive: true, force: true });
10697
+ await rm5(destination, { recursive: true, force: true });
10299
10698
  results.push({
10300
10699
  kind: operation.kind,
10301
10700
  path: destination,
@@ -10314,9 +10713,9 @@ var applySkills = async (payload) => {
10314
10713
  };
10315
10714
 
10316
10715
  // src/handlers/runs.ts
10317
- import { readFile as readFile4, readdir as readdir5, stat as stat5 } from "node:fs/promises";
10318
- import { homedir as homedir6 } from "node:os";
10319
- import { join as join6 } from "node:path";
10716
+ import { readFile as readFile4, readdir as readdir5, stat as stat6 } from "node:fs/promises";
10717
+ import { homedir as homedir7 } from "node:os";
10718
+ import { join as join7 } from "node:path";
10320
10719
  var successfulProcess5 = {
10321
10720
  exitCode: 0,
10322
10721
  signal: null,
@@ -10325,13 +10724,13 @@ var successfulProcess5 = {
10325
10724
  };
10326
10725
  async function fileExists(path) {
10327
10726
  try {
10328
- return (await stat5(path)).isFile();
10727
+ return (await stat6(path)).isFile();
10329
10728
  } catch {
10330
10729
  return false;
10331
10730
  }
10332
10731
  }
10333
10732
  async function findClaudeSessionFile(nativeId, home) {
10334
- const projectsDir = join6(home, ".claude", "projects");
10733
+ const projectsDir = join7(home, ".claude", "projects");
10335
10734
  let entries;
10336
10735
  try {
10337
10736
  entries = await readdir5(projectsDir, { withFileTypes: true });
@@ -10341,13 +10740,13 @@ async function findClaudeSessionFile(nativeId, home) {
10341
10740
  const target2 = `${nativeId}.jsonl`;
10342
10741
  for (const entry of entries) {
10343
10742
  if (!entry.isDirectory()) continue;
10344
- const candidate = join6(projectsDir, entry.name, target2);
10743
+ const candidate = join7(projectsDir, entry.name, target2);
10345
10744
  if (await fileExists(candidate)) return candidate;
10346
10745
  }
10347
10746
  return null;
10348
10747
  }
10349
10748
  async function findCodexSessionFile(nativeId, home) {
10350
- const sessionsDir = join6(home, ".codex", "sessions");
10749
+ const sessionsDir = join7(home, ".codex", "sessions");
10351
10750
  const suffix = `-${nativeId}.jsonl`;
10352
10751
  const walk = async (dir) => {
10353
10752
  let entries;
@@ -10357,7 +10756,7 @@ async function findCodexSessionFile(nativeId, home) {
10357
10756
  return null;
10358
10757
  }
10359
10758
  for (const entry of entries) {
10360
- const path = join6(dir, entry.name);
10759
+ const path = join7(dir, entry.name);
10361
10760
  if (entry.isDirectory()) {
10362
10761
  const found = await walk(path);
10363
10762
  if (found) return found;
@@ -10374,13 +10773,13 @@ async function locateSessionFile(payload, home) {
10374
10773
  }
10375
10774
  var readRunSession = async (payload) => {
10376
10775
  const input = parseRunSessionReadPayload(payload);
10377
- const path = await locateSessionFile(input, homedir6());
10776
+ const path = await locateSessionFile(input, homedir7());
10378
10777
  if (!path) {
10379
10778
  throw new Error(
10380
10779
  `No ${input.provider === "CLAUDE" ? "Claude" : "Codex"} session file found for this run on this agent`
10381
10780
  );
10382
10781
  }
10383
- const { size } = await stat5(path);
10782
+ const { size } = await stat6(path);
10384
10783
  if (size > MAX_RUN_SESSION_FILE_BYTES) {
10385
10784
  throw new Error(
10386
10785
  `Session file is too large to export (${size} bytes exceeds the ${MAX_RUN_SESSION_FILE_BYTES} byte limit)`
@@ -10396,21 +10795,21 @@ var readRunSession = async (payload) => {
10396
10795
 
10397
10796
  // src/handlers/workflows.ts
10398
10797
  import {
10399
- mkdtemp as mkdtemp4,
10798
+ mkdtemp as mkdtemp5,
10400
10799
  readFile as readFile6,
10401
- realpath as realpath5,
10402
- rm as rm7,
10403
- stat as stat7,
10404
- writeFile as writeFile5
10800
+ realpath as realpath6,
10801
+ rm as rm8,
10802
+ stat as stat8,
10803
+ writeFile as writeFile6
10405
10804
  } from "node:fs/promises";
10406
- import { tmpdir as tmpdir4 } from "node:os";
10407
- import { join as join9 } from "node:path";
10805
+ import { tmpdir as tmpdir5 } from "node:os";
10806
+ import { join as join10 } from "node:path";
10408
10807
 
10409
10808
  // src/runs/git-checkpoint.ts
10410
10809
  import { execFile as execFile2 } from "node:child_process";
10411
- import { copyFile, mkdtemp as mkdtemp2, rm as rm5 } from "node:fs/promises";
10412
- import { tmpdir as tmpdir2 } from "node:os";
10413
- import { join as join7 } from "node:path";
10810
+ import { copyFile, mkdtemp as mkdtemp3, rm as rm6 } from "node:fs/promises";
10811
+ import { tmpdir as tmpdir3 } from "node:os";
10812
+ import { join as join8 } from "node:path";
10414
10813
  import { promisify as promisify2 } from "node:util";
10415
10814
  var execFileAsync = promisify2(execFile2);
10416
10815
  async function git2(cwd, args, env) {
@@ -10525,12 +10924,12 @@ async function captureGitCheckpoint(cwd, runId, kind) {
10525
10924
  const manifest = await optionalGit(cwd, ["status", "--porcelain=v2", "-z"]);
10526
10925
  const staged = await optionalGit(cwd, ["diff", "--cached", "--stat", "HEAD"]);
10527
10926
  const unstaged = await optionalGit(cwd, ["diff", "--stat", "HEAD"]);
10528
- const directory = await mkdtemp2(join7(tmpdir2(), "aide-run-index-"));
10927
+ const directory = await mkdtemp3(join8(tmpdir3(), "aide-run-index-"));
10529
10928
  let worktreeTree = null;
10530
10929
  let refName = null;
10531
10930
  try {
10532
10931
  const actualIndex = await git2(cwd, ["rev-parse", "--git-path", "index"]);
10533
- const temporaryIndex = join7(directory, "index");
10932
+ const temporaryIndex = join8(directory, "index");
10534
10933
  try {
10535
10934
  await copyFile(actualIndex, temporaryIndex);
10536
10935
  } catch {
@@ -10562,7 +10961,7 @@ async function captureGitCheckpoint(cwd, runId, kind) {
10562
10961
  refName = `refs/aide/runs/${runId}/${Date.now()}-${kind.toLowerCase()}`;
10563
10962
  await git2(cwd, ["update-ref", refName, checkpointCommit]);
10564
10963
  } finally {
10565
- await rm5(directory, { recursive: true, force: true });
10964
+ await rm6(directory, { recursive: true, force: true });
10566
10965
  }
10567
10966
  return {
10568
10967
  kind,
@@ -10591,36 +10990,37 @@ import { createHash as createHash5, randomUUID as randomUUID3 } from "node:crypt
10591
10990
  import {
10592
10991
  cp,
10593
10992
  mkdir as mkdir4,
10594
- mkdtemp as mkdtemp3,
10993
+ mkdtemp as mkdtemp4,
10595
10994
  open,
10596
10995
  readdir as readdir6,
10597
10996
  readFile as readFile5,
10598
- realpath as realpath4,
10997
+ realpath as realpath5,
10599
10998
  rename as rename3,
10600
- rm as rm6,
10601
- stat as stat6,
10602
- writeFile as writeFile4
10999
+ rm as rm7,
11000
+ stat as stat7,
11001
+ writeFile as writeFile5
10603
11002
  } from "node:fs/promises";
10604
11003
  import { createReadStream as createReadStream3, createWriteStream } from "node:fs";
10605
- import { tmpdir as tmpdir3 } from "node:os";
11004
+ import { tmpdir as tmpdir4 } from "node:os";
10606
11005
  import { pipeline } from "node:stream/promises";
11006
+ import { StringDecoder } from "node:string_decoder";
10607
11007
  import {
10608
11008
  basename as basename3,
10609
11009
  dirname as dirname5,
10610
11010
  isAbsolute as isAbsolute4,
10611
- join as join8,
11011
+ join as join9,
10612
11012
  relative as relative4,
10613
11013
  resolve as resolve5,
10614
11014
  sep as sep4
10615
11015
  } from "node:path";
10616
- import { spawn as spawn4 } from "node:child_process";
11016
+ import { spawn as spawn5 } from "node:child_process";
10617
11017
 
10618
11018
  // src/git-code-state.ts
10619
11019
  import { createHash as createHash4 } from "node:crypto";
10620
11020
  import { createReadStream as createReadStream2 } from "node:fs";
10621
11021
  import { lstat as lstat3, readlink } from "node:fs/promises";
10622
11022
  import { isAbsolute as isAbsolute3, relative as relative3, resolve as resolve4, sep as sep3 } from "node:path";
10623
- import { spawn as spawn3 } from "node:child_process";
11023
+ import { spawn as spawn4 } from "node:child_process";
10624
11024
  function gitEnvironment() {
10625
11025
  return {
10626
11026
  ...process.env,
@@ -10643,7 +11043,7 @@ function hashGitDiff(hash, folder, timeoutMs, signal) {
10643
11043
  return new Promise((resolveResult, reject) => {
10644
11044
  let settled = false;
10645
11045
  let timedOut = false;
10646
- const child = spawn3(
11046
+ const child = spawn4(
10647
11047
  "git",
10648
11048
  [
10649
11049
  "-C",
@@ -10862,8 +11262,8 @@ function requireSuccess2(result, fallback) {
10862
11262
  return result;
10863
11263
  }
10864
11264
  async function validateWorktree(input, timeoutMs, signal) {
10865
- const folder = await realpath4(input.folder);
10866
- if (!(await stat6(folder)).isDirectory())
11265
+ const folder = await realpath5(input.folder);
11266
+ if (!(await stat7(folder)).isDirectory())
10867
11267
  throw new Error("Worktree is missing");
10868
11268
  const gitDirectory2 = requireSuccess2(
10869
11269
  await command(
@@ -10876,7 +11276,7 @@ async function validateWorktree(input, timeoutMs, signal) {
10876
11276
  ),
10877
11277
  "Could not resolve the worktree Git directory"
10878
11278
  ).stdout.trim();
10879
- if (await realpath4(gitDirectory2) !== input.gitDirectory) {
11279
+ if (await realpath5(gitDirectory2) !== input.gitDirectory) {
10880
11280
  throw new Error("Worktree identity changed; refresh the page");
10881
11281
  }
10882
11282
  const origin2 = requireSuccess2(
@@ -10905,12 +11305,12 @@ function containedPath2(root, relativePath) {
10905
11305
  }
10906
11306
  async function validateSource(root, source) {
10907
11307
  const target2 = containedPath2(root, source.relativePath);
10908
- const resolved = await realpath4(target2);
11308
+ const resolved = await realpath5(target2);
10909
11309
  const difference = relative4(root, resolved);
10910
11310
  if (difference === ".." || difference.startsWith(`..${sep4}`) || isAbsolute4(difference)) {
10911
11311
  throw new Error("Build source resolves outside the worktree");
10912
11312
  }
10913
- const information = await stat6(resolved);
11313
+ const information = await stat7(resolved);
10914
11314
  if (source.kind === "PACKAGE" && !information.isFile()) {
10915
11315
  throw new Error("Package.swift is missing");
10916
11316
  }
@@ -10926,7 +11326,7 @@ async function discoverSourcesInFolder(folder) {
10926
11326
  const current = queue.shift();
10927
11327
  for (const entry of await readdir6(current, { withFileTypes: true })) {
10928
11328
  if (entry.isSymbolicLink()) continue;
10929
- const absolute = join8(current, entry.name);
11329
+ const absolute = join9(current, entry.name);
10930
11330
  const path = relative4(folder, absolute).split(sep4).join("/");
10931
11331
  if (entry.isDirectory()) {
10932
11332
  if (entry.name.endsWith(".xcodeproj")) {
@@ -10997,7 +11397,7 @@ function metadataFromList(value) {
10997
11397
  };
10998
11398
  }
10999
11399
  async function workspaceProjectPaths(workspacePath2, folder) {
11000
- const contentsPath = join8(workspacePath2, "contents.xcworkspacedata");
11400
+ const contentsPath = join9(workspacePath2, "contents.xcworkspacedata");
11001
11401
  let contents;
11002
11402
  try {
11003
11403
  contents = await readFile5(contentsPath, "utf8");
@@ -11024,9 +11424,9 @@ async function workspaceProjectPaths(workspacePath2, folder) {
11024
11424
  continue;
11025
11425
  }
11026
11426
  try {
11027
- const resolved = await realpath4(candidate);
11427
+ const resolved = await realpath5(candidate);
11028
11428
  const resolvedDifference = relative4(folder, resolved);
11029
- if (resolvedDifference === ".." || resolvedDifference.startsWith(`..${sep4}`) || isAbsolute4(resolvedDifference) || !(await stat6(resolved)).isDirectory()) {
11429
+ if (resolvedDifference === ".." || resolvedDifference.startsWith(`..${sep4}`) || isAbsolute4(resolvedDifference) || !(await stat7(resolved)).isDirectory()) {
11030
11430
  continue;
11031
11431
  }
11032
11432
  projects.push(resolved);
@@ -11217,7 +11617,7 @@ async function dependentSigningRequirements(source, absolutePath, folder, rootTa
11217
11617
  for (const project of projects.slice(0, 50)) {
11218
11618
  const converted = await command(
11219
11619
  "plutil",
11220
- ["-convert", "json", "-o", "-", join8(project, "project.pbxproj")],
11620
+ ["-convert", "json", "-o", "-", join9(project, "project.pbxproj")],
11221
11621
  Math.min(timeoutMs, 15e3),
11222
11622
  signal,
11223
11623
  folder
@@ -11454,8 +11854,8 @@ function genericBuildDestinations(action) {
11454
11854
  ];
11455
11855
  }
11456
11856
  async function listPhysicalDevices(timeoutMs, signal) {
11457
- const directory = await mkdtemp3(join8(tmpdir3(), "ade-devices-"));
11458
- const output = join8(directory, "devices.json");
11857
+ const directory = await mkdtemp4(join9(tmpdir4(), "ade-devices-"));
11858
+ const output = join9(directory, "devices.json");
11459
11859
  try {
11460
11860
  const result = await command(
11461
11861
  "xcrun",
@@ -11475,7 +11875,7 @@ async function listPhysicalDevices(timeoutMs, signal) {
11475
11875
  if (result.exitCode !== 0) return [];
11476
11876
  return physicalDestinations(JSON.parse(await readFile5(output, "utf8")));
11477
11877
  } finally {
11478
- await rm6(directory, { recursive: true, force: true });
11878
+ await rm7(directory, { recursive: true, force: true });
11479
11879
  }
11480
11880
  }
11481
11881
  var inspectBuildDestinations = async (payload, timeoutMs, signal) => {
@@ -11562,7 +11962,7 @@ function createRedactor(env) {
11562
11962
  );
11563
11963
  };
11564
11964
  }
11565
- var BuildLogger = class {
11965
+ var BuildLogger = class _BuildLogger {
11566
11966
  constructor(buildId, context, rawLogPath, env) {
11567
11967
  this.buildId = buildId;
11568
11968
  this.context = context;
@@ -11571,51 +11971,67 @@ var BuildLogger = class {
11571
11971
  }
11572
11972
  buildId;
11573
11973
  context;
11974
+ static MAX_CHUNK_BYTES = 128 * 1024;
11975
+ static MAX_BATCH_BYTES = 128 * 1024;
11574
11976
  stream;
11575
11977
  redact;
11576
11978
  sequence = 0;
11577
11979
  pending = [];
11980
+ pendingBytes = 0;
11578
11981
  flushChain = Promise.resolve();
11579
11982
  timer = null;
11580
11983
  closePromise = null;
11581
11984
  redactingPrivateKey = false;
11582
11985
  emit(phase, stream, message, scope = "BUILD", scopeId = this.buildId, extraStream) {
11986
+ this.write(phase, stream, `${message}\r
11987
+ `, scope, scopeId, extraStream);
11988
+ }
11989
+ write(phase, stream, output, scope = "BUILD", scopeId = this.buildId, extraStream) {
11990
+ const ending = output.match(/(?:\r\n|\r|\n)$/)?.[0] ?? "";
11991
+ const message = ending ? output.slice(0, -ending.length) : output;
11583
11992
  const startsPrivateKey = /-----BEGIN [^-]*PRIVATE KEY-----/i.test(message);
11584
11993
  const endsPrivateKey = /-----END [^-]*PRIVATE KEY-----/i.test(message);
11585
11994
  if (startsPrivateKey) this.redactingPrivateKey = true;
11586
11995
  const sanitized = this.redactingPrivateKey ? "[REDACTED PRIVATE KEY]" : this.redact(message);
11587
11996
  if (endsPrivateKey) this.redactingPrivateKey = false;
11588
11997
  const createdAt = (/* @__PURE__ */ new Date()).toISOString();
11589
- const line = `[${createdAt}] [${phase}] [${stream}] ${sanitized}
11590
- `;
11998
+ const terminalOutput = `${sanitized}${ending}`;
11999
+ const line = `[${createdAt}] [${phase}] [${stream}] ${sanitized}${ending || "\n"}`;
11591
12000
  this.stream.write(line);
11592
12001
  extraStream?.write(line);
11593
- this.pending.push({
11594
- scope,
11595
- scopeId,
11596
- sequence: this.sequence++,
11597
- phase,
11598
- level: stream === "STDERR" || /\berror\b/i.test(sanitized) ? "ERROR" : /\bwarning\b/i.test(sanitized) ? "WARNING" : "INFO",
11599
- stream,
11600
- message: sanitized,
11601
- createdAt
11602
- });
11603
- if (this.pending.length >= 100) this.flush();
11604
- else if (!this.timer) {
11605
- this.timer = setTimeout(() => this.flush(), 250);
12002
+ for (const data of splitUtf8(terminalOutput, _BuildLogger.MAX_CHUNK_BYTES)) {
12003
+ const bytes = Buffer.from(data, "utf8");
12004
+ this.pending.push({
12005
+ scope,
12006
+ scopeId,
12007
+ sequence: this.sequence++,
12008
+ phase,
12009
+ stream,
12010
+ dataBase64: bytes.toString("base64"),
12011
+ byteLength: bytes.byteLength,
12012
+ createdAt
12013
+ });
12014
+ this.pendingBytes += bytes.byteLength;
12015
+ if (this.pending.length >= 200 || this.pendingBytes >= _BuildLogger.MAX_BATCH_BYTES) {
12016
+ this.flush();
12017
+ }
12018
+ }
12019
+ if (this.pending.length && !this.timer) {
12020
+ this.timer = setTimeout(() => this.flush(), 25);
11606
12021
  this.timer.unref();
11607
12022
  }
11608
12023
  }
11609
12024
  flush() {
11610
12025
  if (this.timer) clearTimeout(this.timer);
11611
12026
  this.timer = null;
11612
- const events = this.pending.splice(0);
11613
- if (!events.length || !this.context?.appendBuildLogs) return;
12027
+ const chunks = this.pending.splice(0);
12028
+ this.pendingBytes = 0;
12029
+ if (!chunks.length || !this.context?.appendBuildLogChunks) return;
11614
12030
  this.flushChain = this.flushChain.then(async () => {
11615
12031
  try {
11616
- await this.context.appendBuildLogs(this.buildId, events);
12032
+ await this.context.appendBuildLogChunks(this.buildId, chunks);
11617
12033
  } catch (error) {
11618
- console.error("Could not append build logs:", cleanError2(error));
12034
+ console.error("Could not append build log chunks:", cleanError2(error));
11619
12035
  }
11620
12036
  });
11621
12037
  }
@@ -11628,6 +12044,24 @@ var BuildLogger = class {
11628
12044
  return this.closePromise;
11629
12045
  }
11630
12046
  };
12047
+ function splitUtf8(value, maximumBytes) {
12048
+ if (!value) return [];
12049
+ const parts = [];
12050
+ let part = "";
12051
+ let byteLength = 0;
12052
+ for (const character of value) {
12053
+ const characterBytes = Buffer.byteLength(character, "utf8");
12054
+ if (part && byteLength + characterBytes > maximumBytes) {
12055
+ parts.push(part);
12056
+ part = "";
12057
+ byteLength = 0;
12058
+ }
12059
+ part += character;
12060
+ byteLength += characterBytes;
12061
+ }
12062
+ if (part) parts.push(part);
12063
+ return parts;
12064
+ }
11631
12065
  function terminateProcess(child) {
11632
12066
  if (child.exitCode !== null || child.killed) return null;
11633
12067
  try {
@@ -11661,9 +12095,15 @@ function runLoggedCommand(options) {
11661
12095
  mode: 384
11662
12096
  });
11663
12097
  }
11664
- const child = spawn4(options.command, options.args, {
12098
+ const child = spawn5(options.command, options.args, {
11665
12099
  cwd: options.cwd,
11666
- env: options.env,
12100
+ env: {
12101
+ ...options.env,
12102
+ TERM: "xterm-256color",
12103
+ COLORTERM: "truecolor",
12104
+ FORCE_COLOR: "1",
12105
+ CLICOLOR_FORCE: "1"
12106
+ },
11667
12107
  shell: false,
11668
12108
  detached: true,
11669
12109
  stdio: ["ignore", "pipe", "pipe"]
@@ -11677,36 +12117,36 @@ function runLoggedCommand(options) {
11677
12117
  extraStream
11678
12118
  );
11679
12119
  const attach = (stream, kind) => {
12120
+ const decoder = new StringDecoder("utf8");
11680
12121
  let remainder = "";
11681
- stream.setEncoding("utf8");
11682
- stream.on("data", (chunk) => {
11683
- const parts = `${remainder}${chunk}`.split(/\r?\n/);
11684
- remainder = parts.pop() ?? "";
11685
- for (const line of parts) {
11686
- output = `${output}${line}
11687
- `.slice(-64e3);
11688
- options.logger.emit(
12122
+ const drain = (final = false) => {
12123
+ while (remainder) {
12124
+ const delimiter = remainder.search(/[\r\n]/);
12125
+ if (delimiter < 0 && !final) return;
12126
+ let end = delimiter < 0 ? remainder.length : delimiter + 1;
12127
+ if (remainder[delimiter] === "\r" && remainder[delimiter + 1] === "\n") {
12128
+ end += 1;
12129
+ }
12130
+ const record = remainder.slice(0, end);
12131
+ remainder = remainder.slice(end);
12132
+ output = `${output}${record}`.slice(-64e3);
12133
+ options.logger.write(
11689
12134
  options.phase,
11690
12135
  kind,
11691
- line,
12136
+ record,
11692
12137
  options.scope,
11693
12138
  options.scopeId,
11694
12139
  extraStream
11695
12140
  );
11696
12141
  }
12142
+ };
12143
+ stream.on("data", (chunk) => {
12144
+ remainder += decoder.write(chunk);
12145
+ drain();
11697
12146
  });
11698
12147
  stream.on("end", () => {
11699
- if (remainder) {
11700
- output = `${output}${remainder}`.slice(-64e3);
11701
- options.logger.emit(
11702
- options.phase,
11703
- kind,
11704
- remainder,
11705
- options.scope,
11706
- options.scopeId,
11707
- extraStream
11708
- );
11709
- }
12148
+ remainder += decoder.end();
12149
+ drain(true);
11710
12150
  });
11711
12151
  };
11712
12152
  attach(child.stdout, "STDOUT");
@@ -11853,7 +12293,7 @@ function actionArgument(action) {
11853
12293
  }[action];
11854
12294
  }
11855
12295
  function xcodeBuildArguments(input) {
11856
- const resultBundle = join8(input.artifactDirectory, "result.xcresult");
12296
+ const resultBundle = join9(input.artifactDirectory, "result.xcresult");
11857
12297
  const sourcePath = containedPath2(input.folder, input.source.relativePath);
11858
12298
  const usesCapturedTestProducts = input.action === "TEST_WITHOUT_BUILDING";
11859
12299
  const args = [
@@ -11875,13 +12315,13 @@ function xcodeBuildArguments(input) {
11875
12315
  if (input.action === "ARCHIVE") {
11876
12316
  args.push(
11877
12317
  "-archivePath",
11878
- join8(input.artifactDirectory, "archive.xcarchive")
12318
+ join9(input.artifactDirectory, "archive.xcarchive")
11879
12319
  );
11880
12320
  }
11881
12321
  if (input.action === "BUILD_FOR_TESTING") {
11882
12322
  args.push(
11883
12323
  "-testProductsPath",
11884
- join8(input.artifactDirectory, "test-products.xctestproducts")
12324
+ join9(input.artifactDirectory, "test-products.xctestproducts")
11885
12325
  );
11886
12326
  }
11887
12327
  if (input.action === "TEST_WITHOUT_BUILDING" && input.advancedSettings.priorTestProductsPath) {
@@ -11944,27 +12384,27 @@ function classifyFailure(output) {
11944
12384
  }
11945
12385
  async function runHook(options) {
11946
12386
  const phaseDirectory = options.phase === "PRE_BUILD" ? "pre" : "post";
11947
- const directory = join8(
12387
+ const directory = join9(
11948
12388
  options.input.artifactDirectory,
11949
12389
  "hooks",
11950
12390
  phaseDirectory
11951
12391
  );
11952
12392
  const prefix = `${String(options.script.position).padStart(3, "0")}-${options.script.id}`;
11953
- const file = join8(directory, `${prefix}.mjs`);
11954
- const runner = join8(directory, `${prefix}.runner.mjs`);
11955
- const log = join8(directory, `${prefix}.log`);
12393
+ const file = join9(directory, `${prefix}.mjs`);
12394
+ const runner = join9(directory, `${prefix}.runner.mjs`);
12395
+ const log = join9(directory, `${prefix}.log`);
11956
12396
  const started = Date.now();
11957
12397
  try {
11958
12398
  await mkdir4(directory, { recursive: true, mode: 448 });
11959
- await writeFile4(file, `${options.source}
12399
+ await writeFile5(file, `${options.source}
11960
12400
  `, { mode: 384 });
11961
- await writeFile4(
12401
+ await writeFile5(
11962
12402
  options.contextPath,
11963
12403
  `${JSON.stringify(options.hookContext, null, 2)}
11964
12404
  `,
11965
12405
  { mode: 384 }
11966
12406
  );
11967
- await writeFile4(
12407
+ await writeFile5(
11968
12408
  runner,
11969
12409
  `import { readFile } from "node:fs/promises";
11970
12410
  const hookModule = await import(${JSON.stringify(`./${basename3(file)}`)});
@@ -12037,26 +12477,26 @@ if (typeof hookModule.default === "function") {
12037
12477
  }
12038
12478
  async function pathExists(path) {
12039
12479
  try {
12040
- await stat6(path);
12480
+ await stat7(path);
12041
12481
  return true;
12042
12482
  } catch {
12043
12483
  return false;
12044
12484
  }
12045
12485
  }
12046
12486
  async function pathSize(path) {
12047
- const information = await stat6(path);
12487
+ const information = await stat7(path);
12048
12488
  if (information.isFile()) return information.size;
12049
12489
  if (!information.isDirectory()) return 0;
12050
12490
  let size = 0;
12051
12491
  for (const entry of await readdir6(path, { withFileTypes: true })) {
12052
12492
  if (entry.isSymbolicLink()) continue;
12053
- size += await pathSize(join8(path, entry.name));
12493
+ size += await pathSize(join9(path, entry.name));
12054
12494
  }
12055
12495
  return size;
12056
12496
  }
12057
12497
  async function fileChecksum(path) {
12058
12498
  try {
12059
- const information = await stat6(path);
12499
+ const information = await stat7(path);
12060
12500
  if (!information.isFile()) return null;
12061
12501
  const hash = createHash5("sha256");
12062
12502
  await pipeline(createReadStream3(path), hash);
@@ -12080,7 +12520,7 @@ async function plistString(plistPath, keyPath, timeoutMs, signal) {
12080
12520
  }
12081
12521
  }
12082
12522
  async function archiveApplicationProperties(archivePath, timeoutMs, signal) {
12083
- const plistPath = join8(archivePath, "Info.plist");
12523
+ const plistPath = join9(archivePath, "Info.plist");
12084
12524
  const read = (key) => plistString(plistPath, `ApplicationProperties.${key}`, timeoutMs, signal);
12085
12525
  const [bundleIdentifier2, bundleShortVersion, bundleVersion, applicationPath] = await Promise.all([
12086
12526
  read("CFBundleIdentifier"),
@@ -12239,9 +12679,9 @@ function normalizeCoverage(value) {
12239
12679
  };
12240
12680
  }
12241
12681
  async function writeJsonReport(input, kind, timeoutMs, signal) {
12242
- const resultBundle = join8(input.artifactDirectory, "result.xcresult");
12682
+ const resultBundle = join9(input.artifactDirectory, "result.xcresult");
12243
12683
  const filename = kind === "TEST_RESULTS" ? "test-results.json" : "code-coverage.json";
12244
- const destination = join8(input.artifactDirectory, filename);
12684
+ const destination = join9(input.artifactDirectory, filename);
12245
12685
  const temporary = `${destination}.tmp-${randomUUID3()}`;
12246
12686
  try {
12247
12687
  if (!await pathExists(resultBundle)) {
@@ -12285,7 +12725,7 @@ async function writeJsonReport(input, kind, timeoutMs, signal) {
12285
12725
  error: null
12286
12726
  };
12287
12727
  } catch (error) {
12288
- await rm6(temporary, { force: true });
12728
+ await rm7(temporary, { force: true });
12289
12729
  return {
12290
12730
  kind,
12291
12731
  status: "FAILED",
@@ -12376,7 +12816,7 @@ async function snapshotCoverageChanges(input, folder, timeoutMs, signal) {
12376
12816
  const types = changeTypesFromStatus(status2.stdout);
12377
12817
  for (const path of untracked.stdout.split("\0").filter(Boolean)) {
12378
12818
  try {
12379
- const contents = await readFile5(join8(folder, path));
12819
+ const contents = await readFile5(join9(folder, path));
12380
12820
  if (contents.includes(0)) continue;
12381
12821
  const lineCount = contents.length ? contents.toString("utf8").split("\n").length - (contents.toString("utf8").endsWith("\n") ? 1 : 0) : 0;
12382
12822
  lines.set(
@@ -12410,7 +12850,7 @@ async function addChangedCoverage(report, changes, input, folder, timeoutMs, sig
12410
12850
  let covered = 0;
12411
12851
  let executable = 0;
12412
12852
  if (coveragePath && change.lines.length) {
12413
- const temporary2 = join8(
12853
+ const temporary2 = join9(
12414
12854
  input.artifactDirectory,
12415
12855
  `.changed-coverage-${randomUUID3()}.json`
12416
12856
  );
@@ -12451,7 +12891,7 @@ async function addChangedCoverage(report, changes, input, folder, timeoutMs, sig
12451
12891
  }
12452
12892
  }
12453
12893
  } finally {
12454
- await rm6(temporary2, { force: true });
12894
+ await rm7(temporary2, { force: true });
12455
12895
  }
12456
12896
  }
12457
12897
  changedCoveredLines += covered;
@@ -12471,9 +12911,9 @@ async function addChangedCoverage(report, changes, input, folder, timeoutMs, sig
12471
12911
  changedLineCoverage: changedExecutableLines ? changedCoveredLines / changedExecutableLines : null
12472
12912
  };
12473
12913
  const data = { ...report.data, changedFiles };
12474
- const destination = join8(input.artifactDirectory, "worktree-coverage.json");
12914
+ const destination = join9(input.artifactDirectory, "worktree-coverage.json");
12475
12915
  const temporary = `${destination}.tmp-${randomUUID3()}`;
12476
- await writeFile4(temporary, JSON.stringify({ summary, data }, null, 2), {
12916
+ await writeFile5(temporary, JSON.stringify({ summary, data }, null, 2), {
12477
12917
  mode: 384
12478
12918
  });
12479
12919
  await rename3(temporary, destination);
@@ -12525,7 +12965,7 @@ async function findFiles(root, predicate, limit = 20) {
12525
12965
  }
12526
12966
  for (const entry of entries) {
12527
12967
  if (entry.isSymbolicLink()) continue;
12528
- const path = join8(current, entry.name);
12968
+ const path = join9(current, entry.name);
12529
12969
  if (entry.isDirectory()) queue.push(path);
12530
12970
  else if (entry.isFile() && predicate(entry.name)) results.push(path);
12531
12971
  if (results.length >= limit) break;
@@ -12535,7 +12975,7 @@ async function findFiles(root, predicate, limit = 20) {
12535
12975
  }
12536
12976
  async function captureArtifacts(input, folder, signal, includeProducts = true) {
12537
12977
  const artifacts = [];
12538
- const resultBundle = join8(input.artifactDirectory, "result.xcresult");
12978
+ const resultBundle = join9(input.artifactDirectory, "result.xcresult");
12539
12979
  if (await pathExists(resultBundle)) {
12540
12980
  const coverageProbe = await command(
12541
12981
  "xcrun",
@@ -12562,7 +13002,7 @@ async function captureArtifacts(input, folder, signal, includeProducts = true) {
12562
13002
  );
12563
13003
  }
12564
13004
  if (!includeProducts) return artifacts;
12565
- const archivePath = join8(input.artifactDirectory, "archive.xcarchive");
13005
+ const archivePath = join9(input.artifactDirectory, "archive.xcarchive");
12566
13006
  if (await pathExists(archivePath)) {
12567
13007
  artifacts.push(
12568
13008
  await artifact(input.artifactDirectory, "ARCHIVE", archivePath)
@@ -12585,12 +13025,12 @@ async function captureArtifacts(input, folder, signal, includeProducts = true) {
12585
13025
  if (apps.length === 1) {
12586
13026
  const settings = apps[0].buildSettings;
12587
13027
  const productName = settings.FULL_PRODUCT_NAME ?? settings.WRAPPER_NAME;
12588
- const source = settings.TARGET_BUILD_DIR && productName ? join8(settings.TARGET_BUILD_DIR, productName) : null;
13028
+ const source = settings.TARGET_BUILD_DIR && productName ? join9(settings.TARGET_BUILD_DIR, productName) : null;
12589
13029
  if (source && await pathExists(source)) {
12590
- const productDirectory = join8(input.artifactDirectory, "products");
12591
- const destination = join8(productDirectory, basename3(source));
13030
+ const productDirectory = join9(input.artifactDirectory, "products");
13031
+ const destination = join9(productDirectory, basename3(source));
12592
13032
  await mkdir4(productDirectory, { recursive: true, mode: 448 });
12593
- await rm6(destination, { recursive: true, force: true });
13033
+ await rm7(destination, { recursive: true, force: true });
12594
13034
  await cp(source, destination, {
12595
13035
  recursive: true,
12596
13036
  preserveTimestamps: true
@@ -12605,7 +13045,7 @@ async function captureArtifacts(input, folder, signal, includeProducts = true) {
12605
13045
  }
12606
13046
  }
12607
13047
  if (input.action === "BUILD_FOR_TESTING") {
12608
- const testDirectory = join8(
13048
+ const testDirectory = join9(
12609
13049
  input.artifactDirectory,
12610
13050
  "test-products.xctestproducts"
12611
13051
  );
@@ -12640,10 +13080,10 @@ var runIosBuild = async (payload, timeoutMs, signal, onLog, context) => {
12640
13080
  const testProductsPath = input.advancedSettings.priorTestProductsPath;
12641
13081
  const xctestrunPath = input.advancedSettings.priorXctestrunPath;
12642
13082
  if (testProductsPath) {
12643
- if (!testProductsPath.endsWith(".xctestproducts") || !await pathExists(testProductsPath) || !(await stat6(testProductsPath)).isDirectory()) {
13083
+ if (!testProductsPath.endsWith(".xctestproducts") || !await pathExists(testProductsPath) || !(await stat7(testProductsPath)).isDirectory()) {
12644
13084
  throw new Error("The captured test-products artifact is unavailable");
12645
13085
  }
12646
- } else if (!xctestrunPath?.endsWith(".xctestrun") || !await pathExists(xctestrunPath) || !(await stat6(xctestrunPath)).isFile()) {
13086
+ } else if (!xctestrunPath?.endsWith(".xctestrun") || !await pathExists(xctestrunPath) || !(await stat7(xctestrunPath)).isFile()) {
12647
13087
  throw new Error("The captured .xctestrun artifact is unavailable");
12648
13088
  }
12649
13089
  }
@@ -12656,11 +13096,11 @@ var runIosBuild = async (payload, timeoutMs, signal, onLog, context) => {
12656
13096
  signal
12657
13097
  );
12658
13098
  await mkdir4(input.artifactDirectory, { recursive: true, mode: 448 });
12659
- const rawLog = join8(input.artifactDirectory, "build.log");
13099
+ const rawLog = join9(input.artifactDirectory, "build.log");
12660
13100
  const logger = new BuildLogger(input.buildId, context, rawLog, process.env);
12661
13101
  try {
12662
13102
  const scriptExecutions = [];
12663
- const contextPath = join8(input.artifactDirectory, "context.json");
13103
+ const contextPath = join9(input.artifactDirectory, "context.json");
12664
13104
  const baseHookContext = {
12665
13105
  buildId: input.buildId,
12666
13106
  branch: input.branch ?? null,
@@ -12919,7 +13359,7 @@ var generateIosBuildReport = async (payload, timeoutMs, signal, onLog) => {
12919
13359
  var deleteIosBuild = async (payload, _timeoutMs, signal, onLog) => {
12920
13360
  const input = parseBuildDeletePayload(payload);
12921
13361
  if (signal.aborted) return { ...successfulProcess6, cancelled: true };
12922
- await rm6(input.artifactDirectory, { recursive: true, force: true });
13362
+ await rm7(input.artifactDirectory, { recursive: true, force: true });
12923
13363
  await onLog({
12924
13364
  sequence: 0,
12925
13365
  stream: "SYSTEM",
@@ -12933,23 +13373,23 @@ var downloadIosBuildArtifact = async (payload, timeoutMs, signal, onLog, context
12933
13373
  if (!context?.uploadBuildArtifact) {
12934
13374
  throw new Error("This agent cannot upload build artifacts");
12935
13375
  }
12936
- const root = await realpath4(input.artifactDirectory);
12937
- const target2 = await realpath4(
13376
+ const root = await realpath5(input.artifactDirectory);
13377
+ const target2 = await realpath5(
12938
13378
  containedPath2(root, input.artifactRelativePath)
12939
13379
  );
12940
13380
  const difference = relative4(root, target2);
12941
13381
  if (!difference || difference === ".." || difference.startsWith(`..${sep4}`) || isAbsolute4(difference)) {
12942
13382
  throw new Error("Build artifact resolves outside the build folder");
12943
13383
  }
12944
- const information = await stat6(target2);
13384
+ const information = await stat7(target2);
12945
13385
  let uploadPath = target2;
12946
13386
  let filename = basename3(target2);
12947
13387
  let contentType = "application/octet-stream";
12948
13388
  let temporaryArchive = null;
12949
13389
  try {
12950
13390
  if (information.isDirectory()) {
12951
- temporaryArchive = join8(
12952
- tmpdir3(),
13391
+ temporaryArchive = join9(
13392
+ tmpdir4(),
12953
13393
  `ade-build-artifact-${randomUUID3()}.tar.gz`
12954
13394
  );
12955
13395
  requireSuccess2(
@@ -12982,7 +13422,7 @@ var downloadIosBuildArtifact = async (payload, timeoutMs, signal, onLog, context
12982
13422
  return successfulProcess6;
12983
13423
  } finally {
12984
13424
  if (temporaryArchive) {
12985
- await rm6(temporaryArchive, { force: true });
13425
+ await rm7(temporaryArchive, { force: true });
12986
13426
  }
12987
13427
  }
12988
13428
  };
@@ -13018,24 +13458,24 @@ var deployIosBuild = async (payload, timeoutMs, signal, _onLog, context) => {
13018
13458
  if (!await pathExists(appPath) || !appPath.endsWith(".app")) {
13019
13459
  throw new Error("Runnable app artifact is missing");
13020
13460
  }
13021
- const deploymentsDirectory = join8(input.artifactDirectory, "deployments");
13461
+ const deploymentsDirectory = join9(input.artifactDirectory, "deployments");
13022
13462
  await mkdir4(deploymentsDirectory, { recursive: true, mode: 448 });
13023
13463
  const logger = new BuildLogger(
13024
13464
  input.buildId,
13025
13465
  context,
13026
- join8(deploymentsDirectory, "deployments.log"),
13466
+ join9(deploymentsDirectory, "deployments.log"),
13027
13467
  process.env
13028
13468
  );
13029
13469
  try {
13030
13470
  const outcomes = [];
13031
13471
  for (const deployment of input.deployments) {
13032
- const directory = join8(
13472
+ const directory = join9(
13033
13473
  input.artifactDirectory,
13034
13474
  "deployments",
13035
13475
  deployment.id
13036
13476
  );
13037
13477
  await mkdir4(directory, { recursive: true, mode: 448 });
13038
- const logPath = join8(directory, "deployment.log");
13478
+ const logPath = join9(directory, "deployment.log");
13039
13479
  const started = Date.now();
13040
13480
  let failure = null;
13041
13481
  try {
@@ -13250,15 +13690,15 @@ var exportIosArchive = async (payload, timeoutMs, signal, _onLog, context) => {
13250
13690
  if (!await pathExists(archivePath) || !archivePath.endsWith(".xcarchive")) {
13251
13691
  throw new Error("Archive artifact is missing");
13252
13692
  }
13253
- const exportDirectory = join8(
13693
+ const exportDirectory = join9(
13254
13694
  input.artifactDirectory,
13255
13695
  "exports",
13256
13696
  input.exportId
13257
13697
  );
13258
13698
  await mkdir4(exportDirectory, { recursive: true, mode: 448 });
13259
- const plistPath = join8(exportDirectory, "ExportOptions.plist");
13260
- const logPath = join8(exportDirectory, "export.log");
13261
- await writeFile4(plistPath, exportPlist(input.settings), { mode: 384 });
13699
+ const plistPath = join9(exportDirectory, "ExportOptions.plist");
13700
+ const logPath = join9(exportDirectory, "export.log");
13701
+ await writeFile5(plistPath, exportPlist(input.settings), { mode: 384 });
13262
13702
  const logger = new BuildLogger(input.buildId, context, logPath, process.env);
13263
13703
  try {
13264
13704
  const result = await runLoggedCommand({
@@ -13324,18 +13764,18 @@ var success = {
13324
13764
  };
13325
13765
  var runWorkflowTerminal = async (payloadValue, timeoutMs, signal, onLog, context) => {
13326
13766
  const payload = parseWorkflowTerminalPayload(payloadValue);
13327
- const cwd = await realpath5(payload.cwd);
13328
- const information = await stat7(cwd);
13767
+ const cwd = await realpath6(payload.cwd);
13768
+ const information = await stat8(cwd);
13329
13769
  if (!information.isDirectory())
13330
13770
  throw new Error("Workflow working directory is not a directory");
13331
- const directory = await mkdtemp4(join9(tmpdir4(), "aide-workflow-"));
13771
+ const directory = await mkdtemp5(join10(tmpdir5(), "aide-workflow-"));
13332
13772
  const extension2 = payload.interpreter === "NODE" ? "mjs" : "sh";
13333
- const scriptPath = join9(directory, `step.${extension2}`);
13334
- const sessionPath = join9(directory, "session.json");
13773
+ const scriptPath = join10(directory, `step.${extension2}`);
13774
+ const sessionPath = join10(directory, "session.json");
13335
13775
  try {
13336
- await writeFile5(scriptPath, `${payload.script}
13776
+ await writeFile6(scriptPath, `${payload.script}
13337
13777
  `, { mode: 384 });
13338
- await writeFile5(
13778
+ await writeFile6(
13339
13779
  sessionPath,
13340
13780
  `${JSON.stringify(payload.sessionData, null, 2)}
13341
13781
  `,
@@ -13379,13 +13819,13 @@ var runWorkflowTerminal = async (payloadValue, timeoutMs, signal, onLog, context
13379
13819
  }
13380
13820
  return { ...result, sessionData };
13381
13821
  } finally {
13382
- await rm7(directory, { recursive: true, force: true });
13822
+ await rm8(directory, { recursive: true, force: true });
13383
13823
  }
13384
13824
  };
13385
13825
  var runWorkflowGitCheckpoint = async (payloadValue, _timeoutMs, signal) => {
13386
13826
  const payload = parseWorkflowGitCheckpointPayload(payloadValue);
13387
13827
  if (signal.aborted) return { ...success, exitCode: null, cancelled: true };
13388
- const cwd = await realpath5(payload.cwd);
13828
+ const cwd = await realpath6(payload.cwd);
13389
13829
  if (payload.operation === "CAPTURE") {
13390
13830
  const checkpoint2 = await captureGitCheckpoint(
13391
13831
  cwd,
@@ -13422,10 +13862,10 @@ var runWorkflowGitCheckpoint = async (payloadValue, _timeoutMs, signal) => {
13422
13862
 
13423
13863
  // src/handlers/worktrees.ts
13424
13864
  import { createWriteStream as createWriteStream2, watch } from "node:fs";
13425
- import { mkdtemp as mkdtemp5, open as open2, readFile as readFile7, realpath as realpath6, rm as rm8, stat as stat8 } from "node:fs/promises";
13426
- import { tmpdir as tmpdir5 } from "node:os";
13427
- import { basename as basename4, dirname as dirname6, isAbsolute as isAbsolute5, join as join10, relative as relative5 } from "node:path";
13428
- import { spawn as spawn5 } from "node:child_process";
13865
+ import { mkdtemp as mkdtemp6, open as open2, readFile as readFile7, realpath as realpath7, rm as rm9, stat as stat9 } from "node:fs/promises";
13866
+ import { tmpdir as tmpdir6 } from "node:os";
13867
+ import { basename as basename4, dirname as dirname6, isAbsolute as isAbsolute5, join as join11, relative as relative5 } from "node:path";
13868
+ import { spawn as spawn6 } from "node:child_process";
13429
13869
  var successfulProcess7 = {
13430
13870
  exitCode: 0,
13431
13871
  signal: null,
@@ -13479,7 +13919,7 @@ async function rebaseInProgress(folder, timeoutMs, signal) {
13479
13919
  const candidate = pathResult.stdout.trim();
13480
13920
  if (!candidate) continue;
13481
13921
  try {
13482
- await stat8(isAbsolute5(candidate) ? candidate : join10(folder, candidate));
13922
+ await stat9(isAbsolute5(candidate) ? candidate : join11(folder, candidate));
13483
13923
  return true;
13484
13924
  } catch {
13485
13925
  }
@@ -13499,7 +13939,7 @@ async function rebaseBranch(folder, timeoutMs, signal) {
13499
13939
  if (!candidate) continue;
13500
13940
  try {
13501
13941
  const headName = (await readFile7(
13502
- isAbsolute5(candidate) ? candidate : join10(folder, candidate),
13942
+ isAbsolute5(candidate) ? candidate : join11(folder, candidate),
13503
13943
  "utf8"
13504
13944
  )).trim();
13505
13945
  if (headName.startsWith("refs/heads/")) {
@@ -13682,7 +14122,7 @@ async function gitDirectory(folder, timeoutMs, signal) {
13682
14122
  ),
13683
14123
  "Could not resolve the worktree Git directory"
13684
14124
  );
13685
- return realpath6(result.stdout.trim());
14125
+ return realpath7(result.stdout.trim());
13686
14126
  }
13687
14127
  async function origin(folder, timeoutMs, signal) {
13688
14128
  const result = requireSuccess3(
@@ -13692,8 +14132,8 @@ async function origin(folder, timeoutMs, signal) {
13692
14132
  return normalizeGitOrigin(result.stdout.trim()).canonicalOrigin;
13693
14133
  }
13694
14134
  async function validateWorktree2(input, timeoutMs, signal) {
13695
- const folder = await realpath6(input.folder);
13696
- if (!(await stat8(folder)).isDirectory())
14135
+ const folder = await realpath7(input.folder);
14136
+ if (!(await stat9(folder)).isDirectory())
13697
14137
  throw new Error("Worktree is missing");
13698
14138
  const observedGitDirectory = await gitDirectory(folder, timeoutMs, signal);
13699
14139
  if (observedGitDirectory !== input.gitDirectory) {
@@ -13739,7 +14179,7 @@ async function worktreePushStatus(folder, branch, changes, timeoutMs, signal) {
13739
14179
  async function inspectWorktreeItem(folderValue2, rootFolder, baseBranch, primary, timeoutMs, signal) {
13740
14180
  const checkedAt = (/* @__PURE__ */ new Date()).toISOString();
13741
14181
  try {
13742
- const folder = await realpath6(folderValue2);
14182
+ const folder = await realpath7(folderValue2);
13743
14183
  const [gitDir, branchResult, headResult, statusResult, rebasing] = await Promise.all([
13744
14184
  gitDirectory(folder, timeoutMs, signal),
13745
14185
  git3(
@@ -13839,7 +14279,7 @@ async function inspectWorktreeItem(folderValue2, rootFolder, baseBranch, primary
13839
14279
  }
13840
14280
  }
13841
14281
  async function discoverWorktrees(rootFolderValue, baseOverrides, knownDefaultBranch, timeoutMs, signal) {
13842
- const rootFolder = await realpath6(rootFolderValue);
14282
+ const rootFolder = await realpath7(rootFolderValue);
13843
14283
  const list = requireSuccess3(
13844
14284
  await git3(
13845
14285
  rootFolder,
@@ -13934,7 +14374,7 @@ function parseNumstat(value) {
13934
14374
  }
13935
14375
  async function untrackedLines(folder, path) {
13936
14376
  try {
13937
- const file = await stat8(`${folder}/${path}`);
14377
+ const file = await stat9(`${folder}/${path}`);
13938
14378
  if (!file.isFile() || file.size > 1024 * 1024) return null;
13939
14379
  const contents = await readFile7(`${folder}/${path}`);
13940
14380
  if (contents.includes(0)) return null;
@@ -14145,7 +14585,7 @@ async function comparisonSides(input, folder, timeoutMs, signal) {
14145
14585
  if (!input.path) return { before: null, after: null };
14146
14586
  const path = input.path;
14147
14587
  const previousPath = input.previousPath ?? path;
14148
- const currentPath = join10(folder, path);
14588
+ const currentPath = join11(folder, path);
14149
14589
  if (input.scope === "UNTRACKED") {
14150
14590
  return { before: null, after: { kind: "FILE", path: currentPath } };
14151
14591
  }
@@ -14228,9 +14668,9 @@ async function availableSide(side, folder, timeoutMs, signal) {
14228
14668
  return gitObjectExists(folder, side.specification, timeoutMs, signal);
14229
14669
  }
14230
14670
  try {
14231
- const resolved = await realpath6(side.path);
14671
+ const resolved = await realpath7(side.path);
14232
14672
  const difference = relative5(folder, resolved);
14233
- return difference !== ".." && !difference.startsWith("../") && (await stat8(resolved)).isFile();
14673
+ return difference !== ".." && !difference.startsWith("../") && (await stat9(resolved)).isFile();
14234
14674
  } catch {
14235
14675
  return false;
14236
14676
  }
@@ -14301,7 +14741,7 @@ async function inspectRequestedDiff(input, folder, timeoutMs, signal) {
14301
14741
  let patch;
14302
14742
  if (input.scope === "UNTRACKED") {
14303
14743
  const bounded = await readBoundedFile(
14304
- join10(folder, input.path),
14744
+ join11(folder, input.path),
14305
14745
  MAX_DIFF_BYTES
14306
14746
  );
14307
14747
  const contents = bounded.contents;
@@ -14405,7 +14845,7 @@ function imageContentType(path) {
14405
14845
  }
14406
14846
  async function writeGitObject(folder, specification, destination, timeoutMs, signal) {
14407
14847
  await new Promise((resolvePromise, rejectPromise) => {
14408
- const child = spawn5(
14848
+ const child = spawn6(
14409
14849
  "git",
14410
14850
  ["-C", folder, "cat-file", "blob", specification],
14411
14851
  { stdio: ["ignore", "pipe", "pipe"] }
@@ -14471,7 +14911,7 @@ var downloadWorktreeDiffAsset = async (payload, timeoutMs, signal, _onLog, conte
14471
14911
  let temporaryDirectory = null;
14472
14912
  try {
14473
14913
  if (selected.kind === "FILE") {
14474
- uploadPath = await realpath6(selected.path);
14914
+ uploadPath = await realpath7(selected.path);
14475
14915
  const difference = relative5(folder, uploadPath);
14476
14916
  if (difference === ".." || difference.startsWith("../")) {
14477
14917
  throw new Error("Diff image resolves outside the worktree");
@@ -14489,8 +14929,8 @@ var downloadWorktreeDiffAsset = async (payload, timeoutMs, signal, _onLog, conte
14489
14929
  if (!/^\d+$/.test(size) || Number(size) > 20 * 1024 * 1024) {
14490
14930
  throw new Error("Diff image exceeds the 20 MiB limit");
14491
14931
  }
14492
- temporaryDirectory = await mkdtemp5(join10(tmpdir5(), "ade-diff-image-"));
14493
- uploadPath = join10(temporaryDirectory, basename4(input.path));
14932
+ temporaryDirectory = await mkdtemp6(join11(tmpdir6(), "ade-diff-image-"));
14933
+ uploadPath = join11(temporaryDirectory, basename4(input.path));
14494
14934
  await writeGitObject(
14495
14935
  folder,
14496
14936
  selected.specification,
@@ -14499,7 +14939,7 @@ var downloadWorktreeDiffAsset = async (payload, timeoutMs, signal, _onLog, conte
14499
14939
  signal
14500
14940
  );
14501
14941
  }
14502
- const information = await stat8(uploadPath);
14942
+ const information = await stat9(uploadPath);
14503
14943
  if (!information.isFile() || information.size > 20 * 1024 * 1024) {
14504
14944
  throw new Error("Diff image exceeds the 20 MiB limit");
14505
14945
  }
@@ -14512,7 +14952,7 @@ var downloadWorktreeDiffAsset = async (payload, timeoutMs, signal, _onLog, conte
14512
14952
  return successfulProcess7;
14513
14953
  } finally {
14514
14954
  if (temporaryDirectory) {
14515
- await rm8(temporaryDirectory, { recursive: true, force: true });
14955
+ await rm9(temporaryDirectory, { recursive: true, force: true });
14516
14956
  }
14517
14957
  }
14518
14958
  };
@@ -14689,8 +15129,8 @@ async function chooseNewBranch(folder, candidates, allowedCurrentBranch, timeout
14689
15129
  throw new Error("Every generated ticket branch name is already taken");
14690
15130
  }
14691
15131
  async function validateBranchRoot(input, timeoutMs, signal) {
14692
- const rootFolder = await realpath6(input.rootFolder);
14693
- if (!(await stat8(rootFolder)).isDirectory()) {
15132
+ const rootFolder = await realpath7(input.rootFolder);
15133
+ if (!(await stat9(rootFolder)).isDirectory()) {
14694
15134
  throw new Error("Base repository is missing");
14695
15135
  }
14696
15136
  if (await origin(rootFolder, timeoutMs, signal) !== input.expectedOrigin) {
@@ -14753,13 +15193,13 @@ var branchWorktree = async (payload, timeoutMs, signal) => {
14753
15193
  timeoutMs,
14754
15194
  signal
14755
15195
  ) : input.candidates[0];
14756
- const targetFolder = input.action === "CREATE" ? join10(
15196
+ const targetFolder = input.action === "CREATE" ? join11(
14757
15197
  dirname6(rootFolder),
14758
15198
  `${basename4(rootFolder)}-${branch.replaceAll("/", "-")}`
14759
15199
  ) : changeFolder;
14760
15200
  if (input.action === "CREATE") {
14761
15201
  try {
14762
- await stat8(targetFolder);
15202
+ await stat9(targetFolder);
14763
15203
  throw new Error(`Worktree folder already exists: ${targetFolder}`);
14764
15204
  } catch (error) {
14765
15205
  if (!(error instanceof Error) || !("code" in error) || error.code !== "ENOENT") {
@@ -14993,12 +15433,12 @@ var checkoutMovedWorktree = async (payload, timeoutMs, signal) => {
14993
15433
  `Branch ${input.branch} is already checked out in ${occupiedFolder}`
14994
15434
  );
14995
15435
  }
14996
- targetFolder = join10(
15436
+ targetFolder = join11(
14997
15437
  dirname6(rootFolder),
14998
15438
  `${basename4(rootFolder)}-${input.branch.replaceAll("/", "-")}`
14999
15439
  );
15000
15440
  try {
15001
- await stat8(targetFolder);
15441
+ await stat9(targetFolder);
15002
15442
  throw new Error(`Worktree folder already exists: ${targetFolder}`);
15003
15443
  } catch (error) {
15004
15444
  if (!(error instanceof Error) || !("code" in error) || error.code !== "ENOENT") {
@@ -15044,7 +15484,7 @@ var checkoutMovedWorktree = async (payload, timeoutMs, signal) => {
15044
15484
  const targetBranch = await currentBranch(targetFolder, timeoutMs, signal);
15045
15485
  const targetChanges = await statusState(targetFolder, timeoutMs, signal);
15046
15486
  if (occupiedFolder) {
15047
- const occupied = await realpath6(occupiedFolder);
15487
+ const occupied = await realpath7(occupiedFolder);
15048
15488
  if (occupied !== targetFolder) {
15049
15489
  throw new Error(
15050
15490
  `Branch ${input.branch} is checked out in another destination worktree`
@@ -15158,8 +15598,8 @@ var checkoutMovedWorktree = async (payload, timeoutMs, signal) => {
15158
15598
  };
15159
15599
  var deleteWorktree = async (payload, timeoutMs, signal) => {
15160
15600
  const input = worktreeDeleteJobPayload(payload);
15161
- const rootFolder = await realpath6(input.rootFolder);
15162
- if (!(await stat8(rootFolder)).isDirectory()) {
15601
+ const rootFolder = await realpath7(input.rootFolder);
15602
+ if (!(await stat9(rootFolder)).isDirectory()) {
15163
15603
  throw new Error("Base repository is missing");
15164
15604
  }
15165
15605
  if (await origin(rootFolder, timeoutMs, signal) !== input.expectedOrigin) {
@@ -15401,7 +15841,7 @@ var operateWorktree = async (payload, timeoutMs, signal) => {
15401
15841
 
15402
15842
  // src/handlers/index.ts
15403
15843
  var handlers = {
15404
- "cloudflared.runTunnel": runCloudflared,
15844
+ [COMMAND_RUN_JOB_KIND]: runCommand,
15405
15845
  [CCUSAGE_REPORT_JOB_KIND]: runCcusage,
15406
15846
  [BUILD_DATA_SCAN_JOB_KIND]: scanBuildData,
15407
15847
  [BUILD_DATA_SIZE_JOB_KIND]: sizeBuildData,
@@ -15489,7 +15929,9 @@ var JobExecutor = class {
15489
15929
  this.running.set(job.id, { controller, task });
15490
15930
  }
15491
15931
  cancel(jobId) {
15492
- this.running.get(jobId)?.controller.abort();
15932
+ const running = this.running.get(jobId);
15933
+ running?.controller.abort();
15934
+ return Boolean(running);
15493
15935
  }
15494
15936
  async cancelAll() {
15495
15937
  this.stopping = true;
@@ -15524,10 +15966,11 @@ var JobExecutor = class {
15524
15966
  {
15525
15967
  reportWorktreeActivity: (input) => this.client.reportWorktreeActivity(input),
15526
15968
  reportBuildProgress: (input) => this.client.reportBuildProgress(input),
15527
- appendBuildLogs: (buildId, events) => this.client.appendBuildLogs(buildId, events),
15969
+ appendBuildLogChunks: (buildId, chunks) => this.client.appendBuildLogChunks(buildId, chunks),
15528
15970
  uploadBuildArtifact: (input) => this.client.uploadBuildArtifact(input),
15529
15971
  claimSigningSecretTransfer: (transferId) => this.client.claimSigningSecretTransfer(transferId),
15530
- claimWorkflowJobSecrets: () => this.client.claimWorkflowJobSecrets(claimed.id)
15972
+ claimWorkflowJobSecrets: () => this.client.claimWorkflowJobSecrets(claimed.id),
15973
+ appendCommandOutput: (attemptId, chunks) => this.client.appendCommandOutput(claimed.id, attemptId, chunks)
15531
15974
  }
15532
15975
  );
15533
15976
  const codebaseId = claimed.payload && typeof claimed.payload === "object" && !Array.isArray(claimed.payload) && typeof claimed.payload.codebaseId === "string" ? String(claimed.payload.codebaseId) : null;
@@ -15703,8 +16146,8 @@ var CodebaseMonitor = class {
15703
16146
 
15704
16147
  // src/runs/run-manager.ts
15705
16148
  import { execFile as execFile4 } from "node:child_process";
15706
- import { mkdir as mkdir6, rm as rm12 } from "node:fs/promises";
15707
- import { dirname as dirname8, join as join14 } from "node:path";
16149
+ import { mkdir as mkdir6, rm as rm13 } from "node:fs/promises";
16150
+ import { dirname as dirname8, join as join15 } from "node:path";
15708
16151
  import { promisify as promisify4 } from "node:util";
15709
16152
 
15710
16153
  // src/runs/journal.ts
@@ -15714,10 +16157,10 @@ import {
15714
16157
  mkdir as mkdir5,
15715
16158
  readFile as readFile8,
15716
16159
  rename as rename4,
15717
- rm as rm9,
15718
- writeFile as writeFile6
16160
+ rm as rm10,
16161
+ writeFile as writeFile7
15719
16162
  } from "node:fs/promises";
15720
- import { dirname as dirname7, join as join11 } from "node:path";
16163
+ import { dirname as dirname7, join as join12 } from "node:path";
15721
16164
  var RunJournal = class {
15722
16165
  constructor(runId, attemptId) {
15723
16166
  this.runId = runId;
@@ -15736,13 +16179,13 @@ var RunJournal = class {
15736
16179
  this.attemptId = attemptId;
15737
16180
  }
15738
16181
  get directory() {
15739
- return join11(dirname7(configPath()), "runs", this.runId);
16182
+ return join12(dirname7(configPath()), "runs", this.runId);
15740
16183
  }
15741
16184
  get eventsPath() {
15742
- return join11(this.directory, "events.jsonl");
16185
+ return join12(this.directory, "events.jsonl");
15743
16186
  }
15744
16187
  get statePath() {
15745
- return join11(this.directory, "state.json");
16188
+ return join12(this.directory, "state.json");
15746
16189
  }
15747
16190
  async load() {
15748
16191
  if (this.loaded) return;
@@ -15843,10 +16286,10 @@ var RunJournal = class {
15843
16286
  const operation = this.saving.then(async () => {
15844
16287
  const temporary = `${this.statePath}.${process.pid}.${randomUUID4()}.tmp`;
15845
16288
  try {
15846
- await writeFile6(temporary, contents, { mode: 384 });
16289
+ await writeFile7(temporary, contents, { mode: 384 });
15847
16290
  await rename4(temporary, this.statePath);
15848
16291
  } catch (error) {
15849
- await rm9(temporary, { force: true }).catch(() => void 0);
16292
+ await rm10(temporary, { force: true }).catch(() => void 0);
15850
16293
  throw error;
15851
16294
  }
15852
16295
  });
@@ -25020,7 +25463,7 @@ function Yy(e) {
25020
25463
  var l = {};
25021
25464
  lt(l, { xid: () => u9, void: () => I9, uuidv7: () => n9, uuidv6: () => r9, uuidv4: () => t9, uuid: () => e9, url: () => o9, uppercase: () => Fl, unknown: () => Ke, union: () => $e, undefined: () => C9, ulid: () => l9, uint64: () => A9, uint32: () => w9, tuple: () => L9, trim: () => Wl, treeifyError: () => Yd, transform: () => jv, toUpperCase: () => Zl, toLowerCase: () => Kl, toJSONSchema: () => Js, templateLiteral: () => q9, symbol: () => O9, superRefine: () => ER, success: () => B9, stringbool: () => W9, stringFormat: () => x9, string: () => k, strictObject: () => N9, startsWith: () => Hl, size: () => $l, setErrorMap: () => J9, set: () => $9, safeParseAsync: () => gv, safeParse: () => mv, registry: () => hl, regexes: () => wo, regex: () => jl, refine: () => SR, record: () => je, readonly: () => hR, property: () => iv, promise: () => G9, prettifyError: () => Xd, preprocess: () => Km, prefault: () => lR, positive: () => tv, pipe: () => Fm, partialRecord: () => M9, parseAsync: () => fv, parse: () => dv, overwrite: () => Vn, optional: () => Ve, object: () => G, number: () => Ce, nullish: () => F9, nullable: () => zm, null: () => Bm, normalize: () => Vl, nonpositive: () => nv, nonoptional: () => uR, nonnegative: () => ov, never: () => Hm, negative: () => rv, nativeEnum: () => j9, nanoid: () => s9, nan: () => H9, multipleOf: () => wi, minSize: () => Ti, minLength: () => Ao, mime: () => Gl, maxSize: () => Ws, maxLength: () => Ks, map: () => U9, lte: () => Ur, lt: () => qn, lowercase: () => zl, looseObject: () => Bt, locales: () => Gs, literal: () => Z, length: () => Zs, lazy: () => bR, ksuid: () => p9, keyof: () => D9, jwt: () => b9, json: () => K9, iso: () => Ys, ipv6: () => f9, ipv4: () => d9, intersection: () => ru, int64: () => k9, int32: () => E9, int: () => hv, instanceof: () => V9, includes: () => Bl, guid: () => QZ, gte: () => ar, gt: () => Gn, globalRegistry: () => sr, getErrorMap: () => Y9, function: () => Dm, formatError: () => js, float64: () => S9, float32: () => v9, flattenError: () => $s, file: () => z9, enum: () => Jt, endsWith: () => ql, emoji: () => i9, email: () => XZ, e164: () => y9, discriminatedUnion: () => Vm, date: () => P9, custom: () => Hv, cuid2: () => c9, cuid: () => a9, core: () => Qr, config: () => ut, coerce: () => qv, clone: () => Ft, cidrv6: () => g9, cidrv4: () => m9, check: () => vR, catch: () => fR, boolean: () => ht, bigint: () => T9, base64url: () => _9, base64: () => h9, array: () => he, any: () => R9, _default: () => aR, _ZodString: () => _v, ZodXID: () => Tv, ZodVoid: () => JC, ZodUnknown: () => KC, ZodUnion: () => Mv, ZodUndefined: () => GC, ZodUUID: () => Wn, ZodURL: () => bv, ZodULID: () => wv, ZodType: () => de, ZodTuple: () => eR, ZodTransform: () => $v, ZodTemplateLiteral: () => _R, ZodSymbol: () => qC, ZodSuccess: () => pR, ZodStringFormat: () => Ge, ZodString: () => Xl, ZodSet: () => rR, ZodRecord: () => Uv, ZodRealError: () => Xs, ZodReadonly: () => gR, ZodPromise: () => xR, ZodPrefault: () => cR, ZodPipe: () => Bv, ZodOptional: () => zv, ZodObject: () => Gm, ZodNumberFormat: () => Qs, ZodNumber: () => Ql, ZodNullable: () => iR, ZodNull: () => VC, ZodNonOptional: () => Fv, ZodNever: () => ZC, ZodNanoID: () => vv, ZodNaN: () => mR, ZodMap: () => tR, ZodLiteral: () => nR, ZodLazy: () => yR, ZodKSUID: () => kv, ZodJWT: () => Nv, ZodIssueCode: () => Z9, ZodIntersection: () => QC, ZodISOTime: () => Um, ZodISODuration: () => $m, ZodISODateTime: () => Lm, ZodISODate: () => Mm, ZodIPv6: () => Ov, ZodIPv4: () => Av, ZodGUID: () => jm, ZodFile: () => oR, ZodError: () => JZ, ZodEnum: () => Yl, ZodEmoji: () => xv, ZodEmail: () => yv, ZodE164: () => Dv, ZodDiscriminatedUnion: () => XC, ZodDefault: () => sR, ZodDate: () => qm, ZodCustomStringFormat: () => HC, ZodCustom: () => Wm, ZodCatch: () => dR, ZodCUID2: () => Ev, ZodCUID: () => Sv, ZodCIDRv6: () => Rv, ZodCIDRv4: () => Cv, ZodBoolean: () => eu, ZodBigIntFormat: () => Lv, ZodBigInt: () => tu, ZodBase64URL: () => Pv, ZodBase64: () => Iv, ZodArray: () => YC, ZodAny: () => WC, TimePrecision: () => lm, NEVER: () => Kd, $output: () => sm, $input: () => am, $brand: () => Zd });
25022
25465
  var Qr = {};
25023
- lt(Qr, { version: () => tx, util: () => M, treeifyError: () => Yd, toJSONSchema: () => Js, toDotPath: () => yC, safeParseAsync: () => Eo, safeParse: () => So, registry: () => hl, regexes: () => wo, prettifyError: () => Xd, parseAsync: () => xi, parse: () => bi, locales: () => Gs, isValidJWT: () => MC, isValidBase64URL: () => LC, isValidBase64: () => ax, globalRegistry: () => sr, globalConfig: () => tl, function: () => Dm, formatError: () => js, flattenError: () => $s, config: () => ut, clone: () => Ft, _xid: () => Ol, _void: () => Tm, _uuidv7: () => vl, _uuidv6: () => xl, _uuidv4: () => bl, _uuid: () => yl, _url: () => Sl, _uppercase: () => Fl, _unknown: () => Ei, _union: () => OZ, _undefined: () => vm, _ulid: () => Al, _uint64: () => bm, _uint32: () => gm, _tuple: () => sv, _trim: () => Wl, _transform: () => UZ, _toUpperCase: () => Zl, _toLowerCase: () => Kl, _templateLiteral: () => VZ, _symbol: () => xm, _success: () => BZ, _stringbool: () => Im, _stringFormat: () => Pm, _string: () => cm, _startsWith: () => Hl, _size: () => $l, _set: () => DZ, _safeParseAsync: () => rf, _safeParse: () => tf, _regex: () => jl, _refine: () => Rm, _record: () => IZ, _readonly: () => GZ, _property: () => iv, _promise: () => KZ, _positive: () => tv, _pipe: () => qZ, _parseAsync: () => ef, _parse: () => Qd, _overwrite: () => Vn, _optional: () => $Z, _number: () => um, _nullable: () => jZ, _null: () => Sm, _normalize: () => Vl, _nonpositive: () => nv, _nonoptional: () => FZ, _nonnegative: () => ov, _never: () => wm, _negative: () => rv, _nativeEnum: () => LZ, _nanoid: () => wl, _nan: () => Am, _multipleOf: () => wi, _minSize: () => Ti, _minLength: () => Ao, _min: () => ar, _mime: () => Gl, _maxSize: () => Ws, _maxLength: () => Ks, _max: () => Ur, _map: () => PZ, _lte: () => Ur, _lt: () => qn, _lowercase: () => zl, _literal: () => MZ, _length: () => Zs, _lazy: () => WZ, _ksuid: () => Cl, _jwt: () => Ul, _isoTime: () => Zx, _isoDuration: () => Jx, _isoDateTime: () => Wx, _isoDate: () => Kx, _ipv6: () => Il, _ipv4: () => Rl, _intersection: () => RZ, _int64: () => ym, _int32: () => mm, _int: () => pm, _includes: () => Bl, _guid: () => Vs, _gte: () => ar, _gt: () => Gn, _float64: () => fm, _float32: () => dm, _file: () => Om, _enum: () => NZ, _endsWith: () => ql, _emoji: () => El, _email: () => _l, _e164: () => Ml, _discriminatedUnion: () => CZ, _default: () => zZ, _date: () => km, _custom: () => Cm, _cuid2: () => kl, _cuid: () => Tl, _coercedString: () => Vx, _coercedNumber: () => Yx, _coercedDate: () => ev, _coercedBoolean: () => Xx, _coercedBigint: () => Qx, _cidrv6: () => Dl, _cidrv4: () => Pl, _catch: () => HZ, _boolean: () => hm, _bigint: () => _m, _base64url: () => Ll, _base64: () => Nl, _array: () => Jl, _any: () => Em, TimePrecision: () => lm, NEVER: () => Kd, JSONSchemaGenerator: () => Nm, JSONSchema: () => zC, Doc: () => af, $output: () => sm, $input: () => am, $constructor: () => S, $brand: () => Zd, $ZodXID: () => bf, $ZodVoid: () => Uf, $ZodUnknown: () => Si, $ZodUnion: () => fl, $ZodUndefined: () => Df, $ZodUUID: () => pf, $ZodURL: () => ff, $ZodULID: () => yf, $ZodType: () => ie, $ZodTuple: () => ko, $ZodTransform: () => Hs, $ZodTemplateLiteral: () => rm10, $ZodSymbol: () => Pf, $ZodSuccess: () => Xf, $ZodStringFormat: () => Ue, $ZodString: () => To, $ZodSet: () => Hf, $ZodRegistry: () => gl, $ZodRecord: () => Ff, $ZodRealError: () => Us, $ZodReadonly: () => tm, $ZodPromise: () => nm, $ZodPrefault: () => Jf, $ZodPipe: () => qs, $ZodOptional: () => Wf, $ZodObject: () => dl, $ZodNumberFormat: () => Rf, $ZodNumber: () => ul, $ZodNullable: () => Kf, $ZodNull: () => Nf, $ZodNonOptional: () => Yf, $ZodNever: () => Mf, $ZodNanoID: () => gf, $ZodNaN: () => em, $ZodMap: () => Bf, $ZodLiteral: () => Gf, $ZodLazy: () => om, $ZodKSUID: () => xf, $ZodJWT: () => Of, $ZodIntersection: () => zf, $ZodISOTime: () => ix, $ZodISODuration: () => sx, $ZodISODateTime: () => nx, $ZodISODate: () => ox, $ZodIPv6: () => Sf, $ZodIPv4: () => vf, $ZodGUID: () => uf, $ZodFunction: () => av, $ZodFile: () => Vf, $ZodError: () => ll, $ZodEnum: () => qf, $ZodEmoji: () => mf, $ZodEmail: () => df, $ZodE164: () => Af, $ZodDiscriminatedUnion: () => jf, $ZodDefault: () => Zf, $ZodDate: () => $f, $ZodCustomStringFormat: () => Cf, $ZodCustom: () => im, $ZodCheckUpperCase: () => Kb, $ZodCheckStringFormat: () => zs, $ZodCheckStartsWith: () => Jb, $ZodCheckSizeEquals: () => Bb, $ZodCheckRegex: () => Vb, $ZodCheckProperty: () => Xb, $ZodCheckOverwrite: () => ex, $ZodCheckNumberFormat: () => $b, $ZodCheckMultipleOf: () => Ub, $ZodCheckMinSize: () => Fb, $ZodCheckMinLength: () => qb, $ZodCheckMimeType: () => Qb, $ZodCheckMaxSize: () => zb, $ZodCheckMaxLength: () => Hb, $ZodCheckLowerCase: () => Wb, $ZodCheckLessThan: () => of, $ZodCheckLengthEquals: () => Gb, $ZodCheckIncludes: () => Zb, $ZodCheckGreaterThan: () => sf, $ZodCheckEndsWith: () => Yb, $ZodCheckBigIntFormat: () => jb, $ZodCheck: () => Xe, $ZodCatch: () => Qf, $ZodCUID2: () => _f, $ZodCUID: () => hf, $ZodCIDRv6: () => wf, $ZodCIDRv4: () => Ef, $ZodBoolean: () => Fs, $ZodBigIntFormat: () => If, $ZodBigInt: () => pl, $ZodBase64URL: () => kf, $ZodBase64: () => Tf, $ZodAsyncError: () => Bn, $ZodArray: () => Bs, $ZodAny: () => Lf });
25466
+ lt(Qr, { version: () => tx, util: () => M, treeifyError: () => Yd, toJSONSchema: () => Js, toDotPath: () => yC, safeParseAsync: () => Eo, safeParse: () => So, registry: () => hl, regexes: () => wo, prettifyError: () => Xd, parseAsync: () => xi, parse: () => bi, locales: () => Gs, isValidJWT: () => MC, isValidBase64URL: () => LC, isValidBase64: () => ax, globalRegistry: () => sr, globalConfig: () => tl, function: () => Dm, formatError: () => js, flattenError: () => $s, config: () => ut, clone: () => Ft, _xid: () => Ol, _void: () => Tm, _uuidv7: () => vl, _uuidv6: () => xl, _uuidv4: () => bl, _uuid: () => yl, _url: () => Sl, _uppercase: () => Fl, _unknown: () => Ei, _union: () => OZ, _undefined: () => vm, _ulid: () => Al, _uint64: () => bm, _uint32: () => gm, _tuple: () => sv, _trim: () => Wl, _transform: () => UZ, _toUpperCase: () => Zl, _toLowerCase: () => Kl, _templateLiteral: () => VZ, _symbol: () => xm, _success: () => BZ, _stringbool: () => Im, _stringFormat: () => Pm, _string: () => cm, _startsWith: () => Hl, _size: () => $l, _set: () => DZ, _safeParseAsync: () => rf, _safeParse: () => tf, _regex: () => jl, _refine: () => Rm, _record: () => IZ, _readonly: () => GZ, _property: () => iv, _promise: () => KZ, _positive: () => tv, _pipe: () => qZ, _parseAsync: () => ef, _parse: () => Qd, _overwrite: () => Vn, _optional: () => $Z, _number: () => um, _nullable: () => jZ, _null: () => Sm, _normalize: () => Vl, _nonpositive: () => nv, _nonoptional: () => FZ, _nonnegative: () => ov, _never: () => wm, _negative: () => rv, _nativeEnum: () => LZ, _nanoid: () => wl, _nan: () => Am, _multipleOf: () => wi, _minSize: () => Ti, _minLength: () => Ao, _min: () => ar, _mime: () => Gl, _maxSize: () => Ws, _maxLength: () => Ks, _max: () => Ur, _map: () => PZ, _lte: () => Ur, _lt: () => qn, _lowercase: () => zl, _literal: () => MZ, _length: () => Zs, _lazy: () => WZ, _ksuid: () => Cl, _jwt: () => Ul, _isoTime: () => Zx, _isoDuration: () => Jx, _isoDateTime: () => Wx, _isoDate: () => Kx, _ipv6: () => Il, _ipv4: () => Rl, _intersection: () => RZ, _int64: () => ym, _int32: () => mm, _int: () => pm, _includes: () => Bl, _guid: () => Vs, _gte: () => ar, _gt: () => Gn, _float64: () => fm, _float32: () => dm, _file: () => Om, _enum: () => NZ, _endsWith: () => ql, _emoji: () => El, _email: () => _l, _e164: () => Ml, _discriminatedUnion: () => CZ, _default: () => zZ, _date: () => km, _custom: () => Cm, _cuid2: () => kl, _cuid: () => Tl, _coercedString: () => Vx, _coercedNumber: () => Yx, _coercedDate: () => ev, _coercedBoolean: () => Xx, _coercedBigint: () => Qx, _cidrv6: () => Dl, _cidrv4: () => Pl, _catch: () => HZ, _boolean: () => hm, _bigint: () => _m, _base64url: () => Ll, _base64: () => Nl, _array: () => Jl, _any: () => Em, TimePrecision: () => lm, NEVER: () => Kd, JSONSchemaGenerator: () => Nm, JSONSchema: () => zC, Doc: () => af, $output: () => sm, $input: () => am, $constructor: () => S, $brand: () => Zd, $ZodXID: () => bf, $ZodVoid: () => Uf, $ZodUnknown: () => Si, $ZodUnion: () => fl, $ZodUndefined: () => Df, $ZodUUID: () => pf, $ZodURL: () => ff, $ZodULID: () => yf, $ZodType: () => ie, $ZodTuple: () => ko, $ZodTransform: () => Hs, $ZodTemplateLiteral: () => rm11, $ZodSymbol: () => Pf, $ZodSuccess: () => Xf, $ZodStringFormat: () => Ue, $ZodString: () => To, $ZodSet: () => Hf, $ZodRegistry: () => gl, $ZodRecord: () => Ff, $ZodRealError: () => Us, $ZodReadonly: () => tm, $ZodPromise: () => nm, $ZodPrefault: () => Jf, $ZodPipe: () => qs, $ZodOptional: () => Wf, $ZodObject: () => dl, $ZodNumberFormat: () => Rf, $ZodNumber: () => ul, $ZodNullable: () => Kf, $ZodNull: () => Nf, $ZodNonOptional: () => Yf, $ZodNever: () => Mf, $ZodNanoID: () => gf, $ZodNaN: () => em, $ZodMap: () => Bf, $ZodLiteral: () => Gf, $ZodLazy: () => om, $ZodKSUID: () => xf, $ZodJWT: () => Of, $ZodIntersection: () => zf, $ZodISOTime: () => ix, $ZodISODuration: () => sx, $ZodISODateTime: () => nx, $ZodISODate: () => ox, $ZodIPv6: () => Sf, $ZodIPv4: () => vf, $ZodGUID: () => uf, $ZodFunction: () => av, $ZodFile: () => Vf, $ZodError: () => ll, $ZodEnum: () => qf, $ZodEmoji: () => mf, $ZodEmail: () => df, $ZodE164: () => Af, $ZodDiscriminatedUnion: () => jf, $ZodDefault: () => Zf, $ZodDate: () => $f, $ZodCustomStringFormat: () => Cf, $ZodCustom: () => im, $ZodCheckUpperCase: () => Kb, $ZodCheckStringFormat: () => zs, $ZodCheckStartsWith: () => Jb, $ZodCheckSizeEquals: () => Bb, $ZodCheckRegex: () => Vb, $ZodCheckProperty: () => Xb, $ZodCheckOverwrite: () => ex, $ZodCheckNumberFormat: () => $b, $ZodCheckMultipleOf: () => Ub, $ZodCheckMinSize: () => Fb, $ZodCheckMinLength: () => qb, $ZodCheckMimeType: () => Qb, $ZodCheckMaxSize: () => zb, $ZodCheckMaxLength: () => Hb, $ZodCheckLowerCase: () => Wb, $ZodCheckLessThan: () => of, $ZodCheckLengthEquals: () => Gb, $ZodCheckIncludes: () => Zb, $ZodCheckGreaterThan: () => sf, $ZodCheckEndsWith: () => Yb, $ZodCheckBigIntFormat: () => jb, $ZodCheck: () => Xe, $ZodCatch: () => Qf, $ZodCUID2: () => _f, $ZodCUID: () => hf, $ZodCIDRv6: () => wf, $ZodCIDRv4: () => Ef, $ZodBoolean: () => Fs, $ZodBigIntFormat: () => If, $ZodBigInt: () => pl, $ZodBase64URL: () => kf, $ZodBase64: () => Tf, $ZodAsyncError: () => Bn, $ZodArray: () => Bs, $ZodAny: () => Lf });
25024
25467
  var Kd = Object.freeze({ status: "aborted" });
25025
25468
  function S(e, t, r) {
25026
25469
  function n(a, c) {
@@ -26568,7 +27011,7 @@ var tm = S("$ZodReadonly", (e, t) => {
26568
27011
  function DC(e) {
26569
27012
  return e.value = Object.freeze(e.value), e;
26570
27013
  }
26571
- var rm10 = S("$ZodTemplateLiteral", (e, t) => {
27014
+ var rm11 = S("$ZodTemplateLiteral", (e, t) => {
26572
27015
  ie.init(e, t);
26573
27016
  let r = [];
26574
27017
  for (let n of t.parts) if (n instanceof ie) {
@@ -30375,7 +30818,7 @@ function hR(e) {
30375
30818
  return new gR({ type: "readonly", innerType: e });
30376
30819
  }
30377
30820
  var _R = S("ZodTemplateLiteral", (e, t) => {
30378
- rm10.init(e, t), de.init(e, t);
30821
+ rm11.init(e, t), de.init(e, t);
30379
30822
  });
30380
30823
  function q9(e, t) {
30381
30824
  return new _R({ type: "template_literal", parts: e, ...M.normalizeParams(t) });
@@ -41994,11 +42437,11 @@ var ClaudeAdapter = class {
41994
42437
  // src/runs/codex-adapter.ts
41995
42438
  import {
41996
42439
  execFile as execFile3,
41997
- spawn as spawn6
42440
+ spawn as spawn7
41998
42441
  } from "node:child_process";
41999
- import { mkdtemp as mkdtemp6, rm as rm11, writeFile as writeFile7 } from "node:fs/promises";
42000
- import { tmpdir as tmpdir6 } from "node:os";
42001
- import { join as join13 } from "node:path";
42442
+ import { mkdtemp as mkdtemp7, rm as rm12, writeFile as writeFile8 } from "node:fs/promises";
42443
+ import { tmpdir as tmpdir7 } from "node:os";
42444
+ import { join as join14 } from "node:path";
42002
42445
  import { createInterface } from "node:readline";
42003
42446
  import { promisify as promisify3 } from "node:util";
42004
42447
  var SUPPORTED_CODEX_APP_SERVER_MINORS = ["0.144", "0.145"];
@@ -42056,7 +42499,7 @@ var CodexAppServer = class {
42056
42499
  async start() {
42057
42500
  const modelCatalogPath = await this.createBundledModelCatalog();
42058
42501
  const modelCatalogDirectory = this.modelCatalogDirectory;
42059
- const child = spawn6("codex", codexAppServerArgs(modelCatalogPath), {
42502
+ const child = spawn7("codex", codexAppServerArgs(modelCatalogPath), {
42060
42503
  stdio: ["pipe", "pipe", "pipe"],
42061
42504
  env: process.env
42062
42505
  });
@@ -42125,7 +42568,7 @@ var CodexAppServer = class {
42125
42568
  }
42126
42569
  }
42127
42570
  async createBundledModelCatalog() {
42128
- const directory = await mkdtemp6(join13(tmpdir6(), "aide-codex-models-"));
42571
+ const directory = await mkdtemp7(join14(tmpdir7(), "aide-codex-models-"));
42129
42572
  try {
42130
42573
  const { stdout } = await execFileAsync2(
42131
42574
  "codex",
@@ -42135,12 +42578,12 @@ var CodexAppServer = class {
42135
42578
  maxBuffer: 16 * 1024 * 1024
42136
42579
  }
42137
42580
  );
42138
- const catalogPath = join13(directory, "models.json");
42139
- await writeFile7(catalogPath, stdout, "utf8");
42581
+ const catalogPath = join14(directory, "models.json");
42582
+ await writeFile8(catalogPath, stdout, "utf8");
42140
42583
  this.modelCatalogDirectory = directory;
42141
42584
  return catalogPath;
42142
42585
  } catch (error) {
42143
- await rm11(directory, { recursive: true, force: true }).catch(
42586
+ await rm12(directory, { recursive: true, force: true }).catch(
42144
42587
  () => void 0
42145
42588
  );
42146
42589
  throw error;
@@ -42151,7 +42594,7 @@ var CodexAppServer = class {
42151
42594
  if (this.modelCatalogDirectory === directory) {
42152
42595
  this.modelCatalogDirectory = void 0;
42153
42596
  }
42154
- await rm11(directory, { recursive: true, force: true }).catch(
42597
+ await rm12(directory, { recursive: true, force: true }).catch(
42155
42598
  () => void 0
42156
42599
  );
42157
42600
  }
@@ -48829,7 +49272,7 @@ var RunManager = class {
48829
49272
  5
48830
49273
  );
48831
49274
  await this.completeCommand(command3.id, "SUCCEEDED");
48832
- await rm12(join14(dirname8(configPath()), "runs", run.id, "attachments"), {
49275
+ await rm13(join15(dirname8(configPath()), "runs", run.id, "attachments"), {
48833
49276
  recursive: true,
48834
49277
  force: true
48835
49278
  }).catch(() => void 0);
@@ -49010,7 +49453,7 @@ var RunManager = class {
49010
49453
  this.active.delete(run.id);
49011
49454
  this.interruptionRequests.delete(run.id);
49012
49455
  this.executingCommands.delete(command3.id);
49013
- await rm12(join14(dirname8(configPath()), "runs", run.id, "attachments"), {
49456
+ await rm13(join15(dirname8(configPath()), "runs", run.id, "attachments"), {
49014
49457
  recursive: true,
49015
49458
  force: true
49016
49459
  }).catch(() => void 0);
@@ -49238,11 +49681,11 @@ var RunManager = class {
49238
49681
  }
49239
49682
  async stageAttachments(runId, attachments) {
49240
49683
  if (!attachments.length) return [];
49241
- const directory = join14(dirname8(configPath()), "runs", runId, "attachments");
49684
+ const directory = join15(dirname8(configPath()), "runs", runId, "attachments");
49242
49685
  await mkdir6(directory, { recursive: true, mode: 448 });
49243
49686
  return Promise.all(
49244
49687
  attachments.map(async (attachment) => {
49245
- const path = join14(
49688
+ const path = join15(
49246
49689
  directory,
49247
49690
  `${attachment.id}-${safeFilename(attachment.filename)}`
49248
49691
  );
@@ -49358,6 +49801,10 @@ var RunManager = class {
49358
49801
  }
49359
49802
  };
49360
49803
 
49804
+ // ../agent-contract/src/disk-space.ts
49805
+ var DISK_SPACE_POLL_INTERVAL_SECONDS = 60;
49806
+ var DISK_SPACE_STALE_AFTER_SECONDS = DISK_SPACE_POLL_INTERVAL_SECONDS * 2;
49807
+
49361
49808
  // src/agent-runtime.ts
49362
49809
  function configuredIntervalMs(value, fallbackSeconds, minSeconds, maxSeconds) {
49363
49810
  return (Number.isInteger(value) && value >= minSeconds && value <= maxSeconds ? value : fallbackSeconds) * 1e3;
@@ -49380,6 +49827,9 @@ async function runAgent(config, signal) {
49380
49827
  let heartbeatTimer;
49381
49828
  let jobReconciliationTimer;
49382
49829
  let codebaseTimer;
49830
+ let diskSpaceTimer;
49831
+ let diskSpaceRunning = false;
49832
+ let diskSpaceIntervalMs = DISK_SPACE_POLL_INTERVAL_SECONDS * 1e3;
49383
49833
  let startupRecoveryPending = true;
49384
49834
  const interruptedJobs = /* @__PURE__ */ new Set();
49385
49835
  const reconcileJobs = async (recoverInterrupted) => {
@@ -49399,6 +49849,12 @@ async function runAgent(config, signal) {
49399
49849
  executor.cancel(job.id);
49400
49850
  return;
49401
49851
  }
49852
+ if (job.status === "CANCELLING") {
49853
+ if (!executor.cancel(job.id)) {
49854
+ await client2.completeJob(job.id, "CANCELLED");
49855
+ }
49856
+ return;
49857
+ }
49402
49858
  if (job.status !== "RUNNING" || !recoverInterrupted && !interruptedJobs.has(job.id)) {
49403
49859
  executor.execute(job);
49404
49860
  return;
@@ -49527,11 +49983,48 @@ async function runAgent(config, signal) {
49527
49983
  codebaseTimer = void 0;
49528
49984
  void reconcileCodebases();
49529
49985
  };
49986
+ const scheduleDiskSpacePoll = () => {
49987
+ if (diskSpaceTimer) clearTimeout(diskSpaceTimer);
49988
+ if (!signal.aborted) {
49989
+ diskSpaceTimer = setTimeout(
49990
+ () => void runDiskSpacePoll(),
49991
+ diskSpaceIntervalMs
49992
+ );
49993
+ }
49994
+ };
49995
+ const runDiskSpacePoll = async () => {
49996
+ if (diskSpaceRunning || signal.aborted) return;
49997
+ diskSpaceRunning = true;
49998
+ if (diskSpaceTimer) clearTimeout(diskSpaceTimer);
49999
+ diskSpaceTimer = void 0;
50000
+ try {
50001
+ const configuration = await client2.diskSpaceConfiguration();
50002
+ diskSpaceIntervalMs = Math.max(
50003
+ 1e3,
50004
+ configuration.pollIntervalSeconds * 1e3
50005
+ );
50006
+ if (configuration.enabled) {
50007
+ const report = await collectAgentDiskSpace(configuration, signal);
50008
+ await client2.reportDiskSpace(report);
50009
+ }
50010
+ } catch (error) {
50011
+ if (!signal.aborted) {
50012
+ console.error(
50013
+ "Disk space poll failed:",
50014
+ error instanceof Error ? error.message : error
50015
+ );
50016
+ }
50017
+ } finally {
50018
+ diskSpaceRunning = false;
50019
+ scheduleDiskSpacePoll();
50020
+ }
50021
+ };
49530
50022
  await refreshCadence();
49531
50023
  await heartbeat();
49532
50024
  await runJobReconciliation();
49533
50025
  await runManager.start();
49534
50026
  void reconcileCodebases();
50027
+ void runDiskSpacePoll();
49535
50028
  const subscriptionClient = createAgentSubscriptionClient(config);
49536
50029
  const unsubscribe = subscribeToAgentEvents(
49537
50030
  subscriptionClient,
@@ -49544,11 +50037,14 @@ async function runAgent(config, signal) {
49544
50037
  requestCodebaseReconcile();
49545
50038
  } else if (event.type === "RUN_COMMAND_AVAILABLE") {
49546
50039
  runManager.execute(event.runCommand);
50040
+ } else if (event.type === "DISK_SPACE_POLL_REQUESTED") {
50041
+ void runDiskSpacePoll();
49547
50042
  } else {
49548
50043
  void refreshCadence().then(() => {
49549
50044
  scheduleHeartbeat();
49550
50045
  scheduleJobReconciliation();
49551
50046
  requestCodebaseReconcile();
50047
+ void runDiskSpacePoll();
49552
50048
  });
49553
50049
  }
49554
50050
  }
@@ -49560,6 +50056,7 @@ async function runAgent(config, signal) {
49560
50056
  if (heartbeatTimer) clearTimeout(heartbeatTimer);
49561
50057
  if (jobReconciliationTimer) clearTimeout(jobReconciliationTimer);
49562
50058
  if (codebaseTimer) clearTimeout(codebaseTimer);
50059
+ if (diskSpaceTimer) clearTimeout(diskSpaceTimer);
49563
50060
  unsubscribe();
49564
50061
  await subscriptionClient.dispose();
49565
50062
  await executor.cancelAll();
@@ -49699,7 +50196,6 @@ function redactedRequestHeaders(headers) {
49699
50196
  }
49700
50197
 
49701
50198
  // src/index.ts
49702
- var execFileAsync4 = promisify5(execFile5);
49703
50199
  function flags(args) {
49704
50200
  const result = {};
49705
50201
  const headerValues = [];
@@ -49802,22 +50298,6 @@ async function doctor() {
49802
50298
  detail: error instanceof Error ? error.message : String(error)
49803
50299
  });
49804
50300
  }
49805
- try {
49806
- const { stdout, stderr } = await execFileAsync4("cloudflared", [
49807
- "--version"
49808
- ]);
49809
- checks.push({
49810
- check: "cloudflared",
49811
- ok: true,
49812
- detail: (stdout || stderr).trim()
49813
- });
49814
- } catch (error) {
49815
- checks.push({
49816
- check: "cloudflared",
49817
- ok: false,
49818
- detail: error instanceof Error ? error.message : String(error)
49819
- });
49820
- }
49821
50301
  for (const check of checks)
49822
50302
  console.log(
49823
50303
  `${check.ok ? "PASS" : "FAIL"} ${check.check}: ${check.detail}`
@@ -49835,21 +50315,26 @@ async function main() {
49835
50315
  if (command3 === "doctor") return doctor();
49836
50316
  if (command3 === "run" || command3 === "dev") {
49837
50317
  const controller = new AbortController();
49838
- process.once("SIGINT", () => controller.abort());
49839
- process.once("SIGTERM", () => controller.abort());
49840
- if (command3 === "dev") {
49841
- const options = flags(args).values;
49842
- const server = options.server ?? process.env.CONTROL_AGENT_DEV_SERVER ?? `http://127.0.0.1:${process.env.PORT ?? "3000"}`;
49843
- return runDevelopmentAgent(
49844
- {
49845
- server,
49846
- websocketServer: options["websocket-server"] ?? process.env.CONTROL_AGENT_DEV_WEBSOCKET_SERVER ?? process.env.NEXT_PUBLIC_AGENT_WS_URL,
49847
- name: options.name
49848
- },
49849
- controller.signal
49850
- );
50318
+ const stop2 = () => controller.abort();
50319
+ const shutdownSignals = ["SIGINT", "SIGTERM", "SIGHUP"];
50320
+ for (const signal of shutdownSignals) process.once(signal, stop2);
50321
+ try {
50322
+ if (command3 === "dev") {
50323
+ const options = flags(args).values;
50324
+ const server = options.server ?? process.env.CONTROL_AGENT_DEV_SERVER ?? `http://127.0.0.1:${process.env.PORT ?? "3000"}`;
50325
+ return await runDevelopmentAgent(
50326
+ {
50327
+ server,
50328
+ websocketServer: options["websocket-server"] ?? process.env.CONTROL_AGENT_DEV_WEBSOCKET_SERVER ?? process.env.NEXT_PUBLIC_AGENT_WS_URL,
50329
+ name: options.name
50330
+ },
50331
+ controller.signal
50332
+ );
50333
+ }
50334
+ return await runAgent(await loadConfig(), controller.signal);
50335
+ } finally {
50336
+ for (const signal of shutdownSignals) process.off(signal, stop2);
49851
50337
  }
49852
- return runAgent(await loadConfig(), controller.signal);
49853
50338
  }
49854
50339
  throw new Error(`Unknown command: ${command3}`);
49855
50340
  }