@ai-development-environment/control-agent 0.0.88 → 0.0.90

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/control-agent.js +1650 -327
  2. package/package.json +1 -1
@@ -2276,7 +2276,7 @@ var require_websocket = __commonJS({
2276
2276
  var http = __require("http");
2277
2277
  var net = __require("net");
2278
2278
  var tls = __require("tls");
2279
- var { randomBytes, createHash: createHash7 } = __require("crypto");
2279
+ var { randomBytes, createHash: createHash8 } = __require("crypto");
2280
2280
  var { Duplex, Readable: Readable2 } = __require("stream");
2281
2281
  var { URL: URL2 } = __require("url");
2282
2282
  var PerMessageDeflate2 = require_permessage_deflate();
@@ -2944,7 +2944,7 @@ var require_websocket = __commonJS({
2944
2944
  abortHandshake(websocket, socket, "Invalid Upgrade header");
2945
2945
  return;
2946
2946
  }
2947
- const digest = createHash7("sha1").update(key + GUID).digest("base64");
2947
+ const digest = createHash8("sha1").update(key + GUID).digest("base64");
2948
2948
  if (res.headers["sec-websocket-accept"] !== digest) {
2949
2949
  abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
2950
2950
  return;
@@ -3313,7 +3313,7 @@ var require_websocket_server = __commonJS({
3313
3313
  var EventEmitter = __require("events");
3314
3314
  var http = __require("http");
3315
3315
  var { Duplex } = __require("stream");
3316
- var { createHash: createHash7 } = __require("crypto");
3316
+ var { createHash: createHash8 } = __require("crypto");
3317
3317
  var extension2 = require_extension();
3318
3318
  var PerMessageDeflate2 = require_permessage_deflate();
3319
3319
  var subprotocol2 = require_subprotocol();
@@ -3620,7 +3620,7 @@ var require_websocket_server = __commonJS({
3620
3620
  );
3621
3621
  }
3622
3622
  if (this._state > RUNNING) return abortHandshake(socket, 503);
3623
- const digest = createHash7("sha1").update(key + GUID).digest("base64");
3623
+ const digest = createHash8("sha1").update(key + GUID).digest("base64");
3624
3624
  const headers = [
3625
3625
  "HTTP/1.1 101 Switching Protocols",
3626
3626
  "Upgrade: websocket",
@@ -3801,12 +3801,12 @@ var require_isexe = __commonJS({
3801
3801
  if (typeof Promise !== "function") {
3802
3802
  throw new TypeError("callback not provided");
3803
3803
  }
3804
- return new Promise(function(resolve8, reject) {
3804
+ return new Promise(function(resolve9, reject) {
3805
3805
  isexe(path, options || {}, function(er2, is) {
3806
3806
  if (er2) {
3807
3807
  reject(er2);
3808
3808
  } else {
3809
- resolve8(is);
3809
+ resolve9(is);
3810
3810
  }
3811
3811
  });
3812
3812
  });
@@ -3872,27 +3872,27 @@ var require_which = __commonJS({
3872
3872
  opt = {};
3873
3873
  const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
3874
3874
  const found = [];
3875
- const step = (i) => new Promise((resolve8, reject) => {
3875
+ const step = (i) => new Promise((resolve9, reject) => {
3876
3876
  if (i === pathEnv.length)
3877
- return opt.all && found.length ? resolve8(found) : reject(getNotFoundError(cmd));
3877
+ return opt.all && found.length ? resolve9(found) : reject(getNotFoundError(cmd));
3878
3878
  const ppRaw = pathEnv[i];
3879
3879
  const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
3880
3880
  const pCmd = path.join(pathPart, cmd);
3881
3881
  const p4 = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
3882
- resolve8(subStep(p4, i, 0));
3882
+ resolve9(subStep(p4, i, 0));
3883
3883
  });
3884
- const subStep = (p4, i, ii) => new Promise((resolve8, reject) => {
3884
+ const subStep = (p4, i, ii) => new Promise((resolve9, reject) => {
3885
3885
  if (ii === pathExt.length)
3886
- return resolve8(step(i + 1));
3886
+ return resolve9(step(i + 1));
3887
3887
  const ext = pathExt[ii];
3888
3888
  isexe(p4 + ext, { pathExt: pathExtExe }, (er2, is) => {
3889
3889
  if (!er2 && is) {
3890
3890
  if (opt.all)
3891
3891
  found.push(p4 + ext);
3892
3892
  else
3893
- return resolve8(p4 + ext);
3893
+ return resolve9(p4 + ext);
3894
3894
  }
3895
- return resolve8(subStep(p4, i, ii + 1));
3895
+ return resolve9(subStep(p4, i, ii + 1));
3896
3896
  });
3897
3897
  });
3898
3898
  return cb2 ? step(0).then((res) => cb2(null, res), cb2) : step(0);
@@ -4205,7 +4205,7 @@ var require_cross_spawn = __commonJS({
4205
4205
  });
4206
4206
 
4207
4207
  // src/index.ts
4208
- import { rm as rm14 } from "node:fs/promises";
4208
+ import { rm as rm15 } from "node:fs/promises";
4209
4209
 
4210
4210
  // src/config.ts
4211
4211
  import { chmod, mkdir, readFile, rename, writeFile } from "node:fs/promises";
@@ -4498,8 +4498,8 @@ function createClient(options) {
4498
4498
  retryWait = async function randomisedExponentialBackoff(retries2) {
4499
4499
  const retryDelaySeconds = Math.pow(2, retries2);
4500
4500
  await new Promise(
4501
- (resolve8) => setTimeout(
4502
- resolve8,
4501
+ (resolve9) => setTimeout(
4502
+ resolve9,
4503
4503
  retryDelaySeconds * 1e3 + // add random timeout from 300ms to 3s
4504
4504
  Math.floor(Math.random() * (3e3 - 300) + 300)
4505
4505
  )
@@ -4735,7 +4735,7 @@ function createClient(options) {
4735
4735
  if (socket.readyState === WebSocketImpl.CLOSING) await throwOnClose;
4736
4736
  let release2 = () => {
4737
4737
  };
4738
- const released = new Promise((resolve8) => release2 = resolve8);
4738
+ const released = new Promise((resolve9) => release2 = resolve9);
4739
4739
  return [
4740
4740
  socket,
4741
4741
  release2,
@@ -4898,7 +4898,7 @@ function createClient(options) {
4898
4898
  const iterator = (async function* iterator2() {
4899
4899
  for (; ; ) {
4900
4900
  if (!pending.length) {
4901
- await new Promise((resolve8) => deferred.resolve = resolve8);
4901
+ await new Promise((resolve9) => deferred.resolve = resolve9);
4902
4902
  }
4903
4903
  while (pending.length) {
4904
4904
  yield pending.shift();
@@ -5480,7 +5480,7 @@ function createAgentSubscriptionClient(config) {
5480
5480
  shouldRetry: () => true,
5481
5481
  retryWait: async (retries) => {
5482
5482
  const delay = Math.min(3e4, 1e3 * 2 ** Math.min(retries, 5));
5483
- await new Promise((resolve8) => setTimeout(resolve8, delay));
5483
+ await new Promise((resolve9) => setTimeout(resolve9, delay));
5484
5484
  },
5485
5485
  on: {
5486
5486
  connected: () => console.log("Connected to control-plane WebSocket"),
@@ -6128,6 +6128,7 @@ var WORKTREE_INSPECT_JOB_KIND = "worktree.inspect";
6128
6128
  var WORKTREE_OPERATION_JOB_KIND = "worktree.operation";
6129
6129
  var WORKTREE_COMMIT_JOB_KIND = "worktree.commit";
6130
6130
  var WORKTREE_AUTO_SYNC_JOB_KIND = "worktree.auto-sync";
6131
+ var WORKTREE_PREPARATION_JOB_KIND = "worktree.prepare";
6131
6132
  var WORKTREE_GIT_INSPECT_JOB_KIND = "worktree.git.inspect";
6132
6133
  var WORKTREE_GIT_OPERATION_JOB_KIND = "worktree.git.operation";
6133
6134
  var WORKTREE_WATCH_JOB_KIND = "worktree.watch";
@@ -6142,6 +6143,7 @@ var WORKTREE_JOB_KINDS = [
6142
6143
  WORKTREE_OPERATION_JOB_KIND,
6143
6144
  WORKTREE_COMMIT_JOB_KIND,
6144
6145
  WORKTREE_AUTO_SYNC_JOB_KIND,
6146
+ WORKTREE_PREPARATION_JOB_KIND,
6145
6147
  WORKTREE_GIT_INSPECT_JOB_KIND,
6146
6148
  WORKTREE_GIT_OPERATION_JOB_KIND,
6147
6149
  WORKTREE_WATCH_JOB_KIND,
@@ -6174,6 +6176,16 @@ var WORKTREE_OPERATIONS = [
6174
6176
  "STAGE_ALL",
6175
6177
  "UNSTAGE_ALL"
6176
6178
  ];
6179
+ var WORKTREE_PREPARATION_KINDS = [
6180
+ "WRITE",
6181
+ "DELETE",
6182
+ "ASSUME_UNCHANGED"
6183
+ ];
6184
+ var WORKTREE_PREPARATION_ACTIONS = [
6185
+ "INSPECT",
6186
+ "APPLY",
6187
+ "UNDO"
6188
+ ];
6177
6189
  function validGitBranchName(value) {
6178
6190
  if (!value || value.length > 255 || value === "@" || value.startsWith("-"))
6179
6191
  return false;
@@ -6214,11 +6226,74 @@ function stashOid2(value, name) {
6214
6226
  }
6215
6227
  function safeRelativePath(value, name) {
6216
6228
  const path = stringValue4(value, name).replaceAll("\\", "/");
6217
- if (path.startsWith("/") || /^[A-Za-z]:\//.test(path) || path.split("/").includes("..") || path.includes("\0")) {
6218
- throw new Error(`${name} must stay within the worktree`);
6229
+ const parts = path.split("/");
6230
+ if (!path || path === "." || path.startsWith("/") || /^[A-Za-z]:\//.test(path) || /[\0\r\n]/.test(path) || parts.some((part) => !part || part === "." || part === "..") || parts.some((part) => part.toLowerCase() === ".git")) {
6231
+ throw new Error(`${name} must be an exact file inside the worktree`);
6219
6232
  }
6220
6233
  return path;
6221
6234
  }
6235
+ function safePreparationPath(value, name) {
6236
+ const path = safeRelativePath(value, name);
6237
+ if (/[*?[\]]/.test(path)) {
6238
+ throw new Error(`${name} must be an exact file inside the worktree`);
6239
+ }
6240
+ return path;
6241
+ }
6242
+ function safeDiffPath(value, name) {
6243
+ try {
6244
+ return safeRelativePath(value, name);
6245
+ } catch {
6246
+ throw new Error(`${name} must stay within the worktree`);
6247
+ }
6248
+ }
6249
+ function preparationDefinitions(value, name) {
6250
+ if (!Array.isArray(value) || value.length > 500) {
6251
+ throw new Error(`${name} must be an array with at most 500 items`);
6252
+ }
6253
+ const definitions = value.map((entry, index) => {
6254
+ const item = objectValue4(entry, `${name}[${index}]`);
6255
+ const allowed = /* @__PURE__ */ new Set([
6256
+ "id",
6257
+ "kind",
6258
+ "path",
6259
+ "contentBase64",
6260
+ "definitionHash"
6261
+ ]);
6262
+ const unexpected = Object.keys(item).find((key) => !allowed.has(key));
6263
+ if (unexpected) {
6264
+ throw new Error(`Unexpected ${name}[${index}] field: ${unexpected}`);
6265
+ }
6266
+ if (typeof item.kind !== "string" || !WORKTREE_PREPARATION_KINDS.includes(item.kind)) {
6267
+ throw new Error(`${name}[${index}].kind is invalid`);
6268
+ }
6269
+ const contentBase64 = item.contentBase64 === null || item.contentBase64 === void 0 ? null : typeof item.contentBase64 === "string" ? item.contentBase64 : (() => {
6270
+ throw new Error(
6271
+ `${name}[${index}].contentBase64 must be a string`
6272
+ );
6273
+ })();
6274
+ if (item.kind === "WRITE" && contentBase64 === null) {
6275
+ throw new Error(`${name}[${index}].contentBase64 is required`);
6276
+ }
6277
+ if (item.kind !== "WRITE" && contentBase64 !== null) {
6278
+ throw new Error(`${name}[${index}].contentBase64 is not allowed`);
6279
+ }
6280
+ return {
6281
+ id: stringValue4(item.id, `${name}[${index}].id`),
6282
+ kind: item.kind,
6283
+ path: safePreparationPath(item.path, `${name}[${index}].path`),
6284
+ contentBase64,
6285
+ definitionHash: stringValue4(
6286
+ item.definitionHash,
6287
+ `${name}[${index}].definitionHash`
6288
+ )
6289
+ };
6290
+ });
6291
+ const paths = definitions.map((item) => item.path);
6292
+ if (new Set(paths).size !== paths.length) {
6293
+ throw new Error(`${name} paths must be unique`);
6294
+ }
6295
+ return definitions;
6296
+ }
6222
6297
  function worktreeBranchJobPayload(value) {
6223
6298
  const payload = objectValue4(value, "worktree branch payload");
6224
6299
  const allowed = /* @__PURE__ */ new Set([
@@ -6231,7 +6306,8 @@ function worktreeBranchJobPayload(value) {
6231
6306
  "action",
6232
6307
  "mode",
6233
6308
  "candidates",
6234
- "stashOnFailure"
6309
+ "stashOnFailure",
6310
+ "preparations"
6235
6311
  ]);
6236
6312
  const unexpected = Object.keys(payload).find((key) => !allowed.has(key));
6237
6313
  if (unexpected) {
@@ -6297,7 +6373,11 @@ function worktreeBranchJobPayload(value) {
6297
6373
  action: payload.action,
6298
6374
  mode: payload.mode,
6299
6375
  candidates,
6300
- stashOnFailure: payload.stashOnFailure
6376
+ stashOnFailure: payload.stashOnFailure,
6377
+ preparations: preparationDefinitions(
6378
+ payload.preparations ?? [],
6379
+ "worktree branch payload.preparations"
6380
+ )
6301
6381
  };
6302
6382
  }
6303
6383
  function worktreeMovePushJobPayload(value) {
@@ -6357,7 +6437,8 @@ function worktreeMoveCheckoutJobPayload(value) {
6357
6437
  "expectedHeadSha",
6358
6438
  "baseBranch",
6359
6439
  "mode",
6360
- "stashOnFailure"
6440
+ "stashOnFailure",
6441
+ "preparations"
6361
6442
  ]);
6362
6443
  const unexpected = Object.keys(payload).find((key) => !allowed.has(key));
6363
6444
  if (unexpected) {
@@ -6418,7 +6499,11 @@ function worktreeMoveCheckoutJobPayload(value) {
6418
6499
  "worktree move checkout payload.baseBranch"
6419
6500
  ),
6420
6501
  mode: payload.mode,
6421
- stashOnFailure: payload.stashOnFailure
6502
+ stashOnFailure: payload.stashOnFailure,
6503
+ preparations: preparationDefinitions(
6504
+ payload.preparations ?? [],
6505
+ "worktree move checkout payload.preparations"
6506
+ )
6422
6507
  };
6423
6508
  }
6424
6509
  function worktreeDeleteJobPayload(value) {
@@ -6560,7 +6645,9 @@ function worktreeJobPayload(value) {
6560
6645
  "expectedOrigin",
6561
6646
  "baseBranch",
6562
6647
  "operation",
6563
- "editorVariant"
6648
+ "editorVariant",
6649
+ "forcePreparations",
6650
+ "preparations"
6564
6651
  ]);
6565
6652
  const unexpected = Object.keys(payload).find((key) => !allowed.has(key));
6566
6653
  if (unexpected)
@@ -6573,6 +6660,9 @@ function worktreeJobPayload(value) {
6573
6660
  if (editorVariant !== void 0 && !["CODE", "CODE_INSIDERS", "NONE"].includes(String(editorVariant))) {
6574
6661
  throw new Error("worktree payload.editorVariant is invalid");
6575
6662
  }
6663
+ if (payload.forcePreparations !== void 0 && typeof payload.forcePreparations !== "boolean") {
6664
+ throw new Error("worktree payload.forcePreparations must be a boolean");
6665
+ }
6576
6666
  return {
6577
6667
  codebaseId: stringValue4(payload.codebaseId, "worktree payload.codebaseId"),
6578
6668
  folder: stringValue4(payload.folder, "worktree payload.folder"),
@@ -6589,7 +6679,12 @@ function worktreeJobPayload(value) {
6589
6679
  "worktree payload.baseBranch"
6590
6680
  ),
6591
6681
  ...operation === void 0 ? {} : { operation },
6592
- ...editorVariant === void 0 ? {} : { editorVariant }
6682
+ ...editorVariant === void 0 ? {} : { editorVariant },
6683
+ forcePreparations: payload.forcePreparations === true,
6684
+ preparations: preparationDefinitions(
6685
+ payload.preparations ?? [],
6686
+ "worktree payload.preparations"
6687
+ )
6593
6688
  };
6594
6689
  }
6595
6690
  function worktreeAutoSyncJobPayload(value) {
@@ -6601,7 +6696,9 @@ function worktreeAutoSyncJobPayload(value) {
6601
6696
  "expectedOrigin",
6602
6697
  "expectedBranch",
6603
6698
  "baseBranch",
6604
- "phase"
6699
+ "phase",
6700
+ "forcePreparations",
6701
+ "preparations"
6605
6702
  ]);
6606
6703
  const unexpected = Object.keys(payload).find((key) => !allowed.has(key));
6607
6704
  if (unexpected) {
@@ -6612,6 +6709,11 @@ function worktreeAutoSyncJobPayload(value) {
6612
6709
  if (payload.phase !== "SYNC" && payload.phase !== "FINALIZE") {
6613
6710
  throw new Error("worktree auto sync payload.phase is invalid");
6614
6711
  }
6712
+ if (payload.forcePreparations !== void 0 && typeof payload.forcePreparations !== "boolean") {
6713
+ throw new Error(
6714
+ "worktree auto sync payload.forcePreparations must be a boolean"
6715
+ );
6716
+ }
6615
6717
  return {
6616
6718
  codebaseId: stringValue4(
6617
6719
  payload.codebaseId,
@@ -6634,9 +6736,104 @@ function worktreeAutoSyncJobPayload(value) {
6634
6736
  payload.baseBranch,
6635
6737
  "worktree auto sync payload.baseBranch"
6636
6738
  ),
6637
- phase: payload.phase
6739
+ phase: payload.phase,
6740
+ forcePreparations: payload.forcePreparations === true,
6741
+ preparations: preparationDefinitions(
6742
+ payload.preparations ?? [],
6743
+ "worktree auto sync payload.preparations"
6744
+ )
6638
6745
  };
6639
6746
  }
6747
+ function worktreePreparationJobPayload(value) {
6748
+ const payload = objectValue4(value, "worktree preparation payload");
6749
+ const batched = payload.worktrees !== void 0;
6750
+ const allowed = new Set(
6751
+ batched ? ["codebaseId", "expectedOrigin", "action", "preparations", "worktrees"] : [
6752
+ "codebaseId",
6753
+ "folder",
6754
+ "gitDirectory",
6755
+ "expectedOrigin",
6756
+ "action",
6757
+ "preparations"
6758
+ ]
6759
+ );
6760
+ const unexpected = Object.keys(payload).find((key) => !allowed.has(key));
6761
+ if (unexpected) {
6762
+ throw new Error(
6763
+ `Unexpected worktree preparation payload field: ${unexpected}`
6764
+ );
6765
+ }
6766
+ if (typeof payload.action !== "string" || !WORKTREE_PREPARATION_ACTIONS.includes(
6767
+ payload.action
6768
+ )) {
6769
+ throw new Error("worktree preparation payload.action is invalid");
6770
+ }
6771
+ const common = {
6772
+ codebaseId: stringValue4(
6773
+ payload.codebaseId,
6774
+ "worktree preparation payload.codebaseId"
6775
+ ),
6776
+ expectedOrigin: stringValue4(
6777
+ payload.expectedOrigin,
6778
+ "worktree preparation payload.expectedOrigin"
6779
+ ),
6780
+ action: payload.action,
6781
+ preparations: preparationDefinitions(
6782
+ payload.preparations,
6783
+ "worktree preparation payload.preparations"
6784
+ )
6785
+ };
6786
+ if (!batched) {
6787
+ return {
6788
+ ...common,
6789
+ folder: stringValue4(
6790
+ payload.folder,
6791
+ "worktree preparation payload.folder"
6792
+ ),
6793
+ gitDirectory: stringValue4(
6794
+ payload.gitDirectory,
6795
+ "worktree preparation payload.gitDirectory"
6796
+ )
6797
+ };
6798
+ }
6799
+ if (!Array.isArray(payload.worktrees) || payload.worktrees.length > 500) {
6800
+ throw new Error(
6801
+ "worktree preparation payload.worktrees must be an array with at most 500 items"
6802
+ );
6803
+ }
6804
+ const worktrees = payload.worktrees.map((value2, index) => {
6805
+ const target2 = objectValue4(
6806
+ value2,
6807
+ `worktree preparation payload.worktrees[${index}]`
6808
+ );
6809
+ const unexpectedTarget = Object.keys(target2).find(
6810
+ (key) => !["worktreeId", "folder", "gitDirectory"].includes(key)
6811
+ );
6812
+ if (unexpectedTarget) {
6813
+ throw new Error(
6814
+ `Unexpected worktree preparation payload.worktrees[${index}] field: ${unexpectedTarget}`
6815
+ );
6816
+ }
6817
+ return {
6818
+ worktreeId: stringValue4(
6819
+ target2.worktreeId,
6820
+ `worktree preparation payload.worktrees[${index}].worktreeId`
6821
+ ),
6822
+ folder: stringValue4(
6823
+ target2.folder,
6824
+ `worktree preparation payload.worktrees[${index}].folder`
6825
+ ),
6826
+ gitDirectory: stringValue4(
6827
+ target2.gitDirectory,
6828
+ `worktree preparation payload.worktrees[${index}].gitDirectory`
6829
+ )
6830
+ };
6831
+ });
6832
+ if (new Set(worktrees.map(({ worktreeId }) => worktreeId)).size !== worktrees.length) {
6833
+ throw new Error("worktree preparation payload.worktreeIds must be unique");
6834
+ }
6835
+ return { ...common, worktrees };
6836
+ }
6640
6837
  function worktreeGitInspectPayload(value) {
6641
6838
  const payload = objectValue4(value, "worktree Git inspect payload");
6642
6839
  const allowed = /* @__PURE__ */ new Set([
@@ -6802,8 +6999,8 @@ function worktreeDiffPayload(value) {
6802
6999
  if (payload.side !== null && payload.side !== void 0 && payload.side !== "BEFORE" && payload.side !== "AFTER") {
6803
7000
  throw new Error("worktree diff payload.side is invalid");
6804
7001
  }
6805
- const path = payload.path === null || payload.path === void 0 ? null : safeRelativePath(payload.path, "worktree diff payload.path");
6806
- const previousPath = payload.previousPath === null || payload.previousPath === void 0 ? null : safeRelativePath(
7002
+ const path = payload.path === null || payload.path === void 0 ? null : safeDiffPath(payload.path, "worktree diff payload.path");
7003
+ const previousPath = payload.previousPath === null || payload.previousPath === void 0 ? null : safeDiffPath(
6807
7004
  payload.previousPath,
6808
7005
  "worktree diff payload.previousPath"
6809
7006
  );
@@ -8321,9 +8518,64 @@ function buildCoverageReportPayload(input) {
8321
8518
  };
8322
8519
  }
8323
8520
 
8521
+ // ../agent-contract/src/cli-health.ts
8522
+ var CLI_HEALTH_JOB_KIND = "cli.health";
8523
+ var CLI_HEALTH_MAX_CHECKS = 27;
8524
+ var CLI_HEALTH_MAX_OUTPUT_BYTES = 32 * 1024;
8525
+ var CLI_HEALTH_CHECK_TIMEOUT_MS = 15e3;
8526
+ function objectValue12(value, name) {
8527
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
8528
+ throw new Error(`${name} must be an object`);
8529
+ }
8530
+ return value;
8531
+ }
8532
+ function checkDefinition(value, index) {
8533
+ const name = `cli.health checks[${index}]`;
8534
+ const check = objectValue12(value, name);
8535
+ const allowed = /* @__PURE__ */ new Set(["id", "name", "command", "builtIn"]);
8536
+ const unexpected = Object.keys(check).find((key) => !allowed.has(key));
8537
+ if (unexpected) throw new Error(`Unexpected ${name} field: ${unexpected}`);
8538
+ for (const field of ["id", "name", "command"]) {
8539
+ if (typeof check[field] !== "string" || check[field].length === 0) {
8540
+ throw new Error(`${name}.${field} must be a non-empty string`);
8541
+ }
8542
+ }
8543
+ if (typeof check.builtIn !== "boolean") {
8544
+ throw new Error(`${name}.builtIn must be a boolean`);
8545
+ }
8546
+ if (check.id.length > 100)
8547
+ throw new Error(`${name}.id is too long`);
8548
+ if (check.name.length > 100)
8549
+ throw new Error(`${name}.name is too long`);
8550
+ if (check.command.length > 4096 || check.command.includes("\0")) {
8551
+ throw new Error(`${name}.command is invalid`);
8552
+ }
8553
+ return check;
8554
+ }
8555
+ function parseCliHealthJobPayload(value) {
8556
+ const payload = objectValue12(value, "cli.health payload");
8557
+ const unexpected = Object.keys(payload).find((key) => key !== "checks");
8558
+ if (unexpected)
8559
+ throw new Error(`Unexpected cli.health payload field: ${unexpected}`);
8560
+ if (!Array.isArray(payload.checks)) {
8561
+ throw new Error("cli.health payload.checks must be an array");
8562
+ }
8563
+ if (payload.checks.length > CLI_HEALTH_MAX_CHECKS) {
8564
+ throw new Error(
8565
+ `cli.health supports at most ${CLI_HEALTH_MAX_CHECKS} checks`
8566
+ );
8567
+ }
8568
+ const checks = payload.checks.map(checkDefinition);
8569
+ if (new Set(checks.map((check) => check.id)).size !== checks.length) {
8570
+ throw new Error("cli.health check identifiers must be unique");
8571
+ }
8572
+ return { checks };
8573
+ }
8574
+
8324
8575
  // src/inventory.ts
8325
8576
  var AGENT_VERSION = process.env.CONTROL_AGENT_VERSION ?? "0.1.0";
8326
8577
  var PORTABLE_AGENT_CAPABILITIES = [
8578
+ CLI_HEALTH_JOB_KIND,
8327
8579
  COMMAND_RUN_JOB_KIND,
8328
8580
  CCUSAGE_REPORT_JOB_KIND,
8329
8581
  ...CODEBASE_JOB_KINDS,
@@ -8390,12 +8642,17 @@ function captureCommand(options) {
8390
8642
  timedOut: !options.signal.aborted,
8391
8643
  cancelled: options.signal.aborted,
8392
8644
  stdout: "",
8393
- stderr: ""
8645
+ stderr: "",
8646
+ outputTruncated: false
8394
8647
  });
8395
8648
  }
8396
- return new Promise((resolve8, reject) => {
8397
- let stdout = "";
8398
- let stderr = "";
8649
+ return new Promise((resolve9, reject) => {
8650
+ const stdoutChunks = [];
8651
+ const stderrChunks = [];
8652
+ let stdoutBytes = 0;
8653
+ let stderrBytes = 0;
8654
+ let retainedBytes = 0;
8655
+ let outputTruncated = false;
8399
8656
  let timedOut = false;
8400
8657
  let cancelled = false;
8401
8658
  let settled = false;
@@ -8415,12 +8672,23 @@ function captureCommand(options) {
8415
8672
  // stop the entire command tree instead of only the immediate Git process.
8416
8673
  detached
8417
8674
  });
8418
- const append = (current, chunk) => `${current}${String(chunk)}`.slice(0, MAX_OUTPUT_BYTES);
8675
+ const append = (chunks, chunk, streamBytes) => {
8676
+ const bytes = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
8677
+ const remaining = Math.max(
8678
+ 0,
8679
+ options.maxOutputBytes === void 0 ? MAX_OUTPUT_BYTES - streamBytes : options.maxOutputBytes - retainedBytes
8680
+ );
8681
+ const retained = bytes.subarray(0, remaining);
8682
+ if (retained.length) chunks.push(Buffer.from(retained));
8683
+ retainedBytes += retained.length;
8684
+ outputTruncated ||= retained.length < bytes.length;
8685
+ return streamBytes + retained.length;
8686
+ };
8419
8687
  child.stdout?.on("data", (chunk) => {
8420
- stdout = append(stdout, chunk);
8688
+ stdoutBytes = append(stdoutChunks, chunk, stdoutBytes);
8421
8689
  });
8422
8690
  child.stderr?.on("data", (chunk) => {
8423
- stderr = append(stderr, chunk);
8691
+ stderrBytes = append(stderrChunks, chunk, stderrBytes);
8424
8692
  });
8425
8693
  const sendSignal = (signal) => {
8426
8694
  if (detached && child.pid) {
@@ -8428,12 +8696,18 @@ function captureCommand(options) {
8428
8696
  process.kill(-child.pid, signal);
8429
8697
  return;
8430
8698
  } catch (error) {
8431
- if (!(error instanceof Error) || !("code" in error) || error.code !== "ESRCH") {
8699
+ if (!(error instanceof Error) || !("code" in error) || error.code !== "ESRCH" && error.code !== "EPERM") {
8432
8700
  throw error;
8433
8701
  }
8434
8702
  }
8435
8703
  }
8436
- child.kill(signal);
8704
+ try {
8705
+ child.kill(signal);
8706
+ } catch (error) {
8707
+ if (!(error instanceof Error) || !("code" in error) || error.code !== "ESRCH" && error.code !== "EPERM") {
8708
+ throw error;
8709
+ }
8710
+ }
8437
8711
  };
8438
8712
  const terminate = () => {
8439
8713
  if (child.exitCode !== null || child.killed) return;
@@ -8468,13 +8742,14 @@ function captureCommand(options) {
8468
8742
  clearTimeout(timeout);
8469
8743
  if (killTimer) clearTimeout(killTimer);
8470
8744
  options.signal.removeEventListener("abort", abort);
8471
- resolve8({
8745
+ resolve9({
8472
8746
  exitCode,
8473
8747
  signal,
8474
8748
  timedOut,
8475
8749
  cancelled,
8476
- stdout,
8477
- stderr
8750
+ stdout: Buffer.concat(stdoutChunks, stdoutBytes).toString("utf8"),
8751
+ stderr: Buffer.concat(stderrChunks, stderrBytes).toString("utf8"),
8752
+ outputTruncated
8478
8753
  });
8479
8754
  });
8480
8755
  });
@@ -8555,11 +8830,11 @@ async function reapOrphanedCommandProcesses(agentId, signal = new AbortControlle
8555
8830
  console.error(
8556
8831
  `Terminating ${signalled.length} command process(es) left by a previous agent run.`
8557
8832
  );
8558
- await new Promise((resolve8) => {
8559
- const timer = setTimeout(resolve8, TERMINATE_GRACE_MS);
8833
+ await new Promise((resolve9) => {
8834
+ const timer = setTimeout(resolve9, TERMINATE_GRACE_MS);
8560
8835
  timer.unref();
8561
- if (signal.aborted) resolve8();
8562
- else signal.addEventListener("abort", () => resolve8(), { once: true });
8836
+ if (signal.aborted) resolve9();
8837
+ else signal.addEventListener("abort", () => resolve9(), { once: true });
8563
8838
  });
8564
8839
  for (const orphan of signalled) signalGroup(orphan.processGroup, "SIGKILL");
8565
8840
  return signalled;
@@ -8615,14 +8890,14 @@ var runCommand = async (rawPayload, _timeoutMs, signal, _onLog, context) => {
8615
8890
  `Could not append command output; retrying in ${delay}ms:`,
8616
8891
  error instanceof Error ? error.message : error
8617
8892
  );
8618
- await new Promise((resolve8) => {
8893
+ await new Promise((resolve9) => {
8619
8894
  const onAbort = () => {
8620
8895
  clearTimeout(retryTimer);
8621
- resolve8();
8896
+ resolve9();
8622
8897
  };
8623
8898
  const retryTimer = setTimeout(() => {
8624
8899
  signal.removeEventListener("abort", onAbort);
8625
- resolve8();
8900
+ resolve9();
8626
8901
  }, delay);
8627
8902
  retryTimer.unref();
8628
8903
  signal.addEventListener("abort", onAbort, { once: true });
@@ -8660,7 +8935,7 @@ var runCommand = async (rawPayload, _timeoutMs, signal, _onLog, context) => {
8660
8935
  }
8661
8936
  };
8662
8937
  try {
8663
- return await new Promise((resolve8, reject) => {
8938
+ return await new Promise((resolve9, reject) => {
8664
8939
  let cancelled = false;
8665
8940
  let settled = false;
8666
8941
  const child = spawn2(process.env.SHELL || "/bin/sh", ["-l", scriptPath], {
@@ -8727,7 +9002,7 @@ var runCommand = async (rawPayload, _timeoutMs, signal, _onLog, context) => {
8727
9002
  signal.removeEventListener("abort", abort);
8728
9003
  flush();
8729
9004
  void uploadChain.then(
8730
- () => resolve8({
9005
+ () => resolve9({
8731
9006
  exitCode,
8732
9007
  signal: closeSignal,
8733
9008
  timedOut: false,
@@ -11760,6 +12035,164 @@ var importCoverageReport = async (payloadValue, timeoutMs, signal, onLog) => {
11760
12035
  };
11761
12036
  };
11762
12037
 
12038
+ // src/handlers/cli-health.ts
12039
+ import { Buffer as Buffer2 } from "node:buffer";
12040
+ import { homedir as homedir3 } from "node:os";
12041
+ var CONCURRENCY = 4;
12042
+ var ANSI_PATTERN = /\u001B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g;
12043
+ var CONTROL_PATTERN = /[\u0000-\u0008\u000B\u000C\u000E-\u001A\u001C-\u001F\u007F]/g;
12044
+ function clean(value) {
12045
+ return value.replace(ANSI_PATTERN, "").replace(CONTROL_PATTERN, "");
12046
+ }
12047
+ function lineBufferedOutput(value) {
12048
+ return value.replace(/\r?\n$/, "");
12049
+ }
12050
+ function appendWithinLimit(current, line, retainedBytes) {
12051
+ const addition = current ? `
12052
+ ${line}` : line;
12053
+ if (!addition) return { value: current, retainedBytes, truncated: false };
12054
+ const remaining = CLI_HEALTH_MAX_OUTPUT_BYTES - retainedBytes;
12055
+ if (remaining <= 0) return { value: current, retainedBytes, truncated: true };
12056
+ const bytes = Buffer2.from(addition, "utf8");
12057
+ if (bytes.length <= remaining)
12058
+ return {
12059
+ value: current + addition,
12060
+ retainedBytes: retainedBytes + bytes.length,
12061
+ truncated: false
12062
+ };
12063
+ let end = remaining;
12064
+ let retained = "";
12065
+ while (end > 0) {
12066
+ try {
12067
+ retained = new TextDecoder("utf-8", { fatal: true }).decode(
12068
+ bytes.subarray(0, end)
12069
+ );
12070
+ break;
12071
+ } catch {
12072
+ end -= 1;
12073
+ }
12074
+ }
12075
+ return {
12076
+ value: current + retained,
12077
+ retainedBytes: retainedBytes + Buffer2.byteLength(retained, "utf8"),
12078
+ truncated: true
12079
+ };
12080
+ }
12081
+ async function reportOutput(check, stdout, stderr, createdAt, onLog) {
12082
+ for (const [stream, message] of [
12083
+ ["STDOUT", stdout],
12084
+ ["STDERR", stderr]
12085
+ ]) {
12086
+ if (!message) continue;
12087
+ try {
12088
+ await onLog({
12089
+ sequence: 0,
12090
+ stream,
12091
+ message: `[${check.name}] ${message}`,
12092
+ createdAt
12093
+ });
12094
+ } catch (error) {
12095
+ console.error(
12096
+ `Could not append CLI health log for ${check.id}:`,
12097
+ error instanceof Error ? error.message : error
12098
+ );
12099
+ }
12100
+ }
12101
+ }
12102
+ async function runCliHealthCheck(check, signal, onLog, options = {}) {
12103
+ const started = Date.now();
12104
+ const checkedAt = (/* @__PURE__ */ new Date()).toISOString();
12105
+ try {
12106
+ const shell = options.shell || process.env.SHELL || "/bin/sh";
12107
+ const timeoutMs = options.timeoutMs ?? CLI_HEALTH_CHECK_TIMEOUT_MS;
12108
+ const result = await captureCommand({
12109
+ command: shell,
12110
+ args: ["-lc", check.command],
12111
+ cwd: options.cwd || homedir3(),
12112
+ timeoutMs,
12113
+ signal,
12114
+ maxOutputBytes: CLI_HEALTH_MAX_OUTPUT_BYTES
12115
+ });
12116
+ const capturedStdout = appendWithinLimit(
12117
+ "",
12118
+ clean(lineBufferedOutput(result.stdout)),
12119
+ 0
12120
+ );
12121
+ const systemError = result.timedOut ? `Process exceeded its ${Math.round(timeoutMs / 1e3)} second timeout` : result.cancelled ? "Cancellation requested" : "";
12122
+ const capturedStderr = appendWithinLimit(
12123
+ "",
12124
+ [clean(lineBufferedOutput(result.stderr)), systemError].filter(Boolean).join("\n"),
12125
+ capturedStdout.retainedBytes
12126
+ );
12127
+ const stdout = capturedStdout.value;
12128
+ const stderr = capturedStderr.value;
12129
+ const outputTruncated = result.outputTruncated || capturedStdout.truncated || capturedStderr.truncated;
12130
+ await reportOutput(check, stdout, stderr, checkedAt, onLog);
12131
+ return {
12132
+ ...check,
12133
+ exitCode: result.exitCode,
12134
+ stdout,
12135
+ stderr,
12136
+ durationMs: Date.now() - started,
12137
+ checkedAt,
12138
+ timedOut: result.timedOut,
12139
+ launchError: null,
12140
+ outputTruncated
12141
+ };
12142
+ } catch (error) {
12143
+ const launchError = clean(
12144
+ error instanceof Error ? error.message : String(error)
12145
+ );
12146
+ await reportOutput(check, "", launchError, checkedAt, onLog);
12147
+ return {
12148
+ ...check,
12149
+ exitCode: null,
12150
+ stdout: "",
12151
+ stderr: launchError,
12152
+ durationMs: Date.now() - started,
12153
+ checkedAt,
12154
+ timedOut: false,
12155
+ launchError,
12156
+ outputTruncated: false
12157
+ };
12158
+ }
12159
+ }
12160
+ async function runCliHealth(payload, _timeoutMs, signal, onLog) {
12161
+ const { checks } = parseCliHealthJobPayload(payload);
12162
+ const results = new Array(checks.length);
12163
+ let next = 0;
12164
+ let logSequence = 0;
12165
+ let logChain = Promise.resolve();
12166
+ const appendSweepLog = (log) => {
12167
+ const sequenced = { ...log, sequence: logSequence++ };
12168
+ const task = logChain.then(() => onLog(sequenced));
12169
+ logChain = task.catch(() => void 0);
12170
+ return task;
12171
+ };
12172
+ const worker = async () => {
12173
+ while (!signal.aborted) {
12174
+ const index = next++;
12175
+ if (index >= checks.length) return;
12176
+ results[index] = await runCliHealthCheck(
12177
+ checks[index],
12178
+ signal,
12179
+ appendSweepLog
12180
+ );
12181
+ }
12182
+ };
12183
+ await Promise.all(
12184
+ Array.from({ length: Math.min(CONCURRENCY, checks.length) }, worker)
12185
+ );
12186
+ await logChain;
12187
+ return {
12188
+ exitCode: signal.aborted ? null : 0,
12189
+ signal: null,
12190
+ timedOut: false,
12191
+ cancelled: signal.aborted,
12192
+ checks: results.filter(Boolean)
12193
+ };
12194
+ }
12195
+
11763
12196
  // src/handlers/signing.ts
11764
12197
  import { createHash as createHash6, randomUUID as randomUUID2, X509Certificate } from "node:crypto";
11765
12198
  import {
@@ -11771,18 +12204,18 @@ import {
11771
12204
  stat as stat4,
11772
12205
  writeFile as writeFile4
11773
12206
  } from "node:fs/promises";
11774
- import { homedir as homedir3, tmpdir as tmpdir3 } from "node:os";
12207
+ import { homedir as homedir4, tmpdir as tmpdir3 } from "node:os";
11775
12208
  import { basename as basename3, join as join5, relative as relative5, sep as sep5 } from "node:path";
11776
12209
  var PROFILE_DIRECTORIES = [
11777
12210
  join5(
11778
- homedir3(),
12211
+ homedir4(),
11779
12212
  "Library",
11780
12213
  "Developer",
11781
12214
  "Xcode",
11782
12215
  "UserData",
11783
12216
  "Provisioning Profiles"
11784
12217
  ),
11785
- join5(homedir3(), "Library", "MobileDevice", "Provisioning Profiles")
12218
+ join5(homedir4(), "Library", "MobileDevice", "Provisioning Profiles")
11786
12219
  ];
11787
12220
  var PROFILE_EXTENSIONS = [".mobileprovision", ".provisionprofile"];
11788
12221
  function text(value) {
@@ -12320,11 +12753,11 @@ var deleteSigningIdentity = async (payload, timeoutMs, signal) => {
12320
12753
  };
12321
12754
 
12322
12755
  // src/handlers/ccusage.ts
12323
- import { Buffer as Buffer2 } from "node:buffer";
12756
+ import { Buffer as Buffer3 } from "node:buffer";
12324
12757
 
12325
12758
  // src/executable-lookup.ts
12326
12759
  import { accessSync, constants } from "node:fs";
12327
- import { homedir as homedir4 } from "node:os";
12760
+ import { homedir as homedir5 } from "node:os";
12328
12761
  import { delimiter, dirname as dirname3, join as join6 } from "node:path";
12329
12762
  function isExecutable(path) {
12330
12763
  try {
@@ -12335,7 +12768,7 @@ function isExecutable(path) {
12335
12768
  }
12336
12769
  }
12337
12770
  function toolDirectories(options = {}) {
12338
- const home = options.home ?? homedir4();
12771
+ const home = options.home ?? homedir5();
12339
12772
  const platform2 = options.platform ?? process.platform;
12340
12773
  return [
12341
12774
  join6(home, ".local", "bin"),
@@ -12388,7 +12821,7 @@ function prependPathDirectory(directory, env = process.env) {
12388
12821
  // src/process-runner.ts
12389
12822
  import { spawn as spawn5 } from "node:child_process";
12390
12823
  async function runProcess(options) {
12391
- return new Promise((resolve8, reject) => {
12824
+ return new Promise((resolve9, reject) => {
12392
12825
  let sequence = 0;
12393
12826
  let timedOut = false;
12394
12827
  let cancelled = false;
@@ -12483,7 +12916,7 @@ async function runProcess(options) {
12483
12916
  clearTimeout(timeout);
12484
12917
  options.signal.removeEventListener("abort", abort);
12485
12918
  void logChain.then(
12486
- () => resolve8({ exitCode, signal, timedOut, cancelled })
12919
+ () => resolve9({ exitCode, signal, timedOut, cancelled })
12487
12920
  );
12488
12921
  });
12489
12922
  });
@@ -12524,7 +12957,7 @@ async function runCcusage(payload, timeoutMs, signal, onLog) {
12524
12957
  await onLog(log);
12525
12958
  return;
12526
12959
  }
12527
- const lineBytes = Buffer2.byteLength(log.message, "utf8") + 1;
12960
+ const lineBytes = Buffer3.byteLength(log.message, "utf8") + 1;
12528
12961
  if (stdoutBytes + lineBytes > MAX_CCUSAGE_STDOUT_BYTES) {
12529
12962
  exceededLimit = true;
12530
12963
  return;
@@ -12560,7 +12993,7 @@ import {
12560
12993
  stat as stat5,
12561
12994
  statfs
12562
12995
  } from "node:fs/promises";
12563
- import { homedir as homedir5 } from "node:os";
12996
+ import { homedir as homedir6 } from "node:os";
12564
12997
  import { basename as basename4, dirname as dirname4, isAbsolute as isAbsolute4, join as join7, resolve as resolve4 } from "node:path";
12565
12998
  var successfulProcess4 = {
12566
12999
  exitCode: 0,
@@ -12578,7 +13011,7 @@ function safeRelativePath3(value) {
12578
13011
  }
12579
13012
  async function configuredRoots(payload) {
12580
13013
  if (payload.mode === "DEFAULT") {
12581
- return [join7(homedir5(), "Library", "Developer", "Xcode", "DerivedData")];
13014
+ return [join7(homedir6(), "Library", "Developer", "Xcode", "DerivedData")];
12582
13015
  }
12583
13016
  if (payload.mode === "ABSOLUTE") {
12584
13017
  if (!payload.path || !isAbsolute4(payload.path)) {
@@ -12662,7 +13095,7 @@ async function scanRoot(configuredRoot, timeoutMs, signal) {
12662
13095
  }
12663
13096
  async function scanDeviceSupport(signal) {
12664
13097
  const configuredRoot = join7(
12665
- process.env.ADE_IOS_DEVICE_SUPPORT_DIRECTORY ?? homedir5(),
13098
+ process.env.ADE_IOS_DEVICE_SUPPORT_DIRECTORY ?? homedir6(),
12666
13099
  ...process.env.ADE_IOS_DEVICE_SUPPORT_DIRECTORY ? [] : ["Library", "Developer", "Xcode", "iOS DeviceSupport"]
12667
13100
  );
12668
13101
  signal.throwIfAborted();
@@ -12956,7 +13389,7 @@ async function collectAgentDiskSpace(configuration, signal) {
12956
13389
 
12957
13390
  // src/handlers/codebases.ts
12958
13391
  import { readdir as readdir4, realpath as realpath5, stat as stat6 } from "node:fs/promises";
12959
- import { homedir as homedir6 } from "node:os";
13392
+ import { homedir as homedir7 } from "node:os";
12960
13393
  import { dirname as dirname5, join as join8, resolve as resolve5 } from "node:path";
12961
13394
  var successfulProcess5 = {
12962
13395
  exitCode: 0,
@@ -13213,7 +13646,7 @@ async function inspectCodebase(selectedFolder, timeoutMs, signal, expectedOrigin
13213
13646
  }
13214
13647
  var browseCodebaseDirectories = async (payload) => {
13215
13648
  const input = codebaseBrowsePayload(payload);
13216
- const homePath = await realpath5(homedir6());
13649
+ const homePath = await realpath5(homedir7());
13217
13650
  const path = await realpath5(input.path ? resolve5(input.path) : homePath);
13218
13651
  if (!(await stat6(path)).isDirectory())
13219
13652
  throw new Error("Path is not a directory");
@@ -13841,7 +14274,7 @@ import {
13841
14274
  stat as stat7,
13842
14275
  writeFile as writeFile5
13843
14276
  } from "node:fs/promises";
13844
- import { homedir as homedir7 } from "node:os";
14277
+ import { homedir as homedir8 } from "node:os";
13845
14278
  import { dirname as dirname6, isAbsolute as isAbsolute5, join as join9, relative as relative6, resolve as resolve6, sep as sep6 } from "node:path";
13846
14279
  import { promisify } from "node:util";
13847
14280
  var executeFile = promisify(execFile);
@@ -13903,7 +14336,7 @@ async function directoryExists(path) {
13903
14336
  }
13904
14337
  }
13905
14338
  async function configuredTools(tools) {
13906
- const homePath = homedir7();
14339
+ const homePath = homedir8();
13907
14340
  return Promise.all(
13908
14341
  AI_TOOLS.filter((tool) => tools.includes(tool)).map(async (tool) => ({
13909
14342
  tool,
@@ -13913,7 +14346,7 @@ async function configuredTools(tools) {
13913
14346
  );
13914
14347
  }
13915
14348
  function rootPath(location) {
13916
- const base = location.scope === "GLOBAL" ? homedir7() : location.folder;
14349
+ const base = location.scope === "GLOBAL" ? homedir8() : location.folder;
13917
14350
  const parts = location.scope === "GLOBAL" ? GLOBAL_ROOTS[location.rootKind] : PROJECT_ROOTS[location.rootKind];
13918
14351
  const path = resolve6(base, ...parts);
13919
14352
  const normalizedBase = resolve6(base);
@@ -14232,7 +14665,7 @@ var applySkills = async (payload) => {
14232
14665
 
14233
14666
  // src/handlers/runs.ts
14234
14667
  import { readFile as readFile6, readdir as readdir6, stat as stat8 } from "node:fs/promises";
14235
- import { homedir as homedir8 } from "node:os";
14668
+ import { homedir as homedir9 } from "node:os";
14236
14669
  import { join as join10 } from "node:path";
14237
14670
  var successfulProcess7 = {
14238
14671
  exitCode: 0,
@@ -14291,7 +14724,7 @@ async function locateSessionFile(payload, home) {
14291
14724
  }
14292
14725
  var readRunSession = async (payload) => {
14293
14726
  const input = parseRunSessionReadPayload(payload);
14294
- const path = await locateSessionFile(input, homedir8());
14727
+ const path = await locateSessionFile(input, homedir9());
14295
14728
  if (!path) {
14296
14729
  throw new Error(
14297
14730
  `No ${input.provider === "CLAUDE" ? "Claude" : "Codex"} session file found for this run on this agent`
@@ -14352,7 +14785,7 @@ async function optionalGit(cwd, args) {
14352
14785
  }
14353
14786
  function cappedGit(cwd, args, limit) {
14354
14787
  const budget = limit - TRUNCATION_RESERVE;
14355
- return new Promise((resolve8, reject) => {
14788
+ return new Promise((resolve9, reject) => {
14356
14789
  const child = spawn6("git", args, {
14357
14790
  cwd,
14358
14791
  env: {
@@ -14402,7 +14835,7 @@ function cappedGit(cwd, args, limit) {
14402
14835
  return;
14403
14836
  }
14404
14837
  const output = Buffer.concat(chunks).toString("utf8");
14405
- resolve8(
14838
+ resolve9(
14406
14839
  truncated ? `${output.trimEnd()}
14407
14840
 
14408
14841
  [Truncated after ${budget} bytes]` : output.trim()
@@ -14712,10 +15145,494 @@ var runWorkflowGitCheckpoint = async (payloadValue, _timeoutMs, signal) => {
14712
15145
 
14713
15146
  // src/handlers/worktrees.ts
14714
15147
  import { createWriteStream as createWriteStream2, watch } from "node:fs";
14715
- import { mkdtemp as mkdtemp6, open as open2, readFile as readFile8, realpath as realpath8, rm as rm9, stat as stat10 } from "node:fs/promises";
15148
+ import { mkdtemp as mkdtemp6, open as open2, readFile as readFile9, realpath as realpath9, rm as rm10, stat as stat10 } from "node:fs/promises";
14716
15149
  import { tmpdir as tmpdir6 } from "node:os";
14717
- import { basename as basename5, dirname as dirname7, isAbsolute as isAbsolute6, join as join13, relative as relative7 } from "node:path";
15150
+ import { basename as basename5, dirname as dirname8, isAbsolute as isAbsolute7, join as join14, relative as relative8 } from "node:path";
14718
15151
  import { spawn as spawn7 } from "node:child_process";
15152
+
15153
+ // src/handlers/worktree-preparations.ts
15154
+ import { createHash as createHash7 } from "node:crypto";
15155
+ import {
15156
+ chmod as chmod4,
15157
+ lstat as lstat4,
15158
+ mkdir as mkdir5,
15159
+ readFile as readFile8,
15160
+ realpath as realpath8,
15161
+ rm as rm9,
15162
+ writeFile as writeFile7
15163
+ } from "node:fs/promises";
15164
+ import { dirname as dirname7, isAbsolute as isAbsolute6, join as join13, relative as relative7, resolve as resolve7 } from "node:path";
15165
+ var EXCLUDE_BEGIN = "# BEGIN AIDE PREPARATIONS";
15166
+ var EXCLUDE_END = "# END AIDE PREPARATIONS";
15167
+ function cleanError3(value) {
15168
+ return (value instanceof Error ? value.message : String(value)).replace(/([a-z][a-z0-9+.-]*:\/\/)[^\s/@]+@/gi, "$1").slice(0, 2e3);
15169
+ }
15170
+ async function git3(folder, args, timeoutMs, signal) {
15171
+ return captureCommand({
15172
+ command: "git",
15173
+ args: ["-C", folder, ...args],
15174
+ timeoutMs,
15175
+ signal,
15176
+ env: {
15177
+ ...process.env,
15178
+ GIT_LITERAL_PATHSPECS: "1",
15179
+ GIT_OPTIONAL_LOCKS: "0",
15180
+ GIT_TERMINAL_PROMPT: "0"
15181
+ }
15182
+ });
15183
+ }
15184
+ function requireSuccess3(result, fallback) {
15185
+ if (result.cancelled) throw new Error("Preparation was cancelled");
15186
+ if (result.timedOut) throw new Error("Preparation timed out");
15187
+ if (result.exitCode !== 0) {
15188
+ throw new Error(cleanError3(result.stderr || fallback));
15189
+ }
15190
+ return result;
15191
+ }
15192
+ async function exists(path) {
15193
+ try {
15194
+ await lstat4(path);
15195
+ return true;
15196
+ } catch (error) {
15197
+ if (error instanceof Error && "code" in error && error.code === "ENOENT") {
15198
+ return false;
15199
+ }
15200
+ throw error;
15201
+ }
15202
+ }
15203
+ async function safeTarget(folder, path) {
15204
+ const root = await realpath8(folder);
15205
+ const target2 = resolve7(root, path);
15206
+ const fromRoot = relative7(root, target2);
15207
+ if (!fromRoot || fromRoot.startsWith("..") || isAbsolute6(fromRoot) || path.includes("\0")) {
15208
+ throw new Error(
15209
+ "Preparation path must be an exact file inside the worktree"
15210
+ );
15211
+ }
15212
+ let current = root;
15213
+ const segments = fromRoot.split(/[\\/]/);
15214
+ for (const segment of segments.slice(0, -1)) {
15215
+ current = join13(current, segment);
15216
+ try {
15217
+ const info = await lstat4(current);
15218
+ if (info.isSymbolicLink()) {
15219
+ throw new Error(`Preparation path crosses symbolic link: ${path}`);
15220
+ }
15221
+ if (!info.isDirectory()) {
15222
+ throw new Error(`Preparation parent is not a directory: ${path}`);
15223
+ }
15224
+ } catch (error) {
15225
+ if (error instanceof Error && "code" in error && error.code === "ENOENT") {
15226
+ break;
15227
+ }
15228
+ throw error;
15229
+ }
15230
+ }
15231
+ return target2;
15232
+ }
15233
+ async function isTracked(folder, path, timeoutMs, signal) {
15234
+ const result = await git3(
15235
+ folder,
15236
+ ["ls-files", "--error-unmatch", "--", path],
15237
+ timeoutMs,
15238
+ signal
15239
+ );
15240
+ if (result.exitCode === 0) return true;
15241
+ if (result.exitCode === 1) return false;
15242
+ requireSuccess3(result, `Could not inspect tracked path ${path}`);
15243
+ return false;
15244
+ }
15245
+ async function isAssumeUnchanged(folder, path, timeoutMs, signal) {
15246
+ const result = requireSuccess3(
15247
+ await git3(folder, ["ls-files", "-v", "--", path], timeoutMs, signal),
15248
+ `Could not inspect assume-unchanged state for ${path}`
15249
+ );
15250
+ const marker = result.stdout[0];
15251
+ return Boolean(marker && /[a-z]/.test(marker));
15252
+ }
15253
+ async function setAssumeUnchanged(folder, path, assumed, timeoutMs, signal) {
15254
+ requireSuccess3(
15255
+ await git3(
15256
+ folder,
15257
+ [
15258
+ "update-index",
15259
+ assumed ? "--assume-unchanged" : "--no-assume-unchanged",
15260
+ "--",
15261
+ path
15262
+ ],
15263
+ timeoutMs,
15264
+ signal
15265
+ ),
15266
+ `Could not ${assumed ? "mark" : "unmark"} ${path} as assume unchanged`
15267
+ );
15268
+ }
15269
+ function excludeEntry(path) {
15270
+ return `/${path}`;
15271
+ }
15272
+ function withoutAideExcludeBlock(value) {
15273
+ const lines = value.split(/\r?\n/);
15274
+ const output = [];
15275
+ let inBlock = false;
15276
+ for (const line of lines) {
15277
+ if (line === EXCLUDE_BEGIN) {
15278
+ inBlock = true;
15279
+ continue;
15280
+ }
15281
+ if (line === EXCLUDE_END) {
15282
+ inBlock = false;
15283
+ continue;
15284
+ }
15285
+ if (!inBlock) output.push(line);
15286
+ }
15287
+ return output.join("\n").replace(/\n+$/, "");
15288
+ }
15289
+ async function excludeFile(folder, timeoutMs, signal) {
15290
+ const result = requireSuccess3(
15291
+ await git3(
15292
+ folder,
15293
+ ["rev-parse", "--git-path", "info/exclude"],
15294
+ timeoutMs,
15295
+ signal
15296
+ ),
15297
+ "Could not locate the repository exclude file"
15298
+ );
15299
+ const candidate = result.stdout.trim();
15300
+ return isAbsolute6(candidate) ? candidate : resolve7(folder, candidate);
15301
+ }
15302
+ async function readExcludeEntries(folder, timeoutMs, signal) {
15303
+ const path = await excludeFile(folder, timeoutMs, signal);
15304
+ let value = "";
15305
+ try {
15306
+ value = await readFile8(path, "utf8");
15307
+ } catch (error) {
15308
+ if (!(error instanceof Error) || !("code" in error) || error.code !== "ENOENT") {
15309
+ throw error;
15310
+ }
15311
+ }
15312
+ const start = value.split(/\r?\n/).indexOf(EXCLUDE_BEGIN);
15313
+ const end = value.split(/\r?\n/).indexOf(EXCLUDE_END);
15314
+ if (start < 0 || end <= start) return /* @__PURE__ */ new Set();
15315
+ return new Set(value.split(/\r?\n/).slice(start + 1, end));
15316
+ }
15317
+ async function reconcileExcludeFile(folder, definitions, timeoutMs, signal) {
15318
+ const path = await excludeFile(folder, timeoutMs, signal);
15319
+ let existing = "";
15320
+ try {
15321
+ existing = await readFile8(path, "utf8");
15322
+ } catch (error) {
15323
+ if (!(error instanceof Error) || !("code" in error) || error.code !== "ENOENT") {
15324
+ throw error;
15325
+ }
15326
+ }
15327
+ const base = withoutAideExcludeBlock(existing);
15328
+ const entries = definitions.filter((definition) => definition.kind === "WRITE").map((definition) => excludeEntry(definition.path)).sort((left, right) => left.localeCompare(right));
15329
+ const block = entries.length ? [EXCLUDE_BEGIN, ...entries, EXCLUDE_END].join("\n") : "";
15330
+ const next = [base, block].filter(Boolean).join("\n\n");
15331
+ await mkdir5(dirname7(path), { recursive: true });
15332
+ await writeFile7(path, next ? `${next}
15333
+ ` : "", "utf8");
15334
+ }
15335
+ function decodeContents(definition) {
15336
+ if (definition.contentBase64 === null) {
15337
+ throw new Error(`Write preparation ${definition.path} has no contents`);
15338
+ }
15339
+ const contents = Buffer.from(definition.contentBase64, "base64");
15340
+ const canonicalInput = definition.contentBase64.replace(/=+$/, "");
15341
+ if (contents.toString("base64").replace(/=+$/, "") !== canonicalInput) {
15342
+ throw new Error(
15343
+ `Write preparation ${definition.path} has invalid base64 contents`
15344
+ );
15345
+ }
15346
+ return contents;
15347
+ }
15348
+ async function removeTarget(target2, path) {
15349
+ try {
15350
+ const info = await lstat4(target2);
15351
+ if (info.isDirectory() && !info.isSymbolicLink()) {
15352
+ throw new Error(`Preparation path is a directory: ${path}`);
15353
+ }
15354
+ await rm9(target2, { force: true });
15355
+ } catch (error) {
15356
+ if (error instanceof Error && "code" in error && error.code === "ENOENT") {
15357
+ return;
15358
+ }
15359
+ throw error;
15360
+ }
15361
+ }
15362
+ async function restoreFromHead(folder, definition, timeoutMs, signal) {
15363
+ const target2 = await safeTarget(folder, definition.path);
15364
+ if (await isTracked(folder, definition.path, timeoutMs, signal)) {
15365
+ await setAssumeUnchanged(folder, definition.path, false, timeoutMs, signal);
15366
+ const atHead = await git3(
15367
+ folder,
15368
+ ["cat-file", "-e", `HEAD:${definition.path}`],
15369
+ timeoutMs,
15370
+ signal
15371
+ );
15372
+ if (atHead.exitCode === 0) {
15373
+ requireSuccess3(
15374
+ await git3(
15375
+ folder,
15376
+ ["restore", "--source=HEAD", "--worktree", "--", definition.path],
15377
+ timeoutMs,
15378
+ signal
15379
+ ),
15380
+ `Could not restore ${definition.path} from HEAD`
15381
+ );
15382
+ return;
15383
+ }
15384
+ if (atHead.exitCode !== 1 && atHead.exitCode !== 128) {
15385
+ requireSuccess3(atHead, `Could not inspect ${definition.path} in HEAD`);
15386
+ }
15387
+ }
15388
+ await removeTarget(target2, definition.path);
15389
+ }
15390
+ async function applyOne(folder, definition, timeoutMs, signal) {
15391
+ const target2 = await safeTarget(folder, definition.path);
15392
+ const tracked = await isTracked(folder, definition.path, timeoutMs, signal);
15393
+ if (definition.kind === "ASSUME_UNCHANGED") {
15394
+ if (!tracked) return "NOT_APPLICABLE";
15395
+ await setAssumeUnchanged(folder, definition.path, true, timeoutMs, signal);
15396
+ return "APPLIED";
15397
+ }
15398
+ if (definition.kind === "DELETE") {
15399
+ await removeTarget(target2, definition.path);
15400
+ } else {
15401
+ const contents = decodeContents(definition);
15402
+ let executable = false;
15403
+ try {
15404
+ const info = await lstat4(target2);
15405
+ if (info.isDirectory() && !info.isSymbolicLink()) {
15406
+ throw new Error(`Preparation path is a directory: ${definition.path}`);
15407
+ }
15408
+ executable = info.isFile() && (info.mode & 73) !== 0;
15409
+ if (info.isSymbolicLink()) await rm9(target2, { force: true });
15410
+ } catch (error) {
15411
+ if (!(error instanceof Error) || !("code" in error) || error.code !== "ENOENT") {
15412
+ throw error;
15413
+ }
15414
+ }
15415
+ await mkdir5(dirname7(target2), { recursive: true, mode: 493 });
15416
+ await safeTarget(folder, definition.path);
15417
+ await writeFile7(target2, contents, { mode: executable ? 493 : 420 });
15418
+ if (executable) await chmod4(target2, 493);
15419
+ }
15420
+ if (tracked) {
15421
+ await setAssumeUnchanged(folder, definition.path, true, timeoutMs, signal);
15422
+ }
15423
+ return "APPLIED";
15424
+ }
15425
+ async function undoOne(folder, definition, timeoutMs, signal) {
15426
+ if (definition.kind === "ASSUME_UNCHANGED") {
15427
+ if (!await isTracked(folder, definition.path, timeoutMs, signal)) {
15428
+ return "NOT_APPLICABLE";
15429
+ }
15430
+ await setAssumeUnchanged(folder, definition.path, false, timeoutMs, signal);
15431
+ return "UNDONE";
15432
+ }
15433
+ await restoreFromHead(folder, definition, timeoutMs, signal);
15434
+ return "UNDONE";
15435
+ }
15436
+ async function inspectOne(folder, definition, excludeEntries, timeoutMs, signal) {
15437
+ const target2 = await safeTarget(folder, definition.path);
15438
+ const tracked = await isTracked(folder, definition.path, timeoutMs, signal);
15439
+ const assumed = tracked ? await isAssumeUnchanged(folder, definition.path, timeoutMs, signal) : false;
15440
+ if (definition.kind === "ASSUME_UNCHANGED") {
15441
+ return tracked ? assumed ? "APPLIED" : "DRIFTED" : "NOT_APPLICABLE";
15442
+ }
15443
+ if (definition.kind === "DELETE") {
15444
+ return !await exists(target2) && (!tracked || assumed) ? "APPLIED" : "DRIFTED";
15445
+ }
15446
+ let matches = false;
15447
+ try {
15448
+ const info = await lstat4(target2);
15449
+ if (info.isFile()) {
15450
+ const expected = createHash7("sha256").update(decodeContents(definition)).digest("hex");
15451
+ const actual = createHash7("sha256").update(await readFile8(target2)).digest("hex");
15452
+ matches = actual === expected;
15453
+ }
15454
+ } catch (error) {
15455
+ if (!(error instanceof Error) || !("code" in error) || error.code !== "ENOENT") {
15456
+ throw error;
15457
+ }
15458
+ }
15459
+ const hidden = tracked ? assumed : excludeEntries.has(excludeEntry(definition.path));
15460
+ return matches && hidden ? "APPLIED" : "DRIFTED";
15461
+ }
15462
+ async function executeWorktreePreparations(folder, definitions, action, timeoutMs, signal) {
15463
+ let excludeError = null;
15464
+ if (action !== "INSPECT") {
15465
+ try {
15466
+ await reconcileExcludeFile(folder, definitions, timeoutMs, signal);
15467
+ } catch (error) {
15468
+ excludeError = cleanError3(error);
15469
+ }
15470
+ }
15471
+ let excludeEntries = /* @__PURE__ */ new Set();
15472
+ try {
15473
+ excludeEntries = await readExcludeEntries(folder, timeoutMs, signal);
15474
+ } catch (error) {
15475
+ excludeError ??= cleanError3(error);
15476
+ }
15477
+ const results = [];
15478
+ for (const definition of definitions) {
15479
+ if (definition.kind === "WRITE" && excludeError) {
15480
+ results.push({
15481
+ id: definition.id,
15482
+ definitionHash: definition.definitionHash,
15483
+ state: "ERROR",
15484
+ message: excludeError
15485
+ });
15486
+ continue;
15487
+ }
15488
+ try {
15489
+ const state = action === "APPLY" ? await applyOne(folder, definition, timeoutMs, signal) : action === "UNDO" ? await undoOne(folder, definition, timeoutMs, signal) : await inspectOne(
15490
+ folder,
15491
+ definition,
15492
+ excludeEntries,
15493
+ timeoutMs,
15494
+ signal
15495
+ );
15496
+ results.push({
15497
+ id: definition.id,
15498
+ definitionHash: definition.definitionHash,
15499
+ state
15500
+ });
15501
+ } catch (error) {
15502
+ results.push({
15503
+ id: definition.id,
15504
+ definitionHash: definition.definitionHash,
15505
+ state: "ERROR",
15506
+ message: cleanError3(error)
15507
+ });
15508
+ }
15509
+ }
15510
+ return results;
15511
+ }
15512
+ async function suspendWorktreePreparations(folder, definitions, timeoutMs, signal, preserveAssumeUnchangedContents = false) {
15513
+ let excludeError = null;
15514
+ try {
15515
+ await reconcileExcludeFile(folder, definitions, timeoutMs, signal);
15516
+ } catch (error) {
15517
+ excludeError = cleanError3(error);
15518
+ }
15519
+ const results = [];
15520
+ for (const definition of definitions) {
15521
+ if (definition.kind === "WRITE" && excludeError) {
15522
+ results.push({
15523
+ id: definition.id,
15524
+ definitionHash: definition.definitionHash,
15525
+ state: "ERROR",
15526
+ message: excludeError
15527
+ });
15528
+ continue;
15529
+ }
15530
+ try {
15531
+ if (definition.kind === "ASSUME_UNCHANGED") {
15532
+ if (await isTracked(folder, definition.path, timeoutMs, signal)) {
15533
+ if (preserveAssumeUnchangedContents) {
15534
+ await setAssumeUnchanged(
15535
+ folder,
15536
+ definition.path,
15537
+ false,
15538
+ timeoutMs,
15539
+ signal
15540
+ );
15541
+ } else {
15542
+ await restoreFromHead(folder, definition, timeoutMs, signal);
15543
+ }
15544
+ results.push({
15545
+ id: definition.id,
15546
+ definitionHash: definition.definitionHash,
15547
+ state: "SUSPENDED"
15548
+ });
15549
+ } else {
15550
+ results.push({
15551
+ id: definition.id,
15552
+ definitionHash: definition.definitionHash,
15553
+ state: "NOT_APPLICABLE"
15554
+ });
15555
+ }
15556
+ } else {
15557
+ await restoreFromHead(folder, definition, timeoutMs, signal);
15558
+ results.push({
15559
+ id: definition.id,
15560
+ definitionHash: definition.definitionHash,
15561
+ state: "SUSPENDED"
15562
+ });
15563
+ }
15564
+ } catch (error) {
15565
+ results.push({
15566
+ id: definition.id,
15567
+ definitionHash: definition.definitionHash,
15568
+ state: "ERROR",
15569
+ message: cleanError3(error)
15570
+ });
15571
+ }
15572
+ }
15573
+ return results;
15574
+ }
15575
+ async function preparationConflictPaths(folder, definitions, remoteBase, timeoutMs, signal) {
15576
+ const paths = [];
15577
+ for (const definition of definitions) {
15578
+ const changedByBase = await git3(
15579
+ folder,
15580
+ ["diff", "--quiet", `HEAD...${remoteBase}`, "--", definition.path],
15581
+ timeoutMs,
15582
+ signal
15583
+ );
15584
+ if (changedByBase.exitCode === 1) {
15585
+ const tracked = await isTracked(
15586
+ folder,
15587
+ definition.path,
15588
+ timeoutMs,
15589
+ signal
15590
+ );
15591
+ let managedChange = false;
15592
+ if (tracked) {
15593
+ const head = await git3(
15594
+ folder,
15595
+ ["rev-parse", `HEAD:${definition.path}`],
15596
+ timeoutMs,
15597
+ signal
15598
+ );
15599
+ const working = await git3(
15600
+ folder,
15601
+ ["hash-object", "--", definition.path],
15602
+ timeoutMs,
15603
+ signal
15604
+ );
15605
+ managedChange = head.exitCode !== 0 || working.exitCode !== 0 || head.stdout.trim() !== working.stdout.trim();
15606
+ } else if (definition.kind === "WRITE") {
15607
+ managedChange = await exists(await safeTarget(folder, definition.path));
15608
+ } else {
15609
+ const presentOnBase = await git3(
15610
+ folder,
15611
+ ["cat-file", "-e", `${remoteBase}:${definition.path}`],
15612
+ timeoutMs,
15613
+ signal
15614
+ );
15615
+ if (presentOnBase.exitCode === 0) {
15616
+ managedChange = true;
15617
+ } else if (presentOnBase.exitCode !== 1 && presentOnBase.exitCode !== 128) {
15618
+ requireSuccess3(
15619
+ presentOnBase,
15620
+ `Could not inspect ${definition.path} on the base branch`
15621
+ );
15622
+ }
15623
+ }
15624
+ if (managedChange) paths.push(definition.path);
15625
+ continue;
15626
+ }
15627
+ requireSuccess3(
15628
+ changedByBase,
15629
+ `Could not inspect preparation conflict for ${definition.path}`
15630
+ );
15631
+ }
15632
+ return paths;
15633
+ }
15634
+
15635
+ // src/handlers/worktrees.ts
14719
15636
  var successfulProcess8 = {
14720
15637
  exitCode: 0,
14721
15638
  signal: null,
@@ -14759,7 +15676,7 @@ function statusChangeState(value) {
14759
15676
  }
14760
15677
  async function rebaseInProgress(folder, timeoutMs, signal) {
14761
15678
  for (const name of ["rebase-merge", "rebase-apply"]) {
14762
- const pathResult = await git3(
15679
+ const pathResult = await git4(
14763
15680
  folder,
14764
15681
  ["rev-parse", "--git-path", name],
14765
15682
  timeoutMs,
@@ -14769,7 +15686,7 @@ async function rebaseInProgress(folder, timeoutMs, signal) {
14769
15686
  const candidate = pathResult.stdout.trim();
14770
15687
  if (!candidate) continue;
14771
15688
  try {
14772
- await stat10(isAbsolute6(candidate) ? candidate : join13(folder, candidate));
15689
+ await stat10(isAbsolute7(candidate) ? candidate : join14(folder, candidate));
14773
15690
  return true;
14774
15691
  } catch {
14775
15692
  }
@@ -14778,7 +15695,7 @@ async function rebaseInProgress(folder, timeoutMs, signal) {
14778
15695
  }
14779
15696
  async function rebaseBranch(folder, timeoutMs, signal) {
14780
15697
  for (const name of ["rebase-merge/head-name", "rebase-apply/head-name"]) {
14781
- const pathResult = await git3(
15698
+ const pathResult = await git4(
14782
15699
  folder,
14783
15700
  ["rev-parse", "--git-path", name],
14784
15701
  timeoutMs,
@@ -14788,8 +15705,8 @@ async function rebaseBranch(folder, timeoutMs, signal) {
14788
15705
  const candidate = pathResult.stdout.trim();
14789
15706
  if (!candidate) continue;
14790
15707
  try {
14791
- const headName = (await readFile8(
14792
- isAbsolute6(candidate) ? candidate : join13(folder, candidate),
15708
+ const headName = (await readFile9(
15709
+ isAbsolute7(candidate) ? candidate : join14(folder, candidate),
14793
15710
  "utf8"
14794
15711
  )).trim();
14795
15712
  if (headName.startsWith("refs/heads/")) {
@@ -14823,7 +15740,7 @@ async function flushWorktreeActivity(entry) {
14823
15740
  try {
14824
15741
  const signal = new AbortController().signal;
14825
15742
  const [status2, branchResult, headResult, codeStateHash, rebasing] = await Promise.all([
14826
- git3(
15743
+ git4(
14827
15744
  entry.folder,
14828
15745
  [
14829
15746
  "--no-optional-locks",
@@ -14835,13 +15752,13 @@ async function flushWorktreeActivity(entry) {
14835
15752
  entry.timeoutMs,
14836
15753
  signal
14837
15754
  ),
14838
- git3(
15755
+ git4(
14839
15756
  entry.folder,
14840
15757
  ["symbolic-ref", "--short", "-q", "HEAD"],
14841
15758
  entry.timeoutMs,
14842
15759
  signal
14843
15760
  ),
14844
- git3(entry.folder, ["rev-parse", "HEAD"], entry.timeoutMs, signal),
15761
+ git4(entry.folder, ["rev-parse", "HEAD"], entry.timeoutMs, signal),
14845
15762
  worktreeCodeStateHash(entry.folder, entry.timeoutMs, signal),
14846
15763
  rebaseInProgress(entry.folder, entry.timeoutMs, signal)
14847
15764
  ]);
@@ -14870,7 +15787,7 @@ async function flushWorktreeActivity(entry) {
14870
15787
  observedAt: (/* @__PURE__ */ new Date()).toISOString()
14871
15788
  };
14872
15789
  if (headIdentity && headIdentity !== entry.headIdentity) {
14873
- const upstreamResult = branch ? await git3(
15790
+ const upstreamResult = branch ? await git4(
14874
15791
  entry.folder,
14875
15792
  [
14876
15793
  "rev-parse",
@@ -14928,24 +15845,24 @@ function scheduleWorktreeActivity(entry) {
14928
15845
  }, WATCH_DEBOUNCE_MS);
14929
15846
  entry.timer.unref();
14930
15847
  }
14931
- function cleanError3(value) {
15848
+ function cleanError4(value) {
14932
15849
  return (value instanceof Error ? value.message : String(value)).replace(/([a-z][a-z0-9+.-]*:\/\/)[^\s/@]+@/gi, "$1").slice(0, 2e3);
14933
15850
  }
14934
15851
  async function command2(executable, args, timeoutMs, signal, env = process.env) {
14935
15852
  return captureCommand({ command: executable, args, timeoutMs, signal, env });
14936
15853
  }
14937
- async function git3(folder, args, timeoutMs, signal) {
15854
+ async function git4(folder, args, timeoutMs, signal) {
14938
15855
  return command2("git", ["-C", folder, ...args], timeoutMs, signal, {
14939
15856
  ...process.env,
14940
15857
  GIT_TERMINAL_PROMPT: "0",
14941
15858
  GIT_OPTIONAL_LOCKS: "0"
14942
15859
  });
14943
15860
  }
14944
- function requireSuccess3(result, fallback) {
15861
+ function requireSuccess4(result, fallback) {
14945
15862
  if (result.cancelled) throw new Error("Worktree operation was cancelled");
14946
15863
  if (result.timedOut) throw new Error("Worktree operation timed out");
14947
15864
  if (result.exitCode !== 0)
14948
- throw new Error(cleanError3(result.stderr || fallback));
15865
+ throw new Error(cleanError4(result.stderr || fallback));
14949
15866
  return result;
14950
15867
  }
14951
15868
  function parseWorktreeList(value) {
@@ -14963,8 +15880,8 @@ function parseWorktreeList(value) {
14963
15880
  }).filter((entry) => Boolean(entry.folder));
14964
15881
  }
14965
15882
  async function gitDirectory(folder, timeoutMs, signal) {
14966
- const result = requireSuccess3(
14967
- await git3(
15883
+ const result = requireSuccess4(
15884
+ await git4(
14968
15885
  folder,
14969
15886
  ["rev-parse", "--path-format=absolute", "--git-dir"],
14970
15887
  timeoutMs,
@@ -14972,17 +15889,17 @@ async function gitDirectory(folder, timeoutMs, signal) {
14972
15889
  ),
14973
15890
  "Could not resolve the worktree Git directory"
14974
15891
  );
14975
- return realpath8(result.stdout.trim());
15892
+ return realpath9(result.stdout.trim());
14976
15893
  }
14977
15894
  async function origin(folder, timeoutMs, signal) {
14978
- const result = requireSuccess3(
14979
- await git3(folder, ["remote", "get-url", "origin"], timeoutMs, signal),
15895
+ const result = requireSuccess4(
15896
+ await git4(folder, ["remote", "get-url", "origin"], timeoutMs, signal),
14980
15897
  "Repository does not have an origin remote"
14981
15898
  );
14982
15899
  return normalizeGitOrigin(result.stdout.trim()).canonicalOrigin;
14983
15900
  }
14984
15901
  async function validateWorktree2(input, timeoutMs, signal) {
14985
- const folder = await realpath8(input.folder);
15902
+ const folder = await realpath9(input.folder);
14986
15903
  if (!(await stat10(folder)).isDirectory())
14987
15904
  throw new Error("Worktree is missing");
14988
15905
  const observedGitDirectory = await gitDirectory(folder, timeoutMs, signal);
@@ -14995,7 +15912,7 @@ async function validateWorktree2(input, timeoutMs, signal) {
14995
15912
  return folder;
14996
15913
  }
14997
15914
  async function counts(folder, range, timeoutMs, signal) {
14998
- const result = await git3(
15915
+ const result = await git4(
14999
15916
  folder,
15000
15917
  ["rev-list", "--left-right", "--count", range],
15001
15918
  timeoutMs,
@@ -15029,17 +15946,17 @@ async function worktreePushStatus(folder, branch, changes, timeoutMs, signal) {
15029
15946
  async function inspectWorktreeItem(folderValue2, rootFolder, baseBranch, primary, timeoutMs, signal) {
15030
15947
  const checkedAt = (/* @__PURE__ */ new Date()).toISOString();
15031
15948
  try {
15032
- const folder = await realpath8(folderValue2);
15949
+ const folder = await realpath9(folderValue2);
15033
15950
  const [gitDir, branchResult, headResult, statusResult, rebasing] = await Promise.all([
15034
15951
  gitDirectory(folder, timeoutMs, signal),
15035
- git3(
15952
+ git4(
15036
15953
  folder,
15037
15954
  ["symbolic-ref", "--short", "-q", "HEAD"],
15038
15955
  timeoutMs,
15039
15956
  signal
15040
15957
  ),
15041
- git3(folder, ["rev-parse", "HEAD"], timeoutMs, signal),
15042
- git3(
15958
+ git4(folder, ["rev-parse", "HEAD"], timeoutMs, signal),
15959
+ git4(
15043
15960
  folder,
15044
15961
  [
15045
15962
  "--no-optional-locks",
@@ -15055,7 +15972,7 @@ async function inspectWorktreeItem(folderValue2, rootFolder, baseBranch, primary
15055
15972
  ]);
15056
15973
  const symbolicBranch = branchResult.exitCode === 0 ? branchResult.stdout.trim() : null;
15057
15974
  const branch = symbolicBranch ?? (rebasing ? await rebaseBranch(folder, timeoutMs, signal) : null);
15058
- const upstreamResult = branch ? await git3(
15975
+ const upstreamResult = branch ? await git4(
15059
15976
  folder,
15060
15977
  ["rev-parse", "--abbrev-ref", "--symbolic-full-name", "@{upstream}"],
15061
15978
  timeoutMs,
@@ -15078,7 +15995,7 @@ async function inspectWorktreeItem(folderValue2, rootFolder, baseBranch, primary
15078
15995
  return {
15079
15996
  gitDirectory: gitDir,
15080
15997
  folder,
15081
- relativePath: relative7(rootFolder, folder) || ".",
15998
+ relativePath: relative8(rootFolder, folder) || ".",
15082
15999
  primary,
15083
16000
  branch,
15084
16001
  headSha: headResult.exitCode === 0 ? headResult.stdout.trim() : null,
@@ -15106,7 +16023,7 @@ async function inspectWorktreeItem(folderValue2, rootFolder, baseBranch, primary
15106
16023
  return {
15107
16024
  gitDirectory: folderValue2,
15108
16025
  folder: folderValue2,
15109
- relativePath: relative7(rootFolder, folderValue2) || ".",
16026
+ relativePath: relative8(rootFolder, folderValue2) || ".",
15110
16027
  primary,
15111
16028
  branch: null,
15112
16029
  headSha: null,
@@ -15123,15 +16040,15 @@ async function inspectWorktreeItem(folderValue2, rootFolder, baseBranch, primary
15123
16040
  hasConflicts: false,
15124
16041
  pushStatus: "UNKNOWN",
15125
16042
  availability: "ERROR",
15126
- error: cleanError3(error),
16043
+ error: cleanError4(error),
15127
16044
  checkedAt
15128
16045
  };
15129
16046
  }
15130
16047
  }
15131
16048
  async function discoverWorktrees(rootFolderValue, baseOverrides, knownDefaultBranch, timeoutMs, signal) {
15132
- const rootFolder = await realpath8(rootFolderValue);
15133
- const list = requireSuccess3(
15134
- await git3(
16049
+ const rootFolder = await realpath9(rootFolderValue);
16050
+ const list = requireSuccess4(
16051
+ await git4(
15135
16052
  rootFolder,
15136
16053
  ["worktree", "list", "--porcelain"],
15137
16054
  timeoutMs,
@@ -15139,14 +16056,14 @@ async function discoverWorktrees(rootFolderValue, baseOverrides, knownDefaultBra
15139
16056
  ),
15140
16057
  "Could not list Git worktrees"
15141
16058
  );
15142
- const remoteHead = await git3(
16059
+ const remoteHead = await git4(
15143
16060
  rootFolder,
15144
16061
  ["ls-remote", "--symref", "origin", "HEAD"],
15145
16062
  timeoutMs,
15146
16063
  signal
15147
16064
  );
15148
16065
  let defaultBranch = remoteHead.stdout.match(/^ref:\s+refs\/heads\/([^\s]+)\s+HEAD/m)?.[1] ?? null;
15149
- const defaultResult = await git3(
16066
+ const defaultResult = await git4(
15150
16067
  rootFolder,
15151
16068
  ["symbolic-ref", "--short", "refs/remotes/origin/HEAD"],
15152
16069
  timeoutMs,
@@ -15157,13 +16074,13 @@ async function discoverWorktrees(rootFolderValue, baseOverrides, knownDefaultBra
15157
16074
  defaultBranch = localDefaultBranch || knownDefaultBranch;
15158
16075
  }
15159
16076
  const [localBranchesResult, remoteBranchesResult] = await Promise.all([
15160
- git3(
16077
+ git4(
15161
16078
  rootFolder,
15162
16079
  ["for-each-ref", "--format=%(refname:strip=2)", "refs/heads"],
15163
16080
  timeoutMs,
15164
16081
  signal
15165
16082
  ),
15166
- git3(
16083
+ git4(
15167
16084
  rootFolder,
15168
16085
  ["for-each-ref", "--format=%(refname:strip=3)", "refs/remotes/origin"],
15169
16086
  timeoutMs,
@@ -15226,7 +16143,7 @@ async function untrackedLines(folder, path) {
15226
16143
  try {
15227
16144
  const file = await stat10(`${folder}/${path}`);
15228
16145
  if (!file.isFile() || file.size > 1024 * 1024) return null;
15229
- const contents = await readFile8(`${folder}/${path}`);
16146
+ const contents = await readFile9(`${folder}/${path}`);
15230
16147
  if (contents.includes(0)) return null;
15231
16148
  const text2 = contents.toString("utf8");
15232
16149
  return text2 ? text2.split("\n").length - (text2.endsWith("\n") ? 1 : 0) : 0;
@@ -15236,16 +16153,16 @@ async function untrackedLines(folder, path) {
15236
16153
  }
15237
16154
  async function inspectChanges(folder, timeoutMs, signal) {
15238
16155
  const [statusResult, stagedResult, unstagedResult] = await Promise.all([
15239
- git3(
16156
+ git4(
15240
16157
  folder,
15241
16158
  ["status", "--porcelain=v1", "-z", "--untracked-files=all"],
15242
16159
  timeoutMs,
15243
16160
  signal
15244
16161
  ),
15245
- git3(folder, ["diff", "--cached", "--numstat", "-z"], timeoutMs, signal),
15246
- git3(folder, ["diff", "--numstat", "-z"], timeoutMs, signal)
16162
+ git4(folder, ["diff", "--cached", "--numstat", "-z"], timeoutMs, signal),
16163
+ git4(folder, ["diff", "--numstat", "-z"], timeoutMs, signal)
15247
16164
  ]);
15248
- requireSuccess3(statusResult, "Could not inspect worktree changes");
16165
+ requireSuccess4(statusResult, "Could not inspect worktree changes");
15249
16166
  const stagedCounts = parseNumstat(stagedResult.stdout);
15250
16167
  const unstagedCounts = parseNumstat(unstagedResult.stdout);
15251
16168
  const values = statusResult.stdout.split("\0").filter(Boolean);
@@ -15305,11 +16222,11 @@ function parseNameStatus(value) {
15305
16222
  }
15306
16223
  async function diffFiles(folder, range, timeoutMs, signal) {
15307
16224
  const [status2, counts2] = await Promise.all([
15308
- git3(folder, ["diff", "--name-status", "-z", range], timeoutMs, signal),
15309
- git3(folder, ["diff", "--numstat", "-z", range], timeoutMs, signal)
16225
+ git4(folder, ["diff", "--name-status", "-z", range], timeoutMs, signal),
16226
+ git4(folder, ["diff", "--numstat", "-z", range], timeoutMs, signal)
15310
16227
  ]);
15311
- requireSuccess3(status2, "Could not inspect changed files");
15312
- requireSuccess3(counts2, "Could not inspect changed line counts");
16228
+ requireSuccess4(status2, "Could not inspect changed files");
16229
+ requireSuccess4(counts2, "Could not inspect changed line counts");
15313
16230
  const numstat = parseNumstat(counts2.stdout);
15314
16231
  return parseNameStatus(status2.stdout).map((file) => {
15315
16232
  const [additions, deletions] = numstat.get(file.path) ?? [null, null];
@@ -15323,8 +16240,8 @@ async function diffFiles(folder, range, timeoutMs, signal) {
15323
16240
  });
15324
16241
  }
15325
16242
  async function inspectBranchChanges(folder, baseBranch, timeoutMs, signal) {
15326
- const mergeBase = requireSuccess3(
15327
- await git3(
16243
+ const mergeBase = requireSuccess4(
16244
+ await git4(
15328
16245
  folder,
15329
16246
  ["merge-base", `refs/remotes/origin/${baseBranch}`, "HEAD"],
15330
16247
  timeoutMs,
@@ -15341,8 +16258,8 @@ async function inspectBranchChanges(folder, baseBranch, timeoutMs, signal) {
15341
16258
  return { changes: files.slice(0, 500), truncated: files.length > 500 };
15342
16259
  }
15343
16260
  async function inspectCommits(folder, baseBranch, timeoutMs, signal) {
15344
- const result = requireSuccess3(
15345
- await git3(
16261
+ const result = requireSuccess4(
16262
+ await git4(
15346
16263
  folder,
15347
16264
  [
15348
16265
  "log",
@@ -15375,7 +16292,7 @@ async function inspectWorktreeDetail(folder, baseBranch, timeoutMs, signal) {
15375
16292
  inspectCommits(folder, baseBranch, timeoutMs, signal),
15376
16293
  inspectChanges(folder, timeoutMs, signal),
15377
16294
  inspectBranchChanges(folder, baseBranch, timeoutMs, signal),
15378
- git3(
16295
+ git4(
15379
16296
  folder,
15380
16297
  ["config", "--bool", "--get", "commit.gpgsign"],
15381
16298
  timeoutMs,
@@ -15393,8 +16310,8 @@ async function inspectWorktreeDetail(folder, baseBranch, timeoutMs, signal) {
15393
16310
  };
15394
16311
  }
15395
16312
  async function baseMergeCommit(folder, baseBranch, timeoutMs, signal) {
15396
- return requireSuccess3(
15397
- await git3(
16313
+ return requireSuccess4(
16314
+ await git4(
15398
16315
  folder,
15399
16316
  ["merge-base", `refs/remotes/origin/${baseBranch}`, "HEAD"],
15400
16317
  timeoutMs,
@@ -15409,13 +16326,13 @@ async function validateDisplayedCommit(folder, baseBranch, commitSha, timeoutMs,
15409
16326
  }
15410
16327
  const base = await baseMergeCommit(folder, baseBranch, timeoutMs, signal);
15411
16328
  const [afterBase, beforeHead] = await Promise.all([
15412
- git3(
16329
+ git4(
15413
16330
  folder,
15414
16331
  ["merge-base", "--is-ancestor", base, commitSha],
15415
16332
  timeoutMs,
15416
16333
  signal
15417
16334
  ),
15418
- git3(
16335
+ git4(
15419
16336
  folder,
15420
16337
  ["merge-base", "--is-ancestor", commitSha, "HEAD"],
15421
16338
  timeoutMs,
@@ -15427,7 +16344,7 @@ async function validateDisplayedCommit(folder, baseBranch, commitSha, timeoutMs,
15427
16344
  }
15428
16345
  }
15429
16346
  async function parentCommit(folder, commitSha, timeoutMs, signal) {
15430
- const result = await git3(
16347
+ const result = await git4(
15431
16348
  folder,
15432
16349
  ["rev-parse", `${commitSha}^`],
15433
16350
  timeoutMs,
@@ -15436,13 +16353,13 @@ async function parentCommit(folder, commitSha, timeoutMs, signal) {
15436
16353
  return result.exitCode === 0 ? result.stdout.trim() : null;
15437
16354
  }
15438
16355
  async function gitObjectExists(folder, specification, timeoutMs, signal) {
15439
- return (await git3(folder, ["cat-file", "-e", specification], timeoutMs, signal)).exitCode === 0;
16356
+ return (await git4(folder, ["cat-file", "-e", specification], timeoutMs, signal)).exitCode === 0;
15440
16357
  }
15441
16358
  async function comparisonSides(input, folder, timeoutMs, signal) {
15442
16359
  if (!input.path) return { before: null, after: null };
15443
16360
  const path = input.path;
15444
16361
  const previousPath = input.previousPath ?? path;
15445
- const currentPath = join13(folder, path);
16362
+ const currentPath = join14(folder, path);
15446
16363
  if (input.scope === "UNTRACKED") {
15447
16364
  return { before: null, after: { kind: "FILE", path: currentPath } };
15448
16365
  }
@@ -15544,8 +16461,8 @@ async function availableSide(side, folder, timeoutMs, signal) {
15544
16461
  return gitObjectExists(folder, side.specification, timeoutMs, signal);
15545
16462
  }
15546
16463
  try {
15547
- const resolved = await realpath8(side.path);
15548
- const difference = relative7(folder, resolved);
16464
+ const resolved = await realpath9(side.path);
16465
+ const difference = relative8(folder, resolved);
15549
16466
  return difference !== ".." && !difference.startsWith("../") && (await stat10(resolved)).isFile();
15550
16467
  } catch {
15551
16468
  return false;
@@ -15617,7 +16534,7 @@ async function inspectRequestedDiff(input, folder, timeoutMs, signal) {
15617
16534
  let patch;
15618
16535
  if (input.scope === "UNTRACKED") {
15619
16536
  const bounded = await readBoundedFile(
15620
- join13(folder, input.path),
16537
+ join14(folder, input.path),
15621
16538
  MAX_DIFF_BYTES
15622
16539
  );
15623
16540
  const contents = bounded.contents;
@@ -15628,8 +16545,8 @@ async function inspectRequestedDiff(input, folder, timeoutMs, signal) {
15628
16545
  patch = untrackedTextPatch(input.path, contents);
15629
16546
  }
15630
16547
  } else {
15631
- patch = requireSuccess3(
15632
- await git3(folder, args, timeoutMs, signal),
16548
+ patch = requireSuccess4(
16549
+ await git4(folder, args, timeoutMs, signal),
15633
16550
  "Could not load the file diff"
15634
16551
  ).stdout;
15635
16552
  }
@@ -15652,7 +16569,7 @@ async function validateChangedPath(input, folder, timeoutMs, signal) {
15652
16569
  if (!input.path) throw new Error("A changed file path is required");
15653
16570
  let result;
15654
16571
  if (input.scope === "UNTRACKED") {
15655
- result = await git3(
16572
+ result = await git4(
15656
16573
  folder,
15657
16574
  ["ls-files", "--others", "--exclude-standard", "-z", "--", input.path],
15658
16575
  timeoutMs,
@@ -15683,9 +16600,9 @@ async function validateChangedPath(input, folder, timeoutMs, signal) {
15683
16600
  );
15684
16601
  }
15685
16602
  args.push("--", ...requestedDiffPaths(input));
15686
- result = await git3(folder, args, timeoutMs, signal);
16603
+ result = await git4(folder, args, timeoutMs, signal);
15687
16604
  }
15688
- requireSuccess3(result, "Could not validate the changed file");
16605
+ requireSuccess4(result, "Could not validate the changed file");
15689
16606
  const requested = input.scope === "UNTRACKED" ? result.stdout.split("\0").filter(Boolean).includes(input.path) : parseNameStatus(result.stdout).some(
15690
16607
  (file) => file.path === input.path && (!input.previousPath || file.previousPath === input.previousPath)
15691
16608
  );
@@ -15750,7 +16667,7 @@ async function writeGitObject(folder, specification, destination, timeoutMs, sig
15750
16667
  signal.removeEventListener("abort", abort);
15751
16668
  if (settled) return;
15752
16669
  if (code !== 0) {
15753
- fail(new Error(cleanError3(stderr || "Could not extract image")));
16670
+ fail(new Error(cleanError4(stderr || "Could not extract image")));
15754
16671
  return;
15755
16672
  }
15756
16673
  output.end(() => {
@@ -15781,14 +16698,14 @@ var downloadWorktreeDiffAsset = async (payload, timeoutMs, signal, _onLog, conte
15781
16698
  let temporaryDirectory = null;
15782
16699
  try {
15783
16700
  if (selected.kind === "FILE") {
15784
- uploadPath = await realpath8(selected.path);
15785
- const difference = relative7(folder, uploadPath);
16701
+ uploadPath = await realpath9(selected.path);
16702
+ const difference = relative8(folder, uploadPath);
15786
16703
  if (difference === ".." || difference.startsWith("../")) {
15787
16704
  throw new Error("Diff image resolves outside the worktree");
15788
16705
  }
15789
16706
  } else {
15790
- const size = requireSuccess3(
15791
- await git3(
16707
+ const size = requireSuccess4(
16708
+ await git4(
15792
16709
  folder,
15793
16710
  ["cat-file", "-s", selected.specification],
15794
16711
  timeoutMs,
@@ -15799,8 +16716,8 @@ var downloadWorktreeDiffAsset = async (payload, timeoutMs, signal, _onLog, conte
15799
16716
  if (!/^\d+$/.test(size) || Number(size) > 20 * 1024 * 1024) {
15800
16717
  throw new Error("Diff image exceeds the 20 MiB limit");
15801
16718
  }
15802
- temporaryDirectory = await mkdtemp6(join13(tmpdir6(), "ade-diff-image-"));
15803
- uploadPath = join13(temporaryDirectory, basename5(input.path));
16719
+ temporaryDirectory = await mkdtemp6(join14(tmpdir6(), "ade-diff-image-"));
16720
+ uploadPath = join14(temporaryDirectory, basename5(input.path));
15804
16721
  await writeGitObject(
15805
16722
  folder,
15806
16723
  selected.specification,
@@ -15822,7 +16739,7 @@ var downloadWorktreeDiffAsset = async (payload, timeoutMs, signal, _onLog, conte
15822
16739
  return successfulProcess8;
15823
16740
  } finally {
15824
16741
  if (temporaryDirectory) {
15825
- await rm9(temporaryDirectory, { recursive: true, force: true });
16742
+ await rm10(temporaryDirectory, { recursive: true, force: true });
15826
16743
  }
15827
16744
  }
15828
16745
  };
@@ -15918,7 +16835,7 @@ var inspectWorktreeGit = async (payload, timeoutMs, signal) => {
15918
16835
  var commitWorktree = async (payload, timeoutMs, signal) => {
15919
16836
  const input = worktreeCommitJobPayload(payload);
15920
16837
  const folder = await validateWorktree2(input, timeoutMs, signal);
15921
- const runGit = async (args, fallback) => requireSuccess3(await git3(folder, args, timeoutMs, signal), fallback);
16838
+ const runGit = async (args, fallback) => requireSuccess4(await git4(folder, args, timeoutMs, signal), fallback);
15922
16839
  if (input.stageAll) {
15923
16840
  await runGit(["add", "--all"], "Could not stage worktree changes");
15924
16841
  } else {
@@ -15931,7 +16848,7 @@ var commitWorktree = async (payload, timeoutMs, signal) => {
15931
16848
  if (!change) throw new Error(`Worktree change no longer exists: ${path}`);
15932
16849
  return change;
15933
16850
  });
15934
- const head = await git3(
16851
+ const head = await git4(
15935
16852
  folder,
15936
16853
  ["rev-parse", "--verify", "HEAD"],
15937
16854
  timeoutMs,
@@ -15960,7 +16877,7 @@ var commitWorktree = async (payload, timeoutMs, signal) => {
15960
16877
  "Could not stage selected worktree changes"
15961
16878
  );
15962
16879
  }
15963
- const staged = await git3(
16880
+ const staged = await git4(
15964
16881
  folder,
15965
16882
  ["diff", "--cached", "--quiet", "--exit-code"],
15966
16883
  timeoutMs,
@@ -15968,10 +16885,10 @@ var commitWorktree = async (payload, timeoutMs, signal) => {
15968
16885
  );
15969
16886
  if (staged.exitCode === 0) throw new Error("No staged changes to commit");
15970
16887
  if (staged.exitCode !== 1)
15971
- requireSuccess3(staged, "Could not inspect staged changes");
16888
+ requireSuccess4(staged, "Could not inspect staged changes");
15972
16889
  let signed = input.signed;
15973
16890
  if (signed === null) {
15974
- const configured = await git3(
16891
+ const configured = await git4(
15975
16892
  folder,
15976
16893
  ["config", "--bool", "--get", "commit.gpgsign"],
15977
16894
  timeoutMs,
@@ -16028,7 +16945,7 @@ var operateWorktreeGit = async (payload, timeoutMs, signal) => {
16028
16945
  };
16029
16946
  };
16030
16947
  async function refExists(folder, ref, timeoutMs, signal) {
16031
- const result = await git3(
16948
+ const result = await git4(
16032
16949
  folder,
16033
16950
  ["show-ref", "--verify", "--quiet", ref],
16034
16951
  timeoutMs,
@@ -16037,13 +16954,13 @@ async function refExists(folder, ref, timeoutMs, signal) {
16037
16954
  return result.exitCode === 0;
16038
16955
  }
16039
16956
  async function resolveHead(folder, ref, timeoutMs, signal) {
16040
- return requireSuccess3(
16041
- await git3(folder, ["rev-parse", ref], timeoutMs, signal),
16957
+ return requireSuccess4(
16958
+ await git4(folder, ["rev-parse", ref], timeoutMs, signal),
16042
16959
  `Could not resolve ${ref}`
16043
16960
  ).stdout.trim();
16044
16961
  }
16045
16962
  async function isAncestor(folder, ancestor, descendant, timeoutMs, signal) {
16046
- const result = await git3(
16963
+ const result = await git4(
16047
16964
  folder,
16048
16965
  ["merge-base", "--is-ancestor", ancestor, descendant],
16049
16966
  timeoutMs,
@@ -16051,12 +16968,12 @@ async function isAncestor(folder, ancestor, descendant, timeoutMs, signal) {
16051
16968
  );
16052
16969
  if (result.exitCode === 0) return true;
16053
16970
  if (result.exitCode === 1) return false;
16054
- requireSuccess3(result, "Could not compare Git history");
16971
+ requireSuccess4(result, "Could not compare Git history");
16055
16972
  return false;
16056
16973
  }
16057
16974
  async function statusState(folder, timeoutMs, signal) {
16058
- const result = requireSuccess3(
16059
- await git3(
16975
+ const result = requireSuccess4(
16976
+ await git4(
16060
16977
  folder,
16061
16978
  ["status", "--porcelain=v1", "-z", "--untracked-files=all"],
16062
16979
  timeoutMs,
@@ -16070,7 +16987,7 @@ function hasChanges(changes) {
16070
16987
  return changes.hasStagedChanges || changes.hasUnstagedChanges;
16071
16988
  }
16072
16989
  async function currentBranch(folder, timeoutMs, signal) {
16073
- const result = await git3(
16990
+ const result = await git4(
16074
16991
  folder,
16075
16992
  ["symbolic-ref", "--short", "-q", "HEAD"],
16076
16993
  timeoutMs,
@@ -16090,7 +17007,7 @@ async function chooseNewBranch(folder, candidates, allowedCurrentBranch, timeout
16090
17007
  throw new Error("Every generated ticket branch name is already taken");
16091
17008
  }
16092
17009
  async function validateBranchRoot(input, timeoutMs, signal) {
16093
- const rootFolder = await realpath8(input.rootFolder);
17010
+ const rootFolder = await realpath9(input.rootFolder);
16094
17011
  if (!(await stat10(rootFolder)).isDirectory()) {
16095
17012
  throw new Error("Base repository is missing");
16096
17013
  }
@@ -16154,8 +17071,8 @@ var branchWorktree = async (payload, timeoutMs, signal) => {
16154
17071
  timeoutMs,
16155
17072
  signal
16156
17073
  ) : input.candidates[0];
16157
- const targetFolder = input.action === "CREATE" ? join13(
16158
- dirname7(rootFolder),
17074
+ const targetFolder = input.action === "CREATE" ? join14(
17075
+ dirname8(rootFolder),
16159
17076
  `${basename5(rootFolder)}-${branch.replaceAll("/", "-")}`
16160
17077
  ) : changeFolder;
16161
17078
  if (input.action === "CREATE") {
@@ -16200,40 +17117,89 @@ var branchWorktree = async (payload, timeoutMs, signal) => {
16200
17117
  ];
16201
17118
  }
16202
17119
  let stashed = false;
16203
- if (args.length > 0) {
16204
- let switched = await git3(
16205
- input.action === "CREATE" ? rootFolder : targetFolder,
16206
- args,
17120
+ let preparationsSuspended = false;
17121
+ const reapplyPreparations = () => executeWorktreePreparations(
17122
+ targetFolder,
17123
+ input.preparations,
17124
+ "APPLY",
17125
+ timeoutMs,
17126
+ signal
17127
+ );
17128
+ if (args.length > 0 && input.action === "CHANGE" && input.preparations.length > 0) {
17129
+ const suspended = await suspendWorktreePreparations(
17130
+ targetFolder,
17131
+ input.preparations,
16207
17132
  timeoutMs,
16208
- signal
17133
+ signal,
17134
+ true
16209
17135
  );
16210
- if (switched.exitCode !== 0 && input.action === "CHANGE" && input.stashOnFailure) {
16211
- const stash = requireSuccess3(
16212
- await git3(
16213
- targetFolder,
16214
- [
16215
- "stash",
16216
- "push",
16217
- "--include-untracked",
16218
- "-m",
16219
- `Automatic stash before switching to ${branch}`
16220
- ],
16221
- timeoutMs,
16222
- signal
16223
- ),
16224
- "Could not stash worktree changes"
17136
+ preparationsSuspended = true;
17137
+ const failed = suspended.filter((item) => item.state === "ERROR");
17138
+ if (failed.length > 0) {
17139
+ await reapplyPreparations();
17140
+ throw new Error(
17141
+ failed.map((item) => item.message ?? "Preparation failed").join("; ")
16225
17142
  );
16226
- stashed = !stash.stdout.toLowerCase().includes("no local changes");
16227
- switched = await git3(targetFolder, args, timeoutMs, signal);
16228
- if (switched.exitCode !== 0) {
16229
- throw new Error(
16230
- `${cleanError3(switched.stderr || "Branch switch failed after stashing")}. The stash was preserved.`
17143
+ }
17144
+ }
17145
+ if (args.length > 0) {
17146
+ try {
17147
+ let switched = await git4(
17148
+ input.action === "CREATE" ? rootFolder : targetFolder,
17149
+ args,
17150
+ timeoutMs,
17151
+ signal
17152
+ );
17153
+ if (switched.exitCode !== 0 && input.action === "CHANGE" && input.stashOnFailure) {
17154
+ const stash = requireSuccess4(
17155
+ await git4(
17156
+ targetFolder,
17157
+ [
17158
+ "stash",
17159
+ "push",
17160
+ "--include-untracked",
17161
+ "-m",
17162
+ `Automatic stash before switching to ${branch}`
17163
+ ],
17164
+ timeoutMs,
17165
+ signal
17166
+ ),
17167
+ "Could not stash worktree changes"
17168
+ );
17169
+ stashed = !stash.stdout.toLowerCase().includes("no local changes");
17170
+ switched = await git4(targetFolder, args, timeoutMs, signal);
17171
+ if (switched.exitCode !== 0) {
17172
+ throw new Error(
17173
+ `${cleanError4(switched.stderr || "Branch switch failed after stashing")}. The stash was preserved.`
17174
+ );
17175
+ }
17176
+ } else {
17177
+ requireSuccess4(
17178
+ switched,
17179
+ input.action === "CREATE" ? "Could not create the worktree" : "Could not change the worktree branch"
16231
17180
  );
16232
17181
  }
16233
- } else {
16234
- requireSuccess3(
16235
- switched,
16236
- input.action === "CREATE" ? "Could not create the worktree" : "Could not change the worktree branch"
17182
+ } catch (error) {
17183
+ if (preparationsSuspended) await reapplyPreparations();
17184
+ throw error;
17185
+ }
17186
+ }
17187
+ let preparations = [];
17188
+ if (input.preparations.length > 0) {
17189
+ preparations = await reapplyPreparations();
17190
+ const failed = preparations.filter((item) => item.state === "ERROR");
17191
+ if (failed.length > 0 && input.action === "CREATE") {
17192
+ await git4(
17193
+ rootFolder,
17194
+ ["worktree", "remove", "--force", targetFolder],
17195
+ timeoutMs,
17196
+ signal
17197
+ );
17198
+ if (input.mode === "NEW") {
17199
+ await git4(rootFolder, ["branch", "-D", branch], timeoutMs, signal);
17200
+ }
17201
+ throw new Error(
17202
+ failed.map((item) => item.message ?? "Preparation failed").join("; ")
16237
17203
  );
16238
17204
  }
16239
17205
  }
@@ -16253,7 +17219,9 @@ var branchWorktree = async (payload, timeoutMs, signal) => {
16253
17219
  worktree,
16254
17220
  branch,
16255
17221
  baseBranch: input.baseBranch,
16256
- stashed
17222
+ stashed,
17223
+ checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
17224
+ preparations
16257
17225
  };
16258
17226
  };
16259
17227
  var pushMovedWorktree = async (payload, timeoutMs, signal) => {
@@ -16280,8 +17248,8 @@ var pushMovedWorktree = async (payload, timeoutMs, signal) => {
16280
17248
  if (hasChanges(changes)) {
16281
17249
  throw new Error("Commit or discard source changes before moving");
16282
17250
  }
16283
- requireSuccess3(
16284
- await git3(folder, ["fetch", "origin"], timeoutMs, signal),
17251
+ requireSuccess4(
17252
+ await git4(folder, ["fetch", "origin"], timeoutMs, signal),
16285
17253
  "Could not fetch origin before moving"
16286
17254
  );
16287
17255
  const remoteRef = `refs/remotes/origin/${branch}`;
@@ -16290,8 +17258,8 @@ var pushMovedWorktree = async (payload, timeoutMs, signal) => {
16290
17258
  "The origin branch contains commits that must be pulled before moving"
16291
17259
  );
16292
17260
  }
16293
- requireSuccess3(
16294
- await git3(
17261
+ requireSuccess4(
17262
+ await git4(
16295
17263
  folder,
16296
17264
  ["push", "--set-upstream", "origin", `HEAD:refs/heads/${branch}`],
16297
17265
  timeoutMs,
@@ -16326,8 +17294,8 @@ async function updateLocalBranchForMove(rootFolder, branch, expectedHeadSha, tim
16326
17294
  `Local branch ${branch} has commits that are not on origin; move them before retrying`
16327
17295
  );
16328
17296
  }
16329
- requireSuccess3(
16330
- await git3(
17297
+ requireSuccess4(
17298
+ await git4(
16331
17299
  rootFolder,
16332
17300
  ["branch", "-f", branch, expectedHeadSha],
16333
17301
  timeoutMs,
@@ -16338,8 +17306,8 @@ async function updateLocalBranchForMove(rootFolder, branch, expectedHeadSha, tim
16338
17306
  return true;
16339
17307
  }
16340
17308
  async function checkedOutBranchFolder(rootFolder, branch, timeoutMs, signal) {
16341
- const result = requireSuccess3(
16342
- await git3(
17309
+ const result = requireSuccess4(
17310
+ await git4(
16343
17311
  rootFolder,
16344
17312
  ["worktree", "list", "--porcelain"],
16345
17313
  timeoutMs,
@@ -16355,8 +17323,8 @@ var checkoutMovedWorktree = async (payload, timeoutMs, signal) => {
16355
17323
  const input = worktreeMoveCheckoutJobPayload(payload);
16356
17324
  const rootFolder = await validateBranchRoot(input, timeoutMs, signal);
16357
17325
  const remoteRef = `refs/remotes/origin/${input.branch}`;
16358
- requireSuccess3(
16359
- await git3(
17326
+ requireSuccess4(
17327
+ await git4(
16360
17328
  rootFolder,
16361
17329
  [
16362
17330
  "fetch",
@@ -16381,6 +17349,7 @@ var checkoutMovedWorktree = async (payload, timeoutMs, signal) => {
16381
17349
  );
16382
17350
  }
16383
17351
  let targetFolder;
17352
+ let createdLocalBranch = false;
16384
17353
  let stashed = false;
16385
17354
  const occupiedFolder = await checkedOutBranchFolder(
16386
17355
  rootFolder,
@@ -16394,8 +17363,8 @@ var checkoutMovedWorktree = async (payload, timeoutMs, signal) => {
16394
17363
  `Branch ${input.branch} is already checked out in ${occupiedFolder}`
16395
17364
  );
16396
17365
  }
16397
- targetFolder = join13(
16398
- dirname7(rootFolder),
17366
+ targetFolder = join14(
17367
+ dirname8(rootFolder),
16399
17368
  `${basename5(rootFolder)}-${input.branch.replaceAll("/", "-")}`
16400
17369
  );
16401
17370
  try {
@@ -16413,8 +17382,9 @@ var checkoutMovedWorktree = async (payload, timeoutMs, signal) => {
16413
17382
  timeoutMs,
16414
17383
  signal
16415
17384
  );
16416
- requireSuccess3(
16417
- await git3(
17385
+ createdLocalBranch = !local;
17386
+ requireSuccess4(
17387
+ await git4(
16418
17388
  rootFolder,
16419
17389
  local ? ["worktree", "add", targetFolder, input.branch] : [
16420
17390
  "worktree",
@@ -16445,7 +17415,7 @@ var checkoutMovedWorktree = async (payload, timeoutMs, signal) => {
16445
17415
  const targetBranch = await currentBranch(targetFolder, timeoutMs, signal);
16446
17416
  const targetChanges = await statusState(targetFolder, timeoutMs, signal);
16447
17417
  if (occupiedFolder) {
16448
- const occupied = await realpath8(occupiedFolder);
17418
+ const occupied = await realpath9(occupiedFolder);
16449
17419
  if (occupied !== targetFolder) {
16450
17420
  throw new Error(
16451
17421
  `Branch ${input.branch} is checked out in another destination worktree`
@@ -16483,8 +17453,8 @@ var checkoutMovedWorktree = async (payload, timeoutMs, signal) => {
16483
17453
  switchArgs = local ? ["switch", input.branch] : ["switch", "--track", "-c", input.branch, remoteRef];
16484
17454
  }
16485
17455
  if (input.stashOnFailure && hasChanges(targetChanges)) {
16486
- const stash = requireSuccess3(
16487
- await git3(
17456
+ const stash = requireSuccess4(
17457
+ await git4(
16488
17458
  targetFolder,
16489
17459
  [
16490
17460
  "stash",
@@ -16500,25 +17470,25 @@ var checkoutMovedWorktree = async (payload, timeoutMs, signal) => {
16500
17470
  );
16501
17471
  stashed = !stash.stdout.toLowerCase().includes("no local changes");
16502
17472
  }
16503
- const switched = await git3(targetFolder, switchArgs, timeoutMs, signal);
17473
+ const switched = await git4(targetFolder, switchArgs, timeoutMs, signal);
16504
17474
  if (switched.exitCode !== 0) {
16505
17475
  if (!input.stashOnFailure && hasChanges(targetChanges)) {
16506
17476
  return {
16507
17477
  ...successfulProcess8,
16508
17478
  moveId: input.moveId,
16509
17479
  outcome: "NEEDS_STASH",
16510
- message: cleanError3(
17480
+ message: cleanError4(
16511
17481
  switched.stderr || "Destination changes block the branch switch"
16512
17482
  )
16513
17483
  };
16514
17484
  }
16515
17485
  throw new Error(
16516
- `${cleanError3(switched.stderr || "Could not check out the moved branch")}${stashed ? ". The destination stash was preserved." : ""}`
17486
+ `${cleanError4(switched.stderr || "Could not check out the moved branch")}${stashed ? ". The destination stash was preserved." : ""}`
16517
17487
  );
16518
17488
  }
16519
17489
  }
16520
- requireSuccess3(
16521
- await git3(
17490
+ requireSuccess4(
17491
+ await git4(
16522
17492
  targetFolder,
16523
17493
  ["branch", "--set-upstream-to", `origin/${input.branch}`, input.branch],
16524
17494
  timeoutMs,
@@ -16535,6 +17505,30 @@ var checkoutMovedWorktree = async (payload, timeoutMs, signal) => {
16535
17505
  if (checkedOutHead !== input.expectedHeadSha) {
16536
17506
  throw new Error("The destination did not check out the pushed commit");
16537
17507
  }
17508
+ const preparations = await executeWorktreePreparations(
17509
+ targetFolder,
17510
+ input.preparations,
17511
+ "APPLY",
17512
+ timeoutMs,
17513
+ signal
17514
+ );
17515
+ const preparationErrors = preparations.filter(
17516
+ (item) => item.state === "ERROR"
17517
+ );
17518
+ if (preparationErrors.length > 0 && input.mode === "NEW") {
17519
+ await git4(
17520
+ rootFolder,
17521
+ ["worktree", "remove", "--force", targetFolder],
17522
+ timeoutMs,
17523
+ signal
17524
+ );
17525
+ if (createdLocalBranch) {
17526
+ await git4(rootFolder, ["branch", "-D", input.branch], timeoutMs, signal);
17527
+ }
17528
+ throw new Error(
17529
+ preparationErrors.map((item) => item.message ?? "Preparation failed").join("; ")
17530
+ );
17531
+ }
16538
17532
  const worktree = await inspectWorktreeItem(
16539
17533
  targetFolder,
16540
17534
  rootFolder,
@@ -16554,12 +17548,72 @@ var checkoutMovedWorktree = async (payload, timeoutMs, signal) => {
16554
17548
  outcome: "CHECKED_OUT",
16555
17549
  worktree,
16556
17550
  baseBranch: input.baseBranch,
16557
- stashed
17551
+ stashed,
17552
+ checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
17553
+ preparations
17554
+ };
17555
+ };
17556
+ var prepareWorktree = async (payload, timeoutMs, signal) => {
17557
+ const input = worktreePreparationJobPayload(payload);
17558
+ if ("worktrees" in input) {
17559
+ const worktrees = [];
17560
+ for (const target2 of input.worktrees) {
17561
+ try {
17562
+ const folder2 = await validateWorktree2(
17563
+ {
17564
+ codebaseId: input.codebaseId,
17565
+ folder: target2.folder,
17566
+ gitDirectory: target2.gitDirectory,
17567
+ expectedOrigin: input.expectedOrigin,
17568
+ baseBranch: null
17569
+ },
17570
+ timeoutMs,
17571
+ signal
17572
+ );
17573
+ const preparations2 = await executeWorktreePreparations(
17574
+ folder2,
17575
+ input.preparations,
17576
+ input.action,
17577
+ timeoutMs,
17578
+ signal
17579
+ );
17580
+ worktrees.push({
17581
+ worktreeId: target2.worktreeId,
17582
+ checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
17583
+ preparations: preparations2
17584
+ });
17585
+ } catch (error) {
17586
+ worktrees.push({
17587
+ worktreeId: target2.worktreeId,
17588
+ checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
17589
+ preparations: input.preparations.map((definition) => ({
17590
+ id: definition.id,
17591
+ definitionHash: definition.definitionHash,
17592
+ state: "ERROR",
17593
+ message: cleanError4(error)
17594
+ }))
17595
+ });
17596
+ }
17597
+ }
17598
+ return { ...successfulProcess8, worktrees };
17599
+ }
17600
+ const folder = await validateWorktree2(input, timeoutMs, signal);
17601
+ const preparations = await executeWorktreePreparations(
17602
+ folder,
17603
+ input.preparations,
17604
+ input.action,
17605
+ timeoutMs,
17606
+ signal
17607
+ );
17608
+ return {
17609
+ ...successfulProcess8,
17610
+ checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
17611
+ preparations
16558
17612
  };
16559
17613
  };
16560
17614
  var deleteWorktree = async (payload, timeoutMs, signal) => {
16561
17615
  const input = worktreeDeleteJobPayload(payload);
16562
- const rootFolder = await realpath8(input.rootFolder);
17616
+ const rootFolder = await realpath9(input.rootFolder);
16563
17617
  if (!(await stat10(rootFolder)).isDirectory()) {
16564
17618
  throw new Error("Base repository is missing");
16565
17619
  }
@@ -16580,8 +17634,8 @@ var deleteWorktree = async (payload, timeoutMs, signal) => {
16580
17634
  if (folder === rootFolder)
16581
17635
  throw new Error("The primary worktree cannot be deleted");
16582
17636
  const listed = parseWorktreeList(
16583
- requireSuccess3(
16584
- await git3(
17637
+ requireSuccess4(
17638
+ await git4(
16585
17639
  rootFolder,
16586
17640
  ["worktree", "list", "--porcelain"],
16587
17641
  timeoutMs,
@@ -16611,15 +17665,15 @@ var deleteWorktree = async (payload, timeoutMs, signal) => {
16611
17665
  if (branch === input.defaultBranch) {
16612
17666
  throw new Error("The default remote branch cannot be deleted");
16613
17667
  }
16614
- const remote = await git3(
17668
+ const remote = await git4(
16615
17669
  rootFolder,
16616
17670
  ["ls-remote", "--exit-code", "--heads", "origin", `refs/heads/${branch}`],
16617
17671
  timeoutMs,
16618
17672
  signal
16619
17673
  );
16620
17674
  if (remote.exitCode === 0) {
16621
- requireSuccess3(
16622
- await git3(
17675
+ requireSuccess4(
17676
+ await git4(
16623
17677
  rootFolder,
16624
17678
  ["push", "origin", "--delete", branch],
16625
17679
  timeoutMs,
@@ -16628,11 +17682,11 @@ var deleteWorktree = async (payload, timeoutMs, signal) => {
16628
17682
  `Could not delete origin/${branch}`
16629
17683
  );
16630
17684
  } else if (remote.exitCode !== 2) {
16631
- requireSuccess3(remote, `Could not inspect origin/${branch}`);
17685
+ requireSuccess4(remote, `Could not inspect origin/${branch}`);
16632
17686
  }
16633
17687
  }
16634
- requireSuccess3(
16635
- await git3(
17688
+ requireSuccess4(
17689
+ await git4(
16636
17690
  rootFolder,
16637
17691
  ["worktree", "remove", "--force", folder],
16638
17692
  timeoutMs,
@@ -16641,8 +17695,8 @@ var deleteWorktree = async (payload, timeoutMs, signal) => {
16641
17695
  "Could not remove the worktree"
16642
17696
  );
16643
17697
  if (branch && await refExists(rootFolder, `refs/heads/${branch}`, timeoutMs, signal)) {
16644
- requireSuccess3(
16645
- await git3(rootFolder, ["branch", "-D", branch], timeoutMs, signal),
17698
+ requireSuccess4(
17699
+ await git4(rootFolder, ["branch", "-D", branch], timeoutMs, signal),
16646
17700
  `Worktree removed, but local branch ${branch} could not be deleted`
16647
17701
  );
16648
17702
  }
@@ -16658,28 +17712,53 @@ var operateWorktree = async (payload, timeoutMs, signal) => {
16658
17712
  const input = worktreeJobPayload(payload);
16659
17713
  const folder = await validateWorktree2(input, timeoutMs, signal);
16660
17714
  if (!input.operation) throw new Error("A worktree operation is required");
16661
- const branchResult = await git3(
17715
+ const branchResult = await git4(
16662
17716
  folder,
16663
17717
  ["symbolic-ref", "--short", "-q", "HEAD"],
16664
17718
  timeoutMs,
16665
17719
  signal
16666
17720
  );
16667
17721
  const branch = branchResult.exitCode === 0 ? branchResult.stdout.trim() : null;
16668
- const upstreamResult = branch ? await git3(
17722
+ const upstreamResult = branch ? await git4(
16669
17723
  folder,
16670
17724
  ["rev-parse", "--abbrev-ref", "@{upstream}"],
16671
17725
  timeoutMs,
16672
17726
  signal
16673
17727
  ) : null;
16674
17728
  const upstream = upstreamResult?.exitCode === 0 ? upstreamResult.stdout.trim() : null;
16675
- const runGit = async (args, fallback) => requireSuccess3(await git3(folder, args, timeoutMs, signal), fallback);
17729
+ const runGit = async (args, fallback) => requireSuccess4(await git4(folder, args, timeoutMs, signal), fallback);
17730
+ let operationOutcome = "COMPLETED";
17731
+ let preparationConflictPathList = [];
17732
+ let preparationResults = [];
17733
+ const inspectPreparations = () => executeWorktreePreparations(
17734
+ folder,
17735
+ input.preparations,
17736
+ "INSPECT",
17737
+ timeoutMs,
17738
+ signal
17739
+ );
17740
+ const reapplyPreparations = () => executeWorktreePreparations(
17741
+ folder,
17742
+ input.preparations,
17743
+ "APPLY",
17744
+ timeoutMs,
17745
+ signal
17746
+ );
17747
+ const worktreeResult = async () => inspectWorktreeItem(
17748
+ folder,
17749
+ folder,
17750
+ input.baseBranch,
17751
+ false,
17752
+ Math.min(timeoutMs, 3e4),
17753
+ signal
17754
+ );
16676
17755
  switch (input.operation) {
16677
17756
  case "OPEN_EDITOR": {
16678
17757
  if (input.editorVariant === "NONE" || !input.editorVariant) {
16679
17758
  throw new Error("VS Code is disabled in Settings");
16680
17759
  }
16681
17760
  const app = input.editorVariant === "CODE_INSIDERS" ? "Visual Studio Code - Insiders" : "Visual Studio Code";
16682
- requireSuccess3(
17761
+ requireSuccess4(
16683
17762
  await command2("open", ["-a", app, folder], timeoutMs, signal),
16684
17763
  `${app} could not be opened`
16685
17764
  );
@@ -16701,26 +17780,105 @@ var operateWorktree = async (payload, timeoutMs, signal) => {
16701
17780
  if (statusResult.stdout.trim())
16702
17781
  throw new Error("Stash or commit changes before syncing");
16703
17782
  await runGit(["fetch", "origin"], "Could not fetch origin");
16704
- const rebase = await git3(
17783
+ const remoteBase = `refs/remotes/origin/${input.baseBranch}`;
17784
+ const isCurrent = await git4(
16705
17785
  folder,
16706
- ["rebase", `refs/remotes/origin/${input.baseBranch}`],
17786
+ ["merge-base", "--is-ancestor", remoteBase, "HEAD"],
16707
17787
  timeoutMs,
16708
17788
  signal
16709
17789
  );
16710
- if (rebase.exitCode !== 0) {
16711
- const status2 = await git3(
17790
+ if (isCurrent.exitCode !== 0 && isCurrent.exitCode !== 1) {
17791
+ requireSuccess4(isCurrent, "Could not compare the base branch");
17792
+ }
17793
+ if (isCurrent.exitCode === 1) {
17794
+ preparationConflictPathList = await preparationConflictPaths(
17795
+ folder,
17796
+ input.preparations,
17797
+ remoteBase,
17798
+ timeoutMs,
17799
+ signal
17800
+ );
17801
+ if (preparationConflictPathList.length > 0 && !input.forcePreparations) {
17802
+ operationOutcome = "PREPARATION_CONFLICT";
17803
+ preparationResults = await inspectPreparations();
17804
+ return {
17805
+ ...successfulProcess8,
17806
+ outcome: operationOutcome,
17807
+ preparationConflictPaths: preparationConflictPathList,
17808
+ checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
17809
+ preparations: preparationResults,
17810
+ worktree: await worktreeResult()
17811
+ };
17812
+ }
17813
+ if (input.forcePreparations) {
17814
+ preparationResults = await suspendWorktreePreparations(
17815
+ folder,
17816
+ input.preparations,
17817
+ timeoutMs,
17818
+ signal
17819
+ );
17820
+ if (preparationResults.some((item) => item.state === "ERROR")) {
17821
+ return {
17822
+ ...successfulProcess8,
17823
+ exitCode: 1,
17824
+ checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
17825
+ preparations: preparationResults
17826
+ };
17827
+ }
17828
+ }
17829
+ }
17830
+ const rebase = isCurrent.exitCode === 0 ? null : await git4(folder, ["rebase", remoteBase], timeoutMs, signal);
17831
+ if (rebase && rebase.exitCode !== 0) {
17832
+ const status2 = await git4(
16712
17833
  folder,
16713
17834
  ["status", "--porcelain=v1", "-z"],
16714
17835
  timeoutMs,
16715
17836
  signal
16716
17837
  );
16717
17838
  const conflicts = status2.exitCode === 0 && statusChangeState(status2.stdout).hasConflicts;
16718
- if (!(conflicts && await rebaseInProgress(folder, timeoutMs, signal))) {
16719
- await git3(folder, ["rebase", "--abort"], timeoutMs, signal);
17839
+ if (conflicts && await rebaseInProgress(folder, timeoutMs, signal)) {
17840
+ operationOutcome = "REBASE_CONFLICT";
17841
+ const conflictsResult = await git4(
17842
+ folder,
17843
+ ["diff", "--name-only", "--diff-filter=U"],
17844
+ timeoutMs,
17845
+ signal
17846
+ );
17847
+ preparationConflictPathList = conflictsResult.exitCode === 0 ? conflictsResult.stdout.split("\n").filter(Boolean) : [];
17848
+ preparationResults = input.preparations.map((definition) => ({
17849
+ id: definition.id,
17850
+ definitionHash: definition.definitionHash,
17851
+ state: "SUSPENDED"
17852
+ }));
17853
+ return {
17854
+ ...successfulProcess8,
17855
+ outcome: operationOutcome,
17856
+ preparationConflictPaths: preparationConflictPathList,
17857
+ checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
17858
+ preparations: preparationResults,
17859
+ worktree: await worktreeResult()
17860
+ };
17861
+ } else {
17862
+ await git4(folder, ["rebase", "--abort"], timeoutMs, signal);
17863
+ }
17864
+ if (input.forcePreparations) {
17865
+ preparationResults = await reapplyPreparations();
16720
17866
  }
16721
- throw new Error(cleanError3(rebase.stderr || "Rebase failed"));
17867
+ throw new Error(cleanError4(rebase.stderr || "Rebase failed"));
16722
17868
  }
16723
- await runGit(["push", "--force-with-lease"], "Sync push failed");
17869
+ const push = await git4(
17870
+ folder,
17871
+ ["push", "--force-with-lease"],
17872
+ timeoutMs,
17873
+ signal
17874
+ );
17875
+ if (push.exitCode !== 0) {
17876
+ if (input.forcePreparations) {
17877
+ preparationResults = await reapplyPreparations();
17878
+ }
17879
+ requireSuccess4(push, "Sync push failed");
17880
+ }
17881
+ preparationResults = input.forcePreparations ? await reapplyPreparations() : await inspectPreparations();
16724
17882
  break;
16725
17883
  }
16726
17884
  case "REBASE": {
@@ -16733,25 +17891,93 @@ var operateWorktree = async (payload, timeoutMs, signal) => {
16733
17891
  if (statusResult.stdout.trim())
16734
17892
  throw new Error("Stash or commit changes before rebasing");
16735
17893
  await runGit(["fetch", "origin"], "Could not fetch origin");
16736
- const rebase = await git3(
17894
+ const remoteBase = `refs/remotes/origin/${input.baseBranch}`;
17895
+ const isCurrent = await git4(
16737
17896
  folder,
16738
- ["rebase", `refs/remotes/origin/${input.baseBranch}`],
17897
+ ["merge-base", "--is-ancestor", remoteBase, "HEAD"],
16739
17898
  timeoutMs,
16740
17899
  signal
16741
17900
  );
16742
- if (rebase.exitCode !== 0) {
16743
- const status2 = await git3(
17901
+ if (isCurrent.exitCode !== 0 && isCurrent.exitCode !== 1) {
17902
+ requireSuccess4(isCurrent, "Could not compare the base branch");
17903
+ }
17904
+ if (isCurrent.exitCode === 1) {
17905
+ preparationConflictPathList = await preparationConflictPaths(
17906
+ folder,
17907
+ input.preparations,
17908
+ remoteBase,
17909
+ timeoutMs,
17910
+ signal
17911
+ );
17912
+ if (preparationConflictPathList.length > 0 && !input.forcePreparations) {
17913
+ operationOutcome = "PREPARATION_CONFLICT";
17914
+ preparationResults = await inspectPreparations();
17915
+ return {
17916
+ ...successfulProcess8,
17917
+ outcome: operationOutcome,
17918
+ preparationConflictPaths: preparationConflictPathList,
17919
+ checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
17920
+ preparations: preparationResults,
17921
+ worktree: await worktreeResult()
17922
+ };
17923
+ }
17924
+ if (input.forcePreparations) {
17925
+ preparationResults = await suspendWorktreePreparations(
17926
+ folder,
17927
+ input.preparations,
17928
+ timeoutMs,
17929
+ signal
17930
+ );
17931
+ if (preparationResults.some((item) => item.state === "ERROR")) {
17932
+ return {
17933
+ ...successfulProcess8,
17934
+ exitCode: 1,
17935
+ checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
17936
+ preparations: preparationResults
17937
+ };
17938
+ }
17939
+ }
17940
+ }
17941
+ const rebase = isCurrent.exitCode === 0 ? null : await git4(folder, ["rebase", remoteBase], timeoutMs, signal);
17942
+ if (rebase && rebase.exitCode !== 0) {
17943
+ const status2 = await git4(
16744
17944
  folder,
16745
17945
  ["status", "--porcelain=v1", "-z"],
16746
17946
  timeoutMs,
16747
17947
  signal
16748
17948
  );
16749
17949
  const conflicts = status2.exitCode === 0 && statusChangeState(status2.stdout).hasConflicts;
16750
- if (!(conflicts && await rebaseInProgress(folder, timeoutMs, signal))) {
16751
- await git3(folder, ["rebase", "--abort"], timeoutMs, signal);
17950
+ if (conflicts && await rebaseInProgress(folder, timeoutMs, signal)) {
17951
+ operationOutcome = "REBASE_CONFLICT";
17952
+ const conflictsResult = await git4(
17953
+ folder,
17954
+ ["diff", "--name-only", "--diff-filter=U"],
17955
+ timeoutMs,
17956
+ signal
17957
+ );
17958
+ preparationConflictPathList = conflictsResult.exitCode === 0 ? conflictsResult.stdout.split("\n").filter(Boolean) : [];
17959
+ preparationResults = input.preparations.map((definition) => ({
17960
+ id: definition.id,
17961
+ definitionHash: definition.definitionHash,
17962
+ state: "SUSPENDED"
17963
+ }));
17964
+ return {
17965
+ ...successfulProcess8,
17966
+ outcome: operationOutcome,
17967
+ preparationConflictPaths: preparationConflictPathList,
17968
+ checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
17969
+ preparations: preparationResults,
17970
+ worktree: await worktreeResult()
17971
+ };
17972
+ } else {
17973
+ await git4(folder, ["rebase", "--abort"], timeoutMs, signal);
16752
17974
  }
16753
- throw new Error(cleanError3(rebase.stderr || "Rebase failed"));
17975
+ if (input.forcePreparations) {
17976
+ preparationResults = await reapplyPreparations();
17977
+ }
17978
+ throw new Error(cleanError4(rebase.stderr || "Rebase failed"));
16754
17979
  }
17980
+ preparationResults = input.forcePreparations ? await reapplyPreparations() : await inspectPreparations();
16755
17981
  break;
16756
17982
  }
16757
17983
  case "CANCEL_REBASE": {
@@ -16759,6 +17985,7 @@ var operateWorktree = async (payload, timeoutMs, signal) => {
16759
17985
  throw new Error("No rebase is in progress");
16760
17986
  }
16761
17987
  await runGit(["rebase", "--abort"], "Could not cancel rebase");
17988
+ preparationResults = await reapplyPreparations();
16762
17989
  break;
16763
17990
  }
16764
17991
  case "PULL": {
@@ -16797,21 +18024,37 @@ var operateWorktree = async (payload, timeoutMs, signal) => {
16797
18024
  }
16798
18025
  return {
16799
18026
  ...successfulProcess8,
16800
- worktree: await inspectWorktreeItem(
16801
- folder,
16802
- folder,
16803
- input.baseBranch,
16804
- false,
16805
- Math.min(timeoutMs, 3e4),
16806
- signal
16807
- )
18027
+ outcome: operationOutcome,
18028
+ preparationConflictPaths: preparationConflictPathList,
18029
+ checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
18030
+ preparations: preparationResults,
18031
+ worktree: await worktreeResult()
16808
18032
  };
16809
18033
  };
16810
18034
  var autoSyncWorktree = async (payload, timeoutMs, signal) => {
16811
18035
  const input = worktreeAutoSyncJobPayload(payload);
16812
18036
  const folder = await validateWorktree2(input, timeoutMs, signal);
16813
- const runGit = async (args, fallback) => requireSuccess3(await git3(folder, args, timeoutMs, signal), fallback);
16814
- const branchResult = await git3(
18037
+ const runGit = async (args, fallback) => requireSuccess4(await git4(folder, args, timeoutMs, signal), fallback);
18038
+ const inspectPreparations = () => executeWorktreePreparations(
18039
+ folder,
18040
+ input.preparations,
18041
+ "INSPECT",
18042
+ timeoutMs,
18043
+ signal
18044
+ );
18045
+ const reapplyPreparations = () => executeWorktreePreparations(
18046
+ folder,
18047
+ input.preparations,
18048
+ "APPLY",
18049
+ timeoutMs,
18050
+ signal
18051
+ );
18052
+ const suspendedPreparations = () => input.preparations.map((definition) => ({
18053
+ id: definition.id,
18054
+ definitionHash: definition.definitionHash,
18055
+ state: "SUSPENDED"
18056
+ }));
18057
+ const branchResult = await git4(
16815
18058
  folder,
16816
18059
  ["symbolic-ref", "--short", "-q", "HEAD"],
16817
18060
  timeoutMs,
@@ -16824,7 +18067,7 @@ var autoSyncWorktree = async (payload, timeoutMs, signal) => {
16824
18067
  `Auto Sync expected branch ${input.expectedBranch}, but found ${branch ?? "detached HEAD"}`
16825
18068
  );
16826
18069
  }
16827
- const upstreamResult = branch ? await git3(
18070
+ const upstreamResult = branch ? await git4(
16828
18071
  folder,
16829
18072
  ["rev-parse", "--abbrev-ref", "@{upstream}"],
16830
18073
  timeoutMs,
@@ -16845,6 +18088,8 @@ var autoSyncWorktree = async (payload, timeoutMs, signal) => {
16845
18088
  return {
16846
18089
  ...successfulProcess8,
16847
18090
  outcome: "UNRESOLVED",
18091
+ checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
18092
+ preparations: suspendedPreparations(),
16848
18093
  worktree: await inspectWorktreeItem(
16849
18094
  folder,
16850
18095
  folder,
@@ -16873,6 +18118,8 @@ var autoSyncWorktree = async (payload, timeoutMs, signal) => {
16873
18118
  return {
16874
18119
  ...successfulProcess8,
16875
18120
  outcome: "UNRESOLVED",
18121
+ checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
18122
+ preparations: suspendedPreparations(),
16876
18123
  worktree: await inspectWorktreeItem(
16877
18124
  folder,
16878
18125
  folder,
@@ -16893,6 +18140,8 @@ var autoSyncWorktree = async (payload, timeoutMs, signal) => {
16893
18140
  return {
16894
18141
  ...successfulProcess8,
16895
18142
  outcome: "UNRESOLVED",
18143
+ checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
18144
+ preparations: suspendedPreparations(),
16896
18145
  worktree: await inspectWorktreeItem(
16897
18146
  folder,
16898
18147
  folder,
@@ -16903,13 +18152,13 @@ var autoSyncWorktree = async (payload, timeoutMs, signal) => {
16903
18152
  )
16904
18153
  };
16905
18154
  }
16906
- const finalBranch = await git3(
18155
+ const finalBranch = await git4(
16907
18156
  folder,
16908
18157
  ["symbolic-ref", "--short", "-q", "HEAD"],
16909
18158
  timeoutMs,
16910
18159
  signal
16911
18160
  );
16912
- const finalUpstream = finalBranch.exitCode === 0 ? await git3(
18161
+ const finalUpstream = finalBranch.exitCode === 0 ? await git4(
16913
18162
  folder,
16914
18163
  ["rev-parse", "--abbrev-ref", "@{upstream}"],
16915
18164
  timeoutMs,
@@ -16920,10 +18169,22 @@ var autoSyncWorktree = async (payload, timeoutMs, signal) => {
16920
18169
  `Auto Sync expected branch ${input.expectedBranch} with an upstream`
16921
18170
  );
16922
18171
  }
16923
- await runGit(["push", "--force-with-lease"], "Auto Sync push failed");
18172
+ const push2 = await git4(
18173
+ folder,
18174
+ ["push", "--force-with-lease"],
18175
+ timeoutMs,
18176
+ signal
18177
+ );
18178
+ if (push2.exitCode !== 0) {
18179
+ await reapplyPreparations();
18180
+ requireSuccess4(push2, "Auto Sync push failed");
18181
+ }
18182
+ const preparations = await reapplyPreparations();
16924
18183
  return {
16925
18184
  ...successfulProcess8,
16926
18185
  outcome: "SYNCED",
18186
+ checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
18187
+ preparations,
16927
18188
  worktree: await inspectWorktreeItem(
16928
18189
  folder,
16929
18190
  folder,
@@ -16943,14 +18204,14 @@ var autoSyncWorktree = async (payload, timeoutMs, signal) => {
16943
18204
  }
16944
18205
  await runGit(["fetch", "origin"], "Could not fetch origin");
16945
18206
  const remoteBase = `refs/remotes/origin/${input.baseBranch}`;
16946
- const isCurrent = await git3(
18207
+ const isCurrent = await git4(
16947
18208
  folder,
16948
18209
  ["merge-base", "--is-ancestor", remoteBase, "HEAD"],
16949
18210
  timeoutMs,
16950
18211
  signal
16951
18212
  );
16952
18213
  if (isCurrent.exitCode === 0) {
16953
- const upstreamContainsHead = await git3(
18214
+ const upstreamContainsHead = await git4(
16954
18215
  folder,
16955
18216
  ["merge-base", "--is-ancestor", "HEAD", "@{upstream}"],
16956
18217
  timeoutMs,
@@ -16958,7 +18219,7 @@ var autoSyncWorktree = async (payload, timeoutMs, signal) => {
16958
18219
  );
16959
18220
  if (upstreamContainsHead.exitCode !== 0 && upstreamContainsHead.exitCode !== 1) {
16960
18221
  throw new Error(
16961
- cleanError3(
18222
+ cleanError4(
16962
18223
  upstreamContainsHead.stderr || "Could not compare the upstream branch"
16963
18224
  )
16964
18225
  );
@@ -16968,6 +18229,8 @@ var autoSyncWorktree = async (payload, timeoutMs, signal) => {
16968
18229
  return {
16969
18230
  ...successfulProcess8,
16970
18231
  outcome: "SYNCED",
18232
+ checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
18233
+ preparations: await inspectPreparations(),
16971
18234
  worktree: await inspectWorktreeItem(
16972
18235
  folder,
16973
18236
  folder,
@@ -16981,6 +18244,32 @@ var autoSyncWorktree = async (payload, timeoutMs, signal) => {
16981
18244
  return {
16982
18245
  ...successfulProcess8,
16983
18246
  outcome: "NO_CHANGE",
18247
+ checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
18248
+ preparations: await inspectPreparations(),
18249
+ worktree: await inspectWorktreeItem(
18250
+ folder,
18251
+ folder,
18252
+ input.baseBranch,
18253
+ false,
18254
+ Math.min(timeoutMs, 3e4),
18255
+ signal
18256
+ )
18257
+ };
18258
+ }
18259
+ const preparationConflictPathList = await preparationConflictPaths(
18260
+ folder,
18261
+ input.preparations,
18262
+ remoteBase,
18263
+ timeoutMs,
18264
+ signal
18265
+ );
18266
+ if (preparationConflictPathList.length > 0 && !input.forcePreparations) {
18267
+ return {
18268
+ ...successfulProcess8,
18269
+ outcome: "PREPARATION_CONFLICT",
18270
+ preparationConflictPaths: preparationConflictPathList,
18271
+ checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
18272
+ preparations: await inspectPreparations(),
16984
18273
  worktree: await inspectWorktreeItem(
16985
18274
  folder,
16986
18275
  folder,
@@ -16991,9 +18280,26 @@ var autoSyncWorktree = async (payload, timeoutMs, signal) => {
16991
18280
  )
16992
18281
  };
16993
18282
  }
16994
- const rebase = await git3(folder, ["rebase", remoteBase], timeoutMs, signal);
18283
+ let preparationResults = [];
18284
+ if (input.forcePreparations) {
18285
+ preparationResults = await suspendWorktreePreparations(
18286
+ folder,
18287
+ input.preparations,
18288
+ timeoutMs,
18289
+ signal
18290
+ );
18291
+ if (preparationResults.some((item) => item.state === "ERROR")) {
18292
+ return {
18293
+ ...successfulProcess8,
18294
+ exitCode: 1,
18295
+ checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
18296
+ preparations: preparationResults
18297
+ };
18298
+ }
18299
+ }
18300
+ const rebase = await git4(folder, ["rebase", remoteBase], timeoutMs, signal);
16995
18301
  if (rebase.exitCode !== 0) {
16996
- const conflictStatus = await git3(
18302
+ const conflictStatus = await git4(
16997
18303
  folder,
16998
18304
  ["status", "--porcelain=v1", "-z"],
16999
18305
  timeoutMs,
@@ -17004,6 +18310,8 @@ var autoSyncWorktree = async (payload, timeoutMs, signal) => {
17004
18310
  return {
17005
18311
  ...successfulProcess8,
17006
18312
  outcome: "CONFLICT",
18313
+ checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
18314
+ preparations: suspendedPreparations(),
17007
18315
  worktree: await inspectWorktreeItem(
17008
18316
  folder,
17009
18317
  folder,
@@ -17014,13 +18322,26 @@ var autoSyncWorktree = async (payload, timeoutMs, signal) => {
17014
18322
  )
17015
18323
  };
17016
18324
  }
17017
- await git3(folder, ["rebase", "--abort"], timeoutMs, signal);
17018
- throw new Error(cleanError3(rebase.stderr || "Auto Sync rebase failed"));
18325
+ await git4(folder, ["rebase", "--abort"], timeoutMs, signal);
18326
+ if (input.forcePreparations) await reapplyPreparations();
18327
+ throw new Error(cleanError4(rebase.stderr || "Auto Sync rebase failed"));
18328
+ }
18329
+ const push = await git4(
18330
+ folder,
18331
+ ["push", "--force-with-lease"],
18332
+ timeoutMs,
18333
+ signal
18334
+ );
18335
+ if (push.exitCode !== 0) {
18336
+ if (input.forcePreparations) await reapplyPreparations();
18337
+ requireSuccess4(push, "Auto Sync push failed");
17019
18338
  }
17020
- await runGit(["push", "--force-with-lease"], "Auto Sync push failed");
18339
+ preparationResults = input.forcePreparations ? await reapplyPreparations() : await inspectPreparations();
17021
18340
  return {
17022
18341
  ...successfulProcess8,
17023
18342
  outcome: "SYNCED",
18343
+ checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
18344
+ preparations: preparationResults,
17024
18345
  worktree: await inspectWorktreeItem(
17025
18346
  folder,
17026
18347
  folder,
@@ -17034,6 +18355,7 @@ var autoSyncWorktree = async (payload, timeoutMs, signal) => {
17034
18355
 
17035
18356
  // src/handlers/index.ts
17036
18357
  var handlers = {
18358
+ [CLI_HEALTH_JOB_KIND]: runCliHealth,
17037
18359
  [COMMAND_RUN_JOB_KIND]: runCommand,
17038
18360
  [CCUSAGE_REPORT_JOB_KIND]: runCcusage,
17039
18361
  [BUILD_DATA_SCAN_JOB_KIND]: scanBuildData,
@@ -17053,6 +18375,7 @@ var handlers = {
17053
18375
  [WORKTREE_MOVE_CHECKOUT_JOB_KIND]: checkoutMovedWorktree,
17054
18376
  [WORKTREE_DELETE_JOB_KIND]: deleteWorktree,
17055
18377
  [WORKTREE_OPERATION_JOB_KIND]: operateWorktree,
18378
+ [WORKTREE_PREPARATION_JOB_KIND]: prepareWorktree,
17056
18379
  [WORKTREE_GIT_INSPECT_JOB_KIND]: inspectWorktreeGit,
17057
18380
  [WORKTREE_GIT_OPERATION_JOB_KIND]: operateWorktreeGit,
17058
18381
  [WORKTREE_WATCH_JOB_KIND]: watchWorktree,
@@ -17091,8 +18414,8 @@ var RepositoryCoordinator = class {
17091
18414
  async run(key, task) {
17092
18415
  const previous = this.tails.get(key) ?? Promise.resolve();
17093
18416
  let release2;
17094
- const current = new Promise((resolve8) => {
17095
- release2 = resolve8;
18417
+ const current = new Promise((resolve9) => {
18418
+ release2 = resolve9;
17096
18419
  });
17097
18420
  const tail = previous.then(() => current);
17098
18421
  this.tails.set(key, tail);
@@ -17196,7 +18519,7 @@ var JobExecutor = class {
17196
18519
  );
17197
18520
  if (this.stopping) return;
17198
18521
  const delay = Math.min(3e4, 1e3 * 2 ** Math.min(retry++, 5));
17199
- await new Promise((resolve8) => setTimeout(resolve8, delay));
18522
+ await new Promise((resolve9) => setTimeout(resolve9, delay));
17200
18523
  }
17201
18524
  }
17202
18525
  }
@@ -17204,7 +18527,7 @@ var JobExecutor = class {
17204
18527
 
17205
18528
  // src/codebase-monitor.ts
17206
18529
  var INSPECTION_TIMEOUT_MS = 3e4;
17207
- var CONCURRENCY = 4;
18530
+ var CONCURRENCY2 = 4;
17208
18531
  var CodebaseMonitor = class {
17209
18532
  constructor(client2, repositoryCoordinator = new RepositoryCoordinator()) {
17210
18533
  this.client = client2;
@@ -17228,8 +18551,8 @@ var CodebaseMonitor = class {
17228
18551
  const codebases = configuration.codebases;
17229
18552
  const reports = [];
17230
18553
  const worktreeReports = [];
17231
- for (let index = 0; index < codebases.length; index += CONCURRENCY) {
17232
- const batch = codebases.slice(index, index + CONCURRENCY);
18554
+ for (let index = 0; index < codebases.length; index += CONCURRENCY2) {
18555
+ const batch = codebases.slice(index, index + CONCURRENCY2);
17233
18556
  const results = await Promise.all(
17234
18557
  batch.map(
17235
18558
  (codebase) => this.repositoryCoordinator.run(codebase.id, async () => {
@@ -17343,21 +18666,21 @@ var CodebaseMonitor = class {
17343
18666
 
17344
18667
  // src/runs/run-manager.ts
17345
18668
  import { execFile as execFile4 } from "node:child_process";
17346
- import { mkdir as mkdir6, rm as rm13 } from "node:fs/promises";
17347
- import { dirname as dirname10, join as join17 } from "node:path";
18669
+ import { mkdir as mkdir7, rm as rm14 } from "node:fs/promises";
18670
+ import { dirname as dirname11, join as join18 } from "node:path";
17348
18671
  import { promisify as promisify4 } from "node:util";
17349
18672
 
17350
18673
  // src/runs/journal.ts
17351
18674
  import { randomUUID as randomUUID4 } from "node:crypto";
17352
18675
  import {
17353
18676
  appendFile,
17354
- mkdir as mkdir5,
17355
- readFile as readFile9,
18677
+ mkdir as mkdir6,
18678
+ readFile as readFile10,
17356
18679
  rename as rename4,
17357
- rm as rm10,
17358
- writeFile as writeFile7
18680
+ rm as rm11,
18681
+ writeFile as writeFile8
17359
18682
  } from "node:fs/promises";
17360
- import { dirname as dirname8, join as join14 } from "node:path";
18683
+ import { dirname as dirname9, join as join15 } from "node:path";
17361
18684
  var RunJournal = class {
17362
18685
  constructor(runId, attemptId) {
17363
18686
  this.runId = runId;
@@ -17376,13 +18699,13 @@ var RunJournal = class {
17376
18699
  this.attemptId = attemptId;
17377
18700
  }
17378
18701
  get directory() {
17379
- return join14(dirname8(configPath()), "runs", this.runId);
18702
+ return join15(dirname9(configPath()), "runs", this.runId);
17380
18703
  }
17381
18704
  get eventsPath() {
17382
- return join14(this.directory, "events.jsonl");
18705
+ return join15(this.directory, "events.jsonl");
17383
18706
  }
17384
18707
  get statePath() {
17385
- return join14(this.directory, "state.json");
18708
+ return join15(this.directory, "state.json");
17386
18709
  }
17387
18710
  async load() {
17388
18711
  if (this.loaded) return;
@@ -17394,9 +18717,9 @@ var RunJournal = class {
17394
18717
  await this.loading;
17395
18718
  }
17396
18719
  async loadState() {
17397
- await mkdir5(this.directory, { recursive: true, mode: 448 });
18720
+ await mkdir6(this.directory, { recursive: true, mode: 448 });
17398
18721
  try {
17399
- const state = JSON.parse(await readFile9(this.statePath, "utf8"));
18722
+ const state = JSON.parse(await readFile10(this.statePath, "utf8"));
17400
18723
  this.acknowledged = state.acknowledged ?? -1;
17401
18724
  this.nextSequence = state.nextSequence ?? 0;
17402
18725
  } catch {
@@ -17471,7 +18794,7 @@ var RunJournal = class {
17471
18794
  }
17472
18795
  async readEvents() {
17473
18796
  try {
17474
- return (await readFile9(this.eventsPath, "utf8")).split("\n").filter(Boolean).map((line) => JSON.parse(line));
18797
+ return (await readFile10(this.eventsPath, "utf8")).split("\n").filter(Boolean).map((line) => JSON.parse(line));
17475
18798
  } catch (error) {
17476
18799
  if (error.code === "ENOENT") return [];
17477
18800
  throw error;
@@ -17483,10 +18806,10 @@ var RunJournal = class {
17483
18806
  const operation = this.saving.then(async () => {
17484
18807
  const temporary = `${this.statePath}.${process.pid}.${randomUUID4()}.tmp`;
17485
18808
  try {
17486
- await writeFile7(temporary, contents, { mode: 384 });
18809
+ await writeFile8(temporary, contents, { mode: 384 });
17487
18810
  await rename4(temporary, this.statePath);
17488
18811
  } catch (error) {
17489
- await rm10(temporary, { force: true }).catch(() => void 0);
18812
+ await rm11(temporary, { force: true }).catch(() => void 0);
17490
18813
  throw error;
17491
18814
  }
17492
18815
  });
@@ -26660,7 +27983,7 @@ function Yy(e) {
26660
27983
  var l = {};
26661
27984
  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 });
26662
27985
  var Qr = {};
26663
- 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 });
27986
+ 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: () => rm12, $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 });
26664
27987
  var Kd = Object.freeze({ status: "aborted" });
26665
27988
  function S(e, t, r) {
26666
27989
  function n(a, c) {
@@ -28208,7 +29531,7 @@ var tm = S("$ZodReadonly", (e, t) => {
28208
29531
  function DC(e) {
28209
29532
  return e.value = Object.freeze(e.value), e;
28210
29533
  }
28211
- var rm11 = S("$ZodTemplateLiteral", (e, t) => {
29534
+ var rm12 = S("$ZodTemplateLiteral", (e, t) => {
28212
29535
  ie.init(e, t);
28213
29536
  let r = [];
28214
29537
  for (let n of t.parts) if (n instanceof ie) {
@@ -32015,7 +33338,7 @@ function hR(e) {
32015
33338
  return new gR({ type: "readonly", innerType: e });
32016
33339
  }
32017
33340
  var _R = S("ZodTemplateLiteral", (e, t) => {
32018
- rm11.init(e, t), de.init(e, t);
33341
+ rm12.init(e, t), de.init(e, t);
32019
33342
  });
32020
33343
  function q9(e, t) {
32021
33344
  return new _R({ type: "template_literal", parts: e, ...M.normalizeParams(t) });
@@ -43342,7 +44665,7 @@ var MessageQueue = class {
43342
44665
  if (value) return Promise.resolve({ value, done: false });
43343
44666
  if (this.closed)
43344
44667
  return Promise.resolve({ value: void 0, done: true });
43345
- return new Promise((resolve8) => this.waiters.push(resolve8));
44668
+ return new Promise((resolve9) => this.waiters.push(resolve9));
43346
44669
  }
43347
44670
  };
43348
44671
  }
@@ -43512,8 +44835,8 @@ var ClaudeAdapter = class {
43512
44835
  const requestId = options.toolUseID || randomUUID5();
43513
44836
  const questions = questionsFromInput(toolInput);
43514
44837
  await callbacks.onQuestion(requestId, questions);
43515
- const answers = await new Promise((resolve8) => {
43516
- pendingQuestions.set(requestId, { input: toolInput, resolve: resolve8 });
44838
+ const answers = await new Promise((resolve9) => {
44839
+ pendingQuestions.set(requestId, { input: toolInput, resolve: resolve9 });
43517
44840
  });
43518
44841
  return {
43519
44842
  behavior: "allow",
@@ -43656,9 +44979,9 @@ import {
43656
44979
  execFile as execFile3,
43657
44980
  spawn as spawn8
43658
44981
  } from "node:child_process";
43659
- import { mkdtemp as mkdtemp7, rm as rm12, writeFile as writeFile8 } from "node:fs/promises";
44982
+ import { mkdtemp as mkdtemp7, rm as rm13, writeFile as writeFile9 } from "node:fs/promises";
43660
44983
  import { tmpdir as tmpdir7 } from "node:os";
43661
- import { join as join16 } from "node:path";
44984
+ import { join as join17 } from "node:path";
43662
44985
  import { createInterface } from "node:readline";
43663
44986
  import { promisify as promisify3 } from "node:util";
43664
44987
  var SUPPORTED_CODEX_APP_SERVER_MINORS = ["0.144", "0.145"];
@@ -43769,8 +45092,8 @@ var CodexAppServer = class {
43769
45092
  });
43770
45093
  const lines = createInterface({ input: child.stdout });
43771
45094
  lines.on("line", (line) => this.receive(line));
43772
- await new Promise((resolve8, reject) => {
43773
- child.once("spawn", resolve8);
45095
+ await new Promise((resolve9, reject) => {
45096
+ child.once("spawn", resolve9);
43774
45097
  child.once("error", reject);
43775
45098
  });
43776
45099
  const initialized = asRecord(
@@ -43812,7 +45135,7 @@ var CodexAppServer = class {
43812
45135
  }
43813
45136
  }
43814
45137
  async createBundledModelCatalog(executable) {
43815
- const directory = await mkdtemp7(join16(tmpdir7(), "aide-codex-models-"));
45138
+ const directory = await mkdtemp7(join17(tmpdir7(), "aide-codex-models-"));
43816
45139
  try {
43817
45140
  const { stdout } = await execFileAsync2(
43818
45141
  executable,
@@ -43822,12 +45145,12 @@ var CodexAppServer = class {
43822
45145
  maxBuffer: 16 * 1024 * 1024
43823
45146
  }
43824
45147
  );
43825
- const catalogPath = join16(directory, "models.json");
43826
- await writeFile8(catalogPath, stdout, "utf8");
45148
+ const catalogPath = join17(directory, "models.json");
45149
+ await writeFile9(catalogPath, stdout, "utf8");
43827
45150
  this.modelCatalogDirectory = directory;
43828
45151
  return catalogPath;
43829
45152
  } catch (error) {
43830
- await rm12(directory, { recursive: true, force: true }).catch(
45153
+ await rm13(directory, { recursive: true, force: true }).catch(
43831
45154
  () => void 0
43832
45155
  );
43833
45156
  throw error;
@@ -43838,7 +45161,7 @@ var CodexAppServer = class {
43838
45161
  if (this.modelCatalogDirectory === directory) {
43839
45162
  this.modelCatalogDirectory = void 0;
43840
45163
  }
43841
- await rm12(directory, { recursive: true, force: true }).catch(
45164
+ await rm13(directory, { recursive: true, force: true }).catch(
43842
45165
  () => void 0
43843
45166
  );
43844
45167
  }
@@ -43878,8 +45201,8 @@ var CodexAppServer = class {
43878
45201
  }
43879
45202
  requestDirect(method, params) {
43880
45203
  const id2 = this.nextId++;
43881
- return new Promise((resolve8, reject) => {
43882
- this.pending.set(id2, { resolve: resolve8, reject });
45204
+ return new Promise((resolve9, reject) => {
45205
+ this.pending.set(id2, { resolve: resolve9, reject });
43883
45206
  this.write({ id: id2, method, params });
43884
45207
  });
43885
45208
  }
@@ -44042,8 +45365,8 @@ var CodexAdapter = class {
44042
45365
  let lastUsageSignature = "";
44043
45366
  const pendingQuestions = /* @__PURE__ */ new Map();
44044
45367
  let resolveCompletion;
44045
- const completion = new Promise((resolve8) => {
44046
- resolveCompletion = resolve8;
45368
+ const completion = new Promise((resolve9) => {
45369
+ resolveCompletion = resolve9;
44047
45370
  });
44048
45371
  const unsubscribe = this.server.listen(nativeId, (message) => {
44049
45372
  void (async () => {
@@ -44253,13 +45576,13 @@ var CodexAdapter = class {
44253
45576
  };
44254
45577
 
44255
45578
  // src/runs/opencode-adapter.ts
44256
- import { dirname as dirname9 } from "node:path";
45579
+ import { dirname as dirname10 } from "node:path";
44257
45580
  import { pathToFileURL } from "node:url";
44258
45581
 
44259
45582
  // ../../node_modules/@opencode-ai/sdk/dist/v2/gen/core/serverSentEvents.gen.js
44260
45583
  var createSseClient = ({ onRequest, onSseError, onSseEvent, responseTransformer, responseValidator, sseDefaultRetryDelay, sseMaxRetryAttempts, sseMaxRetryDelay, sseSleepFn, url, ...options }) => {
44261
45584
  let lastEventId;
44262
- const sleep = sseSleepFn ?? ((ms) => new Promise((resolve8) => setTimeout(resolve8, ms)));
45585
+ const sleep = sseSleepFn ?? ((ms) => new Promise((resolve9) => setTimeout(resolve9, ms)));
44263
45586
  const createStream = async function* () {
44264
45587
  let retryDelay = sseDefaultRetryDelay ?? 3e3;
44265
45588
  let attempt = 0;
@@ -49711,7 +51034,7 @@ async function createOpencodeServer(options) {
49711
51034
  });
49712
51035
  let clear = () => {
49713
51036
  };
49714
- const url = await new Promise((resolve8, reject) => {
51037
+ const url = await new Promise((resolve9, reject) => {
49715
51038
  const id2 = setTimeout(() => {
49716
51039
  clear();
49717
51040
  stop(proc);
@@ -49736,7 +51059,7 @@ async function createOpencodeServer(options) {
49736
51059
  }
49737
51060
  clearTimeout(id2);
49738
51061
  resolved = true;
49739
- resolve8(match[1]);
51062
+ resolve9(match[1]);
49740
51063
  return;
49741
51064
  }
49742
51065
  }
@@ -49901,11 +51224,11 @@ function responseItems(value) {
49901
51224
  }
49902
51225
  function waitForPoll(signal) {
49903
51226
  if (signal.aborted) return Promise.resolve();
49904
- return new Promise((resolve8) => {
51227
+ return new Promise((resolve9) => {
49905
51228
  const finish = () => {
49906
51229
  clearTimeout(timer);
49907
51230
  signal.removeEventListener("abort", finish);
49908
- resolve8();
51231
+ resolve9();
49909
51232
  };
49910
51233
  const timer = setTimeout(finish, QUESTION_RECONCILIATION_INTERVAL_MS);
49911
51234
  timer.unref();
@@ -49934,7 +51257,7 @@ var OpenCodeAdapter = class {
49934
51257
  "opencode was not found. Install it (brew install sst/tap/opencode, or npm install -g opencode-ai) or set CONTROL_AGENT_OPENCODE_EXECUTABLE to its full path."
49935
51258
  );
49936
51259
  }
49937
- prependPathDirectory(dirname9(executable));
51260
+ prependPathDirectory(dirname10(executable));
49938
51261
  this.runtime = await createOpencode({ port: 0 });
49939
51262
  }
49940
51263
  return this.runtime.client;
@@ -50558,7 +51881,7 @@ var RunManager = class {
50558
51881
  5
50559
51882
  );
50560
51883
  await this.completeCommand(command3.id, "SUCCEEDED");
50561
- await rm13(join17(dirname10(configPath()), "runs", run.id, "attachments"), {
51884
+ await rm14(join18(dirname11(configPath()), "runs", run.id, "attachments"), {
50562
51885
  recursive: true,
50563
51886
  force: true
50564
51887
  }).catch(() => void 0);
@@ -50740,7 +52063,7 @@ var RunManager = class {
50740
52063
  this.active.delete(run.id);
50741
52064
  this.interruptionRequests.delete(run.id);
50742
52065
  this.executingCommands.delete(command3.id);
50743
- await rm13(join17(dirname10(configPath()), "runs", run.id, "attachments"), {
52066
+ await rm14(join18(dirname11(configPath()), "runs", run.id, "attachments"), {
50744
52067
  recursive: true,
50745
52068
  force: true
50746
52069
  }).catch(() => void 0);
@@ -50968,11 +52291,11 @@ var RunManager = class {
50968
52291
  }
50969
52292
  async stageAttachments(runId, attachments) {
50970
52293
  if (!attachments.length) return [];
50971
- const directory = join17(dirname10(configPath()), "runs", runId, "attachments");
50972
- await mkdir6(directory, { recursive: true, mode: 448 });
52294
+ const directory = join18(dirname11(configPath()), "runs", runId, "attachments");
52295
+ await mkdir7(directory, { recursive: true, mode: 448 });
50973
52296
  return Promise.all(
50974
52297
  attachments.map(async (attachment) => {
50975
- const path = join17(
52298
+ const path = join18(
50976
52299
  directory,
50977
52300
  `${attachment.id}-${safeFilename(attachment.filename)}`
50978
52301
  );
@@ -51064,7 +52387,7 @@ var RunManager = class {
51064
52387
  return await operation();
51065
52388
  } catch (error) {
51066
52389
  if (this.stopped || attempt >= attempts) throw error;
51067
- await new Promise((resolve8) => setTimeout(resolve8, delay));
52390
+ await new Promise((resolve9) => setTimeout(resolve9, delay));
51068
52391
  delay = Math.min(delay * 2, 3e4);
51069
52392
  }
51070
52393
  }
@@ -51344,9 +52667,9 @@ async function runAgentSession(config, signal, onUnhealthy) {
51344
52667
  }
51345
52668
  }
51346
52669
  );
51347
- await new Promise((resolve8) => {
51348
- if (signal.aborted) resolve8();
51349
- else signal.addEventListener("abort", () => resolve8(), { once: true });
52670
+ await new Promise((resolve9) => {
52671
+ if (signal.aborted) resolve9();
52672
+ else signal.addEventListener("abort", () => resolve9(), { once: true });
51350
52673
  });
51351
52674
  if (heartbeatTimer) clearTimeout(heartbeatTimer);
51352
52675
  if (jobReconciliationTimer) clearTimeout(jobReconciliationTimer);
@@ -51413,7 +52736,7 @@ var defaultDependencies = {
51413
52736
  inventory: collectInventory,
51414
52737
  load: loadConfig,
51415
52738
  save: saveConfig,
51416
- wait: (milliseconds, signal) => new Promise((resolve8, reject) => {
52739
+ wait: (milliseconds, signal) => new Promise((resolve9, reject) => {
51417
52740
  if (signal.aborted) {
51418
52741
  reject(new Error("Development agent startup was cancelled"));
51419
52742
  return;
@@ -51424,7 +52747,7 @@ var defaultDependencies = {
51424
52747
  };
51425
52748
  const timer = setTimeout(() => {
51426
52749
  signal.removeEventListener("abort", onAbort);
51427
- resolve8();
52750
+ resolve9();
51428
52751
  }, milliseconds);
51429
52752
  signal.addEventListener("abort", onAbort, { once: true });
51430
52753
  })
@@ -51668,7 +52991,7 @@ async function unenroll() {
51668
52991
  config = await loadConfig(path);
51669
52992
  } catch {
51670
52993
  }
51671
- await rm14(path, { force: true });
52994
+ await rm15(path, { force: true });
51672
52995
  console.log(
51673
52996
  config ? `Removed the enrollment for ${config.name} (${config.agentId}) from ${path}` : `Removed ${path}`
51674
52997
  );