@ai-development-environment/control-agent 0.0.89 → 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 +1383 -297
  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`);
6232
+ }
6233
+ return path;
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`);
6219
6239
  }
6220
6240
  return path;
6221
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,8 +6736,103 @@ 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
+ )
6745
+ };
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
+ )
6638
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 };
6639
6836
  }
6640
6837
  function worktreeGitInspectPayload(value) {
6641
6838
  const payload = objectValue4(value, "worktree Git inspect payload");
@@ -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
  );
@@ -8449,7 +8646,7 @@ function captureCommand(options) {
8449
8646
  outputTruncated: false
8450
8647
  });
8451
8648
  }
8452
- return new Promise((resolve8, reject) => {
8649
+ return new Promise((resolve9, reject) => {
8453
8650
  const stdoutChunks = [];
8454
8651
  const stderrChunks = [];
8455
8652
  let stdoutBytes = 0;
@@ -8545,7 +8742,7 @@ function captureCommand(options) {
8545
8742
  clearTimeout(timeout);
8546
8743
  if (killTimer) clearTimeout(killTimer);
8547
8744
  options.signal.removeEventListener("abort", abort);
8548
- resolve8({
8745
+ resolve9({
8549
8746
  exitCode,
8550
8747
  signal,
8551
8748
  timedOut,
@@ -8633,11 +8830,11 @@ async function reapOrphanedCommandProcesses(agentId, signal = new AbortControlle
8633
8830
  console.error(
8634
8831
  `Terminating ${signalled.length} command process(es) left by a previous agent run.`
8635
8832
  );
8636
- await new Promise((resolve8) => {
8637
- const timer = setTimeout(resolve8, TERMINATE_GRACE_MS);
8833
+ await new Promise((resolve9) => {
8834
+ const timer = setTimeout(resolve9, TERMINATE_GRACE_MS);
8638
8835
  timer.unref();
8639
- if (signal.aborted) resolve8();
8640
- else signal.addEventListener("abort", () => resolve8(), { once: true });
8836
+ if (signal.aborted) resolve9();
8837
+ else signal.addEventListener("abort", () => resolve9(), { once: true });
8641
8838
  });
8642
8839
  for (const orphan of signalled) signalGroup(orphan.processGroup, "SIGKILL");
8643
8840
  return signalled;
@@ -8693,14 +8890,14 @@ var runCommand = async (rawPayload, _timeoutMs, signal, _onLog, context) => {
8693
8890
  `Could not append command output; retrying in ${delay}ms:`,
8694
8891
  error instanceof Error ? error.message : error
8695
8892
  );
8696
- await new Promise((resolve8) => {
8893
+ await new Promise((resolve9) => {
8697
8894
  const onAbort = () => {
8698
8895
  clearTimeout(retryTimer);
8699
- resolve8();
8896
+ resolve9();
8700
8897
  };
8701
8898
  const retryTimer = setTimeout(() => {
8702
8899
  signal.removeEventListener("abort", onAbort);
8703
- resolve8();
8900
+ resolve9();
8704
8901
  }, delay);
8705
8902
  retryTimer.unref();
8706
8903
  signal.addEventListener("abort", onAbort, { once: true });
@@ -8738,7 +8935,7 @@ var runCommand = async (rawPayload, _timeoutMs, signal, _onLog, context) => {
8738
8935
  }
8739
8936
  };
8740
8937
  try {
8741
- return await new Promise((resolve8, reject) => {
8938
+ return await new Promise((resolve9, reject) => {
8742
8939
  let cancelled = false;
8743
8940
  let settled = false;
8744
8941
  const child = spawn2(process.env.SHELL || "/bin/sh", ["-l", scriptPath], {
@@ -8805,7 +9002,7 @@ var runCommand = async (rawPayload, _timeoutMs, signal, _onLog, context) => {
8805
9002
  signal.removeEventListener("abort", abort);
8806
9003
  flush();
8807
9004
  void uploadChain.then(
8808
- () => resolve8({
9005
+ () => resolve9({
8809
9006
  exitCode,
8810
9007
  signal: closeSignal,
8811
9008
  timedOut: false,
@@ -12624,7 +12821,7 @@ function prependPathDirectory(directory, env = process.env) {
12624
12821
  // src/process-runner.ts
12625
12822
  import { spawn as spawn5 } from "node:child_process";
12626
12823
  async function runProcess(options) {
12627
- return new Promise((resolve8, reject) => {
12824
+ return new Promise((resolve9, reject) => {
12628
12825
  let sequence = 0;
12629
12826
  let timedOut = false;
12630
12827
  let cancelled = false;
@@ -12719,7 +12916,7 @@ async function runProcess(options) {
12719
12916
  clearTimeout(timeout);
12720
12917
  options.signal.removeEventListener("abort", abort);
12721
12918
  void logChain.then(
12722
- () => resolve8({ exitCode, signal, timedOut, cancelled })
12919
+ () => resolve9({ exitCode, signal, timedOut, cancelled })
12723
12920
  );
12724
12921
  });
12725
12922
  });
@@ -14588,7 +14785,7 @@ async function optionalGit(cwd, args) {
14588
14785
  }
14589
14786
  function cappedGit(cwd, args, limit) {
14590
14787
  const budget = limit - TRUNCATION_RESERVE;
14591
- return new Promise((resolve8, reject) => {
14788
+ return new Promise((resolve9, reject) => {
14592
14789
  const child = spawn6("git", args, {
14593
14790
  cwd,
14594
14791
  env: {
@@ -14638,7 +14835,7 @@ function cappedGit(cwd, args, limit) {
14638
14835
  return;
14639
14836
  }
14640
14837
  const output = Buffer.concat(chunks).toString("utf8");
14641
- resolve8(
14838
+ resolve9(
14642
14839
  truncated ? `${output.trimEnd()}
14643
14840
 
14644
14841
  [Truncated after ${budget} bytes]` : output.trim()
@@ -14948,10 +15145,494 @@ var runWorkflowGitCheckpoint = async (payloadValue, _timeoutMs, signal) => {
14948
15145
 
14949
15146
  // src/handlers/worktrees.ts
14950
15147
  import { createWriteStream as createWriteStream2, watch } from "node:fs";
14951
- 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";
14952
15149
  import { tmpdir as tmpdir6 } from "node:os";
14953
- 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";
14954
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
14955
15636
  var successfulProcess8 = {
14956
15637
  exitCode: 0,
14957
15638
  signal: null,
@@ -14995,7 +15676,7 @@ function statusChangeState(value) {
14995
15676
  }
14996
15677
  async function rebaseInProgress(folder, timeoutMs, signal) {
14997
15678
  for (const name of ["rebase-merge", "rebase-apply"]) {
14998
- const pathResult = await git3(
15679
+ const pathResult = await git4(
14999
15680
  folder,
15000
15681
  ["rev-parse", "--git-path", name],
15001
15682
  timeoutMs,
@@ -15005,7 +15686,7 @@ async function rebaseInProgress(folder, timeoutMs, signal) {
15005
15686
  const candidate = pathResult.stdout.trim();
15006
15687
  if (!candidate) continue;
15007
15688
  try {
15008
- await stat10(isAbsolute6(candidate) ? candidate : join13(folder, candidate));
15689
+ await stat10(isAbsolute7(candidate) ? candidate : join14(folder, candidate));
15009
15690
  return true;
15010
15691
  } catch {
15011
15692
  }
@@ -15014,7 +15695,7 @@ async function rebaseInProgress(folder, timeoutMs, signal) {
15014
15695
  }
15015
15696
  async function rebaseBranch(folder, timeoutMs, signal) {
15016
15697
  for (const name of ["rebase-merge/head-name", "rebase-apply/head-name"]) {
15017
- const pathResult = await git3(
15698
+ const pathResult = await git4(
15018
15699
  folder,
15019
15700
  ["rev-parse", "--git-path", name],
15020
15701
  timeoutMs,
@@ -15024,8 +15705,8 @@ async function rebaseBranch(folder, timeoutMs, signal) {
15024
15705
  const candidate = pathResult.stdout.trim();
15025
15706
  if (!candidate) continue;
15026
15707
  try {
15027
- const headName = (await readFile8(
15028
- isAbsolute6(candidate) ? candidate : join13(folder, candidate),
15708
+ const headName = (await readFile9(
15709
+ isAbsolute7(candidate) ? candidate : join14(folder, candidate),
15029
15710
  "utf8"
15030
15711
  )).trim();
15031
15712
  if (headName.startsWith("refs/heads/")) {
@@ -15059,7 +15740,7 @@ async function flushWorktreeActivity(entry) {
15059
15740
  try {
15060
15741
  const signal = new AbortController().signal;
15061
15742
  const [status2, branchResult, headResult, codeStateHash, rebasing] = await Promise.all([
15062
- git3(
15743
+ git4(
15063
15744
  entry.folder,
15064
15745
  [
15065
15746
  "--no-optional-locks",
@@ -15071,13 +15752,13 @@ async function flushWorktreeActivity(entry) {
15071
15752
  entry.timeoutMs,
15072
15753
  signal
15073
15754
  ),
15074
- git3(
15755
+ git4(
15075
15756
  entry.folder,
15076
15757
  ["symbolic-ref", "--short", "-q", "HEAD"],
15077
15758
  entry.timeoutMs,
15078
15759
  signal
15079
15760
  ),
15080
- git3(entry.folder, ["rev-parse", "HEAD"], entry.timeoutMs, signal),
15761
+ git4(entry.folder, ["rev-parse", "HEAD"], entry.timeoutMs, signal),
15081
15762
  worktreeCodeStateHash(entry.folder, entry.timeoutMs, signal),
15082
15763
  rebaseInProgress(entry.folder, entry.timeoutMs, signal)
15083
15764
  ]);
@@ -15106,7 +15787,7 @@ async function flushWorktreeActivity(entry) {
15106
15787
  observedAt: (/* @__PURE__ */ new Date()).toISOString()
15107
15788
  };
15108
15789
  if (headIdentity && headIdentity !== entry.headIdentity) {
15109
- const upstreamResult = branch ? await git3(
15790
+ const upstreamResult = branch ? await git4(
15110
15791
  entry.folder,
15111
15792
  [
15112
15793
  "rev-parse",
@@ -15164,24 +15845,24 @@ function scheduleWorktreeActivity(entry) {
15164
15845
  }, WATCH_DEBOUNCE_MS);
15165
15846
  entry.timer.unref();
15166
15847
  }
15167
- function cleanError3(value) {
15848
+ function cleanError4(value) {
15168
15849
  return (value instanceof Error ? value.message : String(value)).replace(/([a-z][a-z0-9+.-]*:\/\/)[^\s/@]+@/gi, "$1").slice(0, 2e3);
15169
15850
  }
15170
15851
  async function command2(executable, args, timeoutMs, signal, env = process.env) {
15171
15852
  return captureCommand({ command: executable, args, timeoutMs, signal, env });
15172
15853
  }
15173
- async function git3(folder, args, timeoutMs, signal) {
15854
+ async function git4(folder, args, timeoutMs, signal) {
15174
15855
  return command2("git", ["-C", folder, ...args], timeoutMs, signal, {
15175
15856
  ...process.env,
15176
15857
  GIT_TERMINAL_PROMPT: "0",
15177
15858
  GIT_OPTIONAL_LOCKS: "0"
15178
15859
  });
15179
15860
  }
15180
- function requireSuccess3(result, fallback) {
15861
+ function requireSuccess4(result, fallback) {
15181
15862
  if (result.cancelled) throw new Error("Worktree operation was cancelled");
15182
15863
  if (result.timedOut) throw new Error("Worktree operation timed out");
15183
15864
  if (result.exitCode !== 0)
15184
- throw new Error(cleanError3(result.stderr || fallback));
15865
+ throw new Error(cleanError4(result.stderr || fallback));
15185
15866
  return result;
15186
15867
  }
15187
15868
  function parseWorktreeList(value) {
@@ -15199,8 +15880,8 @@ function parseWorktreeList(value) {
15199
15880
  }).filter((entry) => Boolean(entry.folder));
15200
15881
  }
15201
15882
  async function gitDirectory(folder, timeoutMs, signal) {
15202
- const result = requireSuccess3(
15203
- await git3(
15883
+ const result = requireSuccess4(
15884
+ await git4(
15204
15885
  folder,
15205
15886
  ["rev-parse", "--path-format=absolute", "--git-dir"],
15206
15887
  timeoutMs,
@@ -15208,17 +15889,17 @@ async function gitDirectory(folder, timeoutMs, signal) {
15208
15889
  ),
15209
15890
  "Could not resolve the worktree Git directory"
15210
15891
  );
15211
- return realpath8(result.stdout.trim());
15892
+ return realpath9(result.stdout.trim());
15212
15893
  }
15213
15894
  async function origin(folder, timeoutMs, signal) {
15214
- const result = requireSuccess3(
15215
- await git3(folder, ["remote", "get-url", "origin"], timeoutMs, signal),
15895
+ const result = requireSuccess4(
15896
+ await git4(folder, ["remote", "get-url", "origin"], timeoutMs, signal),
15216
15897
  "Repository does not have an origin remote"
15217
15898
  );
15218
15899
  return normalizeGitOrigin(result.stdout.trim()).canonicalOrigin;
15219
15900
  }
15220
15901
  async function validateWorktree2(input, timeoutMs, signal) {
15221
- const folder = await realpath8(input.folder);
15902
+ const folder = await realpath9(input.folder);
15222
15903
  if (!(await stat10(folder)).isDirectory())
15223
15904
  throw new Error("Worktree is missing");
15224
15905
  const observedGitDirectory = await gitDirectory(folder, timeoutMs, signal);
@@ -15231,7 +15912,7 @@ async function validateWorktree2(input, timeoutMs, signal) {
15231
15912
  return folder;
15232
15913
  }
15233
15914
  async function counts(folder, range, timeoutMs, signal) {
15234
- const result = await git3(
15915
+ const result = await git4(
15235
15916
  folder,
15236
15917
  ["rev-list", "--left-right", "--count", range],
15237
15918
  timeoutMs,
@@ -15265,17 +15946,17 @@ async function worktreePushStatus(folder, branch, changes, timeoutMs, signal) {
15265
15946
  async function inspectWorktreeItem(folderValue2, rootFolder, baseBranch, primary, timeoutMs, signal) {
15266
15947
  const checkedAt = (/* @__PURE__ */ new Date()).toISOString();
15267
15948
  try {
15268
- const folder = await realpath8(folderValue2);
15949
+ const folder = await realpath9(folderValue2);
15269
15950
  const [gitDir, branchResult, headResult, statusResult, rebasing] = await Promise.all([
15270
15951
  gitDirectory(folder, timeoutMs, signal),
15271
- git3(
15952
+ git4(
15272
15953
  folder,
15273
15954
  ["symbolic-ref", "--short", "-q", "HEAD"],
15274
15955
  timeoutMs,
15275
15956
  signal
15276
15957
  ),
15277
- git3(folder, ["rev-parse", "HEAD"], timeoutMs, signal),
15278
- git3(
15958
+ git4(folder, ["rev-parse", "HEAD"], timeoutMs, signal),
15959
+ git4(
15279
15960
  folder,
15280
15961
  [
15281
15962
  "--no-optional-locks",
@@ -15291,7 +15972,7 @@ async function inspectWorktreeItem(folderValue2, rootFolder, baseBranch, primary
15291
15972
  ]);
15292
15973
  const symbolicBranch = branchResult.exitCode === 0 ? branchResult.stdout.trim() : null;
15293
15974
  const branch = symbolicBranch ?? (rebasing ? await rebaseBranch(folder, timeoutMs, signal) : null);
15294
- const upstreamResult = branch ? await git3(
15975
+ const upstreamResult = branch ? await git4(
15295
15976
  folder,
15296
15977
  ["rev-parse", "--abbrev-ref", "--symbolic-full-name", "@{upstream}"],
15297
15978
  timeoutMs,
@@ -15314,7 +15995,7 @@ async function inspectWorktreeItem(folderValue2, rootFolder, baseBranch, primary
15314
15995
  return {
15315
15996
  gitDirectory: gitDir,
15316
15997
  folder,
15317
- relativePath: relative7(rootFolder, folder) || ".",
15998
+ relativePath: relative8(rootFolder, folder) || ".",
15318
15999
  primary,
15319
16000
  branch,
15320
16001
  headSha: headResult.exitCode === 0 ? headResult.stdout.trim() : null,
@@ -15342,7 +16023,7 @@ async function inspectWorktreeItem(folderValue2, rootFolder, baseBranch, primary
15342
16023
  return {
15343
16024
  gitDirectory: folderValue2,
15344
16025
  folder: folderValue2,
15345
- relativePath: relative7(rootFolder, folderValue2) || ".",
16026
+ relativePath: relative8(rootFolder, folderValue2) || ".",
15346
16027
  primary,
15347
16028
  branch: null,
15348
16029
  headSha: null,
@@ -15359,15 +16040,15 @@ async function inspectWorktreeItem(folderValue2, rootFolder, baseBranch, primary
15359
16040
  hasConflicts: false,
15360
16041
  pushStatus: "UNKNOWN",
15361
16042
  availability: "ERROR",
15362
- error: cleanError3(error),
16043
+ error: cleanError4(error),
15363
16044
  checkedAt
15364
16045
  };
15365
16046
  }
15366
16047
  }
15367
16048
  async function discoverWorktrees(rootFolderValue, baseOverrides, knownDefaultBranch, timeoutMs, signal) {
15368
- const rootFolder = await realpath8(rootFolderValue);
15369
- const list = requireSuccess3(
15370
- await git3(
16049
+ const rootFolder = await realpath9(rootFolderValue);
16050
+ const list = requireSuccess4(
16051
+ await git4(
15371
16052
  rootFolder,
15372
16053
  ["worktree", "list", "--porcelain"],
15373
16054
  timeoutMs,
@@ -15375,14 +16056,14 @@ async function discoverWorktrees(rootFolderValue, baseOverrides, knownDefaultBra
15375
16056
  ),
15376
16057
  "Could not list Git worktrees"
15377
16058
  );
15378
- const remoteHead = await git3(
16059
+ const remoteHead = await git4(
15379
16060
  rootFolder,
15380
16061
  ["ls-remote", "--symref", "origin", "HEAD"],
15381
16062
  timeoutMs,
15382
16063
  signal
15383
16064
  );
15384
16065
  let defaultBranch = remoteHead.stdout.match(/^ref:\s+refs\/heads\/([^\s]+)\s+HEAD/m)?.[1] ?? null;
15385
- const defaultResult = await git3(
16066
+ const defaultResult = await git4(
15386
16067
  rootFolder,
15387
16068
  ["symbolic-ref", "--short", "refs/remotes/origin/HEAD"],
15388
16069
  timeoutMs,
@@ -15393,13 +16074,13 @@ async function discoverWorktrees(rootFolderValue, baseOverrides, knownDefaultBra
15393
16074
  defaultBranch = localDefaultBranch || knownDefaultBranch;
15394
16075
  }
15395
16076
  const [localBranchesResult, remoteBranchesResult] = await Promise.all([
15396
- git3(
16077
+ git4(
15397
16078
  rootFolder,
15398
16079
  ["for-each-ref", "--format=%(refname:strip=2)", "refs/heads"],
15399
16080
  timeoutMs,
15400
16081
  signal
15401
16082
  ),
15402
- git3(
16083
+ git4(
15403
16084
  rootFolder,
15404
16085
  ["for-each-ref", "--format=%(refname:strip=3)", "refs/remotes/origin"],
15405
16086
  timeoutMs,
@@ -15462,7 +16143,7 @@ async function untrackedLines(folder, path) {
15462
16143
  try {
15463
16144
  const file = await stat10(`${folder}/${path}`);
15464
16145
  if (!file.isFile() || file.size > 1024 * 1024) return null;
15465
- const contents = await readFile8(`${folder}/${path}`);
16146
+ const contents = await readFile9(`${folder}/${path}`);
15466
16147
  if (contents.includes(0)) return null;
15467
16148
  const text2 = contents.toString("utf8");
15468
16149
  return text2 ? text2.split("\n").length - (text2.endsWith("\n") ? 1 : 0) : 0;
@@ -15472,16 +16153,16 @@ async function untrackedLines(folder, path) {
15472
16153
  }
15473
16154
  async function inspectChanges(folder, timeoutMs, signal) {
15474
16155
  const [statusResult, stagedResult, unstagedResult] = await Promise.all([
15475
- git3(
16156
+ git4(
15476
16157
  folder,
15477
16158
  ["status", "--porcelain=v1", "-z", "--untracked-files=all"],
15478
16159
  timeoutMs,
15479
16160
  signal
15480
16161
  ),
15481
- git3(folder, ["diff", "--cached", "--numstat", "-z"], timeoutMs, signal),
15482
- git3(folder, ["diff", "--numstat", "-z"], timeoutMs, signal)
16162
+ git4(folder, ["diff", "--cached", "--numstat", "-z"], timeoutMs, signal),
16163
+ git4(folder, ["diff", "--numstat", "-z"], timeoutMs, signal)
15483
16164
  ]);
15484
- requireSuccess3(statusResult, "Could not inspect worktree changes");
16165
+ requireSuccess4(statusResult, "Could not inspect worktree changes");
15485
16166
  const stagedCounts = parseNumstat(stagedResult.stdout);
15486
16167
  const unstagedCounts = parseNumstat(unstagedResult.stdout);
15487
16168
  const values = statusResult.stdout.split("\0").filter(Boolean);
@@ -15541,11 +16222,11 @@ function parseNameStatus(value) {
15541
16222
  }
15542
16223
  async function diffFiles(folder, range, timeoutMs, signal) {
15543
16224
  const [status2, counts2] = await Promise.all([
15544
- git3(folder, ["diff", "--name-status", "-z", range], timeoutMs, signal),
15545
- 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)
15546
16227
  ]);
15547
- requireSuccess3(status2, "Could not inspect changed files");
15548
- 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");
15549
16230
  const numstat = parseNumstat(counts2.stdout);
15550
16231
  return parseNameStatus(status2.stdout).map((file) => {
15551
16232
  const [additions, deletions] = numstat.get(file.path) ?? [null, null];
@@ -15559,8 +16240,8 @@ async function diffFiles(folder, range, timeoutMs, signal) {
15559
16240
  });
15560
16241
  }
15561
16242
  async function inspectBranchChanges(folder, baseBranch, timeoutMs, signal) {
15562
- const mergeBase = requireSuccess3(
15563
- await git3(
16243
+ const mergeBase = requireSuccess4(
16244
+ await git4(
15564
16245
  folder,
15565
16246
  ["merge-base", `refs/remotes/origin/${baseBranch}`, "HEAD"],
15566
16247
  timeoutMs,
@@ -15577,8 +16258,8 @@ async function inspectBranchChanges(folder, baseBranch, timeoutMs, signal) {
15577
16258
  return { changes: files.slice(0, 500), truncated: files.length > 500 };
15578
16259
  }
15579
16260
  async function inspectCommits(folder, baseBranch, timeoutMs, signal) {
15580
- const result = requireSuccess3(
15581
- await git3(
16261
+ const result = requireSuccess4(
16262
+ await git4(
15582
16263
  folder,
15583
16264
  [
15584
16265
  "log",
@@ -15611,7 +16292,7 @@ async function inspectWorktreeDetail(folder, baseBranch, timeoutMs, signal) {
15611
16292
  inspectCommits(folder, baseBranch, timeoutMs, signal),
15612
16293
  inspectChanges(folder, timeoutMs, signal),
15613
16294
  inspectBranchChanges(folder, baseBranch, timeoutMs, signal),
15614
- git3(
16295
+ git4(
15615
16296
  folder,
15616
16297
  ["config", "--bool", "--get", "commit.gpgsign"],
15617
16298
  timeoutMs,
@@ -15629,8 +16310,8 @@ async function inspectWorktreeDetail(folder, baseBranch, timeoutMs, signal) {
15629
16310
  };
15630
16311
  }
15631
16312
  async function baseMergeCommit(folder, baseBranch, timeoutMs, signal) {
15632
- return requireSuccess3(
15633
- await git3(
16313
+ return requireSuccess4(
16314
+ await git4(
15634
16315
  folder,
15635
16316
  ["merge-base", `refs/remotes/origin/${baseBranch}`, "HEAD"],
15636
16317
  timeoutMs,
@@ -15645,13 +16326,13 @@ async function validateDisplayedCommit(folder, baseBranch, commitSha, timeoutMs,
15645
16326
  }
15646
16327
  const base = await baseMergeCommit(folder, baseBranch, timeoutMs, signal);
15647
16328
  const [afterBase, beforeHead] = await Promise.all([
15648
- git3(
16329
+ git4(
15649
16330
  folder,
15650
16331
  ["merge-base", "--is-ancestor", base, commitSha],
15651
16332
  timeoutMs,
15652
16333
  signal
15653
16334
  ),
15654
- git3(
16335
+ git4(
15655
16336
  folder,
15656
16337
  ["merge-base", "--is-ancestor", commitSha, "HEAD"],
15657
16338
  timeoutMs,
@@ -15663,7 +16344,7 @@ async function validateDisplayedCommit(folder, baseBranch, commitSha, timeoutMs,
15663
16344
  }
15664
16345
  }
15665
16346
  async function parentCommit(folder, commitSha, timeoutMs, signal) {
15666
- const result = await git3(
16347
+ const result = await git4(
15667
16348
  folder,
15668
16349
  ["rev-parse", `${commitSha}^`],
15669
16350
  timeoutMs,
@@ -15672,13 +16353,13 @@ async function parentCommit(folder, commitSha, timeoutMs, signal) {
15672
16353
  return result.exitCode === 0 ? result.stdout.trim() : null;
15673
16354
  }
15674
16355
  async function gitObjectExists(folder, specification, timeoutMs, signal) {
15675
- 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;
15676
16357
  }
15677
16358
  async function comparisonSides(input, folder, timeoutMs, signal) {
15678
16359
  if (!input.path) return { before: null, after: null };
15679
16360
  const path = input.path;
15680
16361
  const previousPath = input.previousPath ?? path;
15681
- const currentPath = join13(folder, path);
16362
+ const currentPath = join14(folder, path);
15682
16363
  if (input.scope === "UNTRACKED") {
15683
16364
  return { before: null, after: { kind: "FILE", path: currentPath } };
15684
16365
  }
@@ -15780,8 +16461,8 @@ async function availableSide(side, folder, timeoutMs, signal) {
15780
16461
  return gitObjectExists(folder, side.specification, timeoutMs, signal);
15781
16462
  }
15782
16463
  try {
15783
- const resolved = await realpath8(side.path);
15784
- const difference = relative7(folder, resolved);
16464
+ const resolved = await realpath9(side.path);
16465
+ const difference = relative8(folder, resolved);
15785
16466
  return difference !== ".." && !difference.startsWith("../") && (await stat10(resolved)).isFile();
15786
16467
  } catch {
15787
16468
  return false;
@@ -15853,7 +16534,7 @@ async function inspectRequestedDiff(input, folder, timeoutMs, signal) {
15853
16534
  let patch;
15854
16535
  if (input.scope === "UNTRACKED") {
15855
16536
  const bounded = await readBoundedFile(
15856
- join13(folder, input.path),
16537
+ join14(folder, input.path),
15857
16538
  MAX_DIFF_BYTES
15858
16539
  );
15859
16540
  const contents = bounded.contents;
@@ -15864,8 +16545,8 @@ async function inspectRequestedDiff(input, folder, timeoutMs, signal) {
15864
16545
  patch = untrackedTextPatch(input.path, contents);
15865
16546
  }
15866
16547
  } else {
15867
- patch = requireSuccess3(
15868
- await git3(folder, args, timeoutMs, signal),
16548
+ patch = requireSuccess4(
16549
+ await git4(folder, args, timeoutMs, signal),
15869
16550
  "Could not load the file diff"
15870
16551
  ).stdout;
15871
16552
  }
@@ -15888,7 +16569,7 @@ async function validateChangedPath(input, folder, timeoutMs, signal) {
15888
16569
  if (!input.path) throw new Error("A changed file path is required");
15889
16570
  let result;
15890
16571
  if (input.scope === "UNTRACKED") {
15891
- result = await git3(
16572
+ result = await git4(
15892
16573
  folder,
15893
16574
  ["ls-files", "--others", "--exclude-standard", "-z", "--", input.path],
15894
16575
  timeoutMs,
@@ -15919,9 +16600,9 @@ async function validateChangedPath(input, folder, timeoutMs, signal) {
15919
16600
  );
15920
16601
  }
15921
16602
  args.push("--", ...requestedDiffPaths(input));
15922
- result = await git3(folder, args, timeoutMs, signal);
16603
+ result = await git4(folder, args, timeoutMs, signal);
15923
16604
  }
15924
- requireSuccess3(result, "Could not validate the changed file");
16605
+ requireSuccess4(result, "Could not validate the changed file");
15925
16606
  const requested = input.scope === "UNTRACKED" ? result.stdout.split("\0").filter(Boolean).includes(input.path) : parseNameStatus(result.stdout).some(
15926
16607
  (file) => file.path === input.path && (!input.previousPath || file.previousPath === input.previousPath)
15927
16608
  );
@@ -15986,7 +16667,7 @@ async function writeGitObject(folder, specification, destination, timeoutMs, sig
15986
16667
  signal.removeEventListener("abort", abort);
15987
16668
  if (settled) return;
15988
16669
  if (code !== 0) {
15989
- fail(new Error(cleanError3(stderr || "Could not extract image")));
16670
+ fail(new Error(cleanError4(stderr || "Could not extract image")));
15990
16671
  return;
15991
16672
  }
15992
16673
  output.end(() => {
@@ -16017,14 +16698,14 @@ var downloadWorktreeDiffAsset = async (payload, timeoutMs, signal, _onLog, conte
16017
16698
  let temporaryDirectory = null;
16018
16699
  try {
16019
16700
  if (selected.kind === "FILE") {
16020
- uploadPath = await realpath8(selected.path);
16021
- const difference = relative7(folder, uploadPath);
16701
+ uploadPath = await realpath9(selected.path);
16702
+ const difference = relative8(folder, uploadPath);
16022
16703
  if (difference === ".." || difference.startsWith("../")) {
16023
16704
  throw new Error("Diff image resolves outside the worktree");
16024
16705
  }
16025
16706
  } else {
16026
- const size = requireSuccess3(
16027
- await git3(
16707
+ const size = requireSuccess4(
16708
+ await git4(
16028
16709
  folder,
16029
16710
  ["cat-file", "-s", selected.specification],
16030
16711
  timeoutMs,
@@ -16035,8 +16716,8 @@ var downloadWorktreeDiffAsset = async (payload, timeoutMs, signal, _onLog, conte
16035
16716
  if (!/^\d+$/.test(size) || Number(size) > 20 * 1024 * 1024) {
16036
16717
  throw new Error("Diff image exceeds the 20 MiB limit");
16037
16718
  }
16038
- temporaryDirectory = await mkdtemp6(join13(tmpdir6(), "ade-diff-image-"));
16039
- uploadPath = join13(temporaryDirectory, basename5(input.path));
16719
+ temporaryDirectory = await mkdtemp6(join14(tmpdir6(), "ade-diff-image-"));
16720
+ uploadPath = join14(temporaryDirectory, basename5(input.path));
16040
16721
  await writeGitObject(
16041
16722
  folder,
16042
16723
  selected.specification,
@@ -16058,7 +16739,7 @@ var downloadWorktreeDiffAsset = async (payload, timeoutMs, signal, _onLog, conte
16058
16739
  return successfulProcess8;
16059
16740
  } finally {
16060
16741
  if (temporaryDirectory) {
16061
- await rm9(temporaryDirectory, { recursive: true, force: true });
16742
+ await rm10(temporaryDirectory, { recursive: true, force: true });
16062
16743
  }
16063
16744
  }
16064
16745
  };
@@ -16154,7 +16835,7 @@ var inspectWorktreeGit = async (payload, timeoutMs, signal) => {
16154
16835
  var commitWorktree = async (payload, timeoutMs, signal) => {
16155
16836
  const input = worktreeCommitJobPayload(payload);
16156
16837
  const folder = await validateWorktree2(input, timeoutMs, signal);
16157
- 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);
16158
16839
  if (input.stageAll) {
16159
16840
  await runGit(["add", "--all"], "Could not stage worktree changes");
16160
16841
  } else {
@@ -16167,7 +16848,7 @@ var commitWorktree = async (payload, timeoutMs, signal) => {
16167
16848
  if (!change) throw new Error(`Worktree change no longer exists: ${path}`);
16168
16849
  return change;
16169
16850
  });
16170
- const head = await git3(
16851
+ const head = await git4(
16171
16852
  folder,
16172
16853
  ["rev-parse", "--verify", "HEAD"],
16173
16854
  timeoutMs,
@@ -16196,7 +16877,7 @@ var commitWorktree = async (payload, timeoutMs, signal) => {
16196
16877
  "Could not stage selected worktree changes"
16197
16878
  );
16198
16879
  }
16199
- const staged = await git3(
16880
+ const staged = await git4(
16200
16881
  folder,
16201
16882
  ["diff", "--cached", "--quiet", "--exit-code"],
16202
16883
  timeoutMs,
@@ -16204,10 +16885,10 @@ var commitWorktree = async (payload, timeoutMs, signal) => {
16204
16885
  );
16205
16886
  if (staged.exitCode === 0) throw new Error("No staged changes to commit");
16206
16887
  if (staged.exitCode !== 1)
16207
- requireSuccess3(staged, "Could not inspect staged changes");
16888
+ requireSuccess4(staged, "Could not inspect staged changes");
16208
16889
  let signed = input.signed;
16209
16890
  if (signed === null) {
16210
- const configured = await git3(
16891
+ const configured = await git4(
16211
16892
  folder,
16212
16893
  ["config", "--bool", "--get", "commit.gpgsign"],
16213
16894
  timeoutMs,
@@ -16264,7 +16945,7 @@ var operateWorktreeGit = async (payload, timeoutMs, signal) => {
16264
16945
  };
16265
16946
  };
16266
16947
  async function refExists(folder, ref, timeoutMs, signal) {
16267
- const result = await git3(
16948
+ const result = await git4(
16268
16949
  folder,
16269
16950
  ["show-ref", "--verify", "--quiet", ref],
16270
16951
  timeoutMs,
@@ -16273,13 +16954,13 @@ async function refExists(folder, ref, timeoutMs, signal) {
16273
16954
  return result.exitCode === 0;
16274
16955
  }
16275
16956
  async function resolveHead(folder, ref, timeoutMs, signal) {
16276
- return requireSuccess3(
16277
- await git3(folder, ["rev-parse", ref], timeoutMs, signal),
16957
+ return requireSuccess4(
16958
+ await git4(folder, ["rev-parse", ref], timeoutMs, signal),
16278
16959
  `Could not resolve ${ref}`
16279
16960
  ).stdout.trim();
16280
16961
  }
16281
16962
  async function isAncestor(folder, ancestor, descendant, timeoutMs, signal) {
16282
- const result = await git3(
16963
+ const result = await git4(
16283
16964
  folder,
16284
16965
  ["merge-base", "--is-ancestor", ancestor, descendant],
16285
16966
  timeoutMs,
@@ -16287,12 +16968,12 @@ async function isAncestor(folder, ancestor, descendant, timeoutMs, signal) {
16287
16968
  );
16288
16969
  if (result.exitCode === 0) return true;
16289
16970
  if (result.exitCode === 1) return false;
16290
- requireSuccess3(result, "Could not compare Git history");
16971
+ requireSuccess4(result, "Could not compare Git history");
16291
16972
  return false;
16292
16973
  }
16293
16974
  async function statusState(folder, timeoutMs, signal) {
16294
- const result = requireSuccess3(
16295
- await git3(
16975
+ const result = requireSuccess4(
16976
+ await git4(
16296
16977
  folder,
16297
16978
  ["status", "--porcelain=v1", "-z", "--untracked-files=all"],
16298
16979
  timeoutMs,
@@ -16306,7 +16987,7 @@ function hasChanges(changes) {
16306
16987
  return changes.hasStagedChanges || changes.hasUnstagedChanges;
16307
16988
  }
16308
16989
  async function currentBranch(folder, timeoutMs, signal) {
16309
- const result = await git3(
16990
+ const result = await git4(
16310
16991
  folder,
16311
16992
  ["symbolic-ref", "--short", "-q", "HEAD"],
16312
16993
  timeoutMs,
@@ -16326,7 +17007,7 @@ async function chooseNewBranch(folder, candidates, allowedCurrentBranch, timeout
16326
17007
  throw new Error("Every generated ticket branch name is already taken");
16327
17008
  }
16328
17009
  async function validateBranchRoot(input, timeoutMs, signal) {
16329
- const rootFolder = await realpath8(input.rootFolder);
17010
+ const rootFolder = await realpath9(input.rootFolder);
16330
17011
  if (!(await stat10(rootFolder)).isDirectory()) {
16331
17012
  throw new Error("Base repository is missing");
16332
17013
  }
@@ -16390,8 +17071,8 @@ var branchWorktree = async (payload, timeoutMs, signal) => {
16390
17071
  timeoutMs,
16391
17072
  signal
16392
17073
  ) : input.candidates[0];
16393
- const targetFolder = input.action === "CREATE" ? join13(
16394
- dirname7(rootFolder),
17074
+ const targetFolder = input.action === "CREATE" ? join14(
17075
+ dirname8(rootFolder),
16395
17076
  `${basename5(rootFolder)}-${branch.replaceAll("/", "-")}`
16396
17077
  ) : changeFolder;
16397
17078
  if (input.action === "CREATE") {
@@ -16436,40 +17117,89 @@ var branchWorktree = async (payload, timeoutMs, signal) => {
16436
17117
  ];
16437
17118
  }
16438
17119
  let stashed = false;
16439
- if (args.length > 0) {
16440
- let switched = await git3(
16441
- input.action === "CREATE" ? rootFolder : targetFolder,
16442
- 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,
16443
17132
  timeoutMs,
16444
- signal
17133
+ signal,
17134
+ true
16445
17135
  );
16446
- if (switched.exitCode !== 0 && input.action === "CHANGE" && input.stashOnFailure) {
16447
- const stash = requireSuccess3(
16448
- await git3(
16449
- targetFolder,
16450
- [
16451
- "stash",
16452
- "push",
16453
- "--include-untracked",
16454
- "-m",
16455
- `Automatic stash before switching to ${branch}`
16456
- ],
16457
- timeoutMs,
16458
- signal
16459
- ),
16460
- "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("; ")
16461
17142
  );
16462
- stashed = !stash.stdout.toLowerCase().includes("no local changes");
16463
- switched = await git3(targetFolder, args, timeoutMs, signal);
16464
- if (switched.exitCode !== 0) {
16465
- throw new Error(
16466
- `${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"
16467
17180
  );
16468
17181
  }
16469
- } else {
16470
- requireSuccess3(
16471
- switched,
16472
- 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("; ")
16473
17203
  );
16474
17204
  }
16475
17205
  }
@@ -16489,7 +17219,9 @@ var branchWorktree = async (payload, timeoutMs, signal) => {
16489
17219
  worktree,
16490
17220
  branch,
16491
17221
  baseBranch: input.baseBranch,
16492
- stashed
17222
+ stashed,
17223
+ checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
17224
+ preparations
16493
17225
  };
16494
17226
  };
16495
17227
  var pushMovedWorktree = async (payload, timeoutMs, signal) => {
@@ -16516,8 +17248,8 @@ var pushMovedWorktree = async (payload, timeoutMs, signal) => {
16516
17248
  if (hasChanges(changes)) {
16517
17249
  throw new Error("Commit or discard source changes before moving");
16518
17250
  }
16519
- requireSuccess3(
16520
- await git3(folder, ["fetch", "origin"], timeoutMs, signal),
17251
+ requireSuccess4(
17252
+ await git4(folder, ["fetch", "origin"], timeoutMs, signal),
16521
17253
  "Could not fetch origin before moving"
16522
17254
  );
16523
17255
  const remoteRef = `refs/remotes/origin/${branch}`;
@@ -16526,8 +17258,8 @@ var pushMovedWorktree = async (payload, timeoutMs, signal) => {
16526
17258
  "The origin branch contains commits that must be pulled before moving"
16527
17259
  );
16528
17260
  }
16529
- requireSuccess3(
16530
- await git3(
17261
+ requireSuccess4(
17262
+ await git4(
16531
17263
  folder,
16532
17264
  ["push", "--set-upstream", "origin", `HEAD:refs/heads/${branch}`],
16533
17265
  timeoutMs,
@@ -16562,8 +17294,8 @@ async function updateLocalBranchForMove(rootFolder, branch, expectedHeadSha, tim
16562
17294
  `Local branch ${branch} has commits that are not on origin; move them before retrying`
16563
17295
  );
16564
17296
  }
16565
- requireSuccess3(
16566
- await git3(
17297
+ requireSuccess4(
17298
+ await git4(
16567
17299
  rootFolder,
16568
17300
  ["branch", "-f", branch, expectedHeadSha],
16569
17301
  timeoutMs,
@@ -16574,8 +17306,8 @@ async function updateLocalBranchForMove(rootFolder, branch, expectedHeadSha, tim
16574
17306
  return true;
16575
17307
  }
16576
17308
  async function checkedOutBranchFolder(rootFolder, branch, timeoutMs, signal) {
16577
- const result = requireSuccess3(
16578
- await git3(
17309
+ const result = requireSuccess4(
17310
+ await git4(
16579
17311
  rootFolder,
16580
17312
  ["worktree", "list", "--porcelain"],
16581
17313
  timeoutMs,
@@ -16591,8 +17323,8 @@ var checkoutMovedWorktree = async (payload, timeoutMs, signal) => {
16591
17323
  const input = worktreeMoveCheckoutJobPayload(payload);
16592
17324
  const rootFolder = await validateBranchRoot(input, timeoutMs, signal);
16593
17325
  const remoteRef = `refs/remotes/origin/${input.branch}`;
16594
- requireSuccess3(
16595
- await git3(
17326
+ requireSuccess4(
17327
+ await git4(
16596
17328
  rootFolder,
16597
17329
  [
16598
17330
  "fetch",
@@ -16617,6 +17349,7 @@ var checkoutMovedWorktree = async (payload, timeoutMs, signal) => {
16617
17349
  );
16618
17350
  }
16619
17351
  let targetFolder;
17352
+ let createdLocalBranch = false;
16620
17353
  let stashed = false;
16621
17354
  const occupiedFolder = await checkedOutBranchFolder(
16622
17355
  rootFolder,
@@ -16630,8 +17363,8 @@ var checkoutMovedWorktree = async (payload, timeoutMs, signal) => {
16630
17363
  `Branch ${input.branch} is already checked out in ${occupiedFolder}`
16631
17364
  );
16632
17365
  }
16633
- targetFolder = join13(
16634
- dirname7(rootFolder),
17366
+ targetFolder = join14(
17367
+ dirname8(rootFolder),
16635
17368
  `${basename5(rootFolder)}-${input.branch.replaceAll("/", "-")}`
16636
17369
  );
16637
17370
  try {
@@ -16649,8 +17382,9 @@ var checkoutMovedWorktree = async (payload, timeoutMs, signal) => {
16649
17382
  timeoutMs,
16650
17383
  signal
16651
17384
  );
16652
- requireSuccess3(
16653
- await git3(
17385
+ createdLocalBranch = !local;
17386
+ requireSuccess4(
17387
+ await git4(
16654
17388
  rootFolder,
16655
17389
  local ? ["worktree", "add", targetFolder, input.branch] : [
16656
17390
  "worktree",
@@ -16681,7 +17415,7 @@ var checkoutMovedWorktree = async (payload, timeoutMs, signal) => {
16681
17415
  const targetBranch = await currentBranch(targetFolder, timeoutMs, signal);
16682
17416
  const targetChanges = await statusState(targetFolder, timeoutMs, signal);
16683
17417
  if (occupiedFolder) {
16684
- const occupied = await realpath8(occupiedFolder);
17418
+ const occupied = await realpath9(occupiedFolder);
16685
17419
  if (occupied !== targetFolder) {
16686
17420
  throw new Error(
16687
17421
  `Branch ${input.branch} is checked out in another destination worktree`
@@ -16719,8 +17453,8 @@ var checkoutMovedWorktree = async (payload, timeoutMs, signal) => {
16719
17453
  switchArgs = local ? ["switch", input.branch] : ["switch", "--track", "-c", input.branch, remoteRef];
16720
17454
  }
16721
17455
  if (input.stashOnFailure && hasChanges(targetChanges)) {
16722
- const stash = requireSuccess3(
16723
- await git3(
17456
+ const stash = requireSuccess4(
17457
+ await git4(
16724
17458
  targetFolder,
16725
17459
  [
16726
17460
  "stash",
@@ -16736,25 +17470,25 @@ var checkoutMovedWorktree = async (payload, timeoutMs, signal) => {
16736
17470
  );
16737
17471
  stashed = !stash.stdout.toLowerCase().includes("no local changes");
16738
17472
  }
16739
- const switched = await git3(targetFolder, switchArgs, timeoutMs, signal);
17473
+ const switched = await git4(targetFolder, switchArgs, timeoutMs, signal);
16740
17474
  if (switched.exitCode !== 0) {
16741
17475
  if (!input.stashOnFailure && hasChanges(targetChanges)) {
16742
17476
  return {
16743
17477
  ...successfulProcess8,
16744
17478
  moveId: input.moveId,
16745
17479
  outcome: "NEEDS_STASH",
16746
- message: cleanError3(
17480
+ message: cleanError4(
16747
17481
  switched.stderr || "Destination changes block the branch switch"
16748
17482
  )
16749
17483
  };
16750
17484
  }
16751
17485
  throw new Error(
16752
- `${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." : ""}`
16753
17487
  );
16754
17488
  }
16755
17489
  }
16756
- requireSuccess3(
16757
- await git3(
17490
+ requireSuccess4(
17491
+ await git4(
16758
17492
  targetFolder,
16759
17493
  ["branch", "--set-upstream-to", `origin/${input.branch}`, input.branch],
16760
17494
  timeoutMs,
@@ -16771,6 +17505,30 @@ var checkoutMovedWorktree = async (payload, timeoutMs, signal) => {
16771
17505
  if (checkedOutHead !== input.expectedHeadSha) {
16772
17506
  throw new Error("The destination did not check out the pushed commit");
16773
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
+ }
16774
17532
  const worktree = await inspectWorktreeItem(
16775
17533
  targetFolder,
16776
17534
  rootFolder,
@@ -16790,12 +17548,72 @@ var checkoutMovedWorktree = async (payload, timeoutMs, signal) => {
16790
17548
  outcome: "CHECKED_OUT",
16791
17549
  worktree,
16792
17550
  baseBranch: input.baseBranch,
16793
- 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
16794
17612
  };
16795
17613
  };
16796
17614
  var deleteWorktree = async (payload, timeoutMs, signal) => {
16797
17615
  const input = worktreeDeleteJobPayload(payload);
16798
- const rootFolder = await realpath8(input.rootFolder);
17616
+ const rootFolder = await realpath9(input.rootFolder);
16799
17617
  if (!(await stat10(rootFolder)).isDirectory()) {
16800
17618
  throw new Error("Base repository is missing");
16801
17619
  }
@@ -16816,8 +17634,8 @@ var deleteWorktree = async (payload, timeoutMs, signal) => {
16816
17634
  if (folder === rootFolder)
16817
17635
  throw new Error("The primary worktree cannot be deleted");
16818
17636
  const listed = parseWorktreeList(
16819
- requireSuccess3(
16820
- await git3(
17637
+ requireSuccess4(
17638
+ await git4(
16821
17639
  rootFolder,
16822
17640
  ["worktree", "list", "--porcelain"],
16823
17641
  timeoutMs,
@@ -16847,15 +17665,15 @@ var deleteWorktree = async (payload, timeoutMs, signal) => {
16847
17665
  if (branch === input.defaultBranch) {
16848
17666
  throw new Error("The default remote branch cannot be deleted");
16849
17667
  }
16850
- const remote = await git3(
17668
+ const remote = await git4(
16851
17669
  rootFolder,
16852
17670
  ["ls-remote", "--exit-code", "--heads", "origin", `refs/heads/${branch}`],
16853
17671
  timeoutMs,
16854
17672
  signal
16855
17673
  );
16856
17674
  if (remote.exitCode === 0) {
16857
- requireSuccess3(
16858
- await git3(
17675
+ requireSuccess4(
17676
+ await git4(
16859
17677
  rootFolder,
16860
17678
  ["push", "origin", "--delete", branch],
16861
17679
  timeoutMs,
@@ -16864,11 +17682,11 @@ var deleteWorktree = async (payload, timeoutMs, signal) => {
16864
17682
  `Could not delete origin/${branch}`
16865
17683
  );
16866
17684
  } else if (remote.exitCode !== 2) {
16867
- requireSuccess3(remote, `Could not inspect origin/${branch}`);
17685
+ requireSuccess4(remote, `Could not inspect origin/${branch}`);
16868
17686
  }
16869
17687
  }
16870
- requireSuccess3(
16871
- await git3(
17688
+ requireSuccess4(
17689
+ await git4(
16872
17690
  rootFolder,
16873
17691
  ["worktree", "remove", "--force", folder],
16874
17692
  timeoutMs,
@@ -16877,8 +17695,8 @@ var deleteWorktree = async (payload, timeoutMs, signal) => {
16877
17695
  "Could not remove the worktree"
16878
17696
  );
16879
17697
  if (branch && await refExists(rootFolder, `refs/heads/${branch}`, timeoutMs, signal)) {
16880
- requireSuccess3(
16881
- await git3(rootFolder, ["branch", "-D", branch], timeoutMs, signal),
17698
+ requireSuccess4(
17699
+ await git4(rootFolder, ["branch", "-D", branch], timeoutMs, signal),
16882
17700
  `Worktree removed, but local branch ${branch} could not be deleted`
16883
17701
  );
16884
17702
  }
@@ -16894,28 +17712,53 @@ var operateWorktree = async (payload, timeoutMs, signal) => {
16894
17712
  const input = worktreeJobPayload(payload);
16895
17713
  const folder = await validateWorktree2(input, timeoutMs, signal);
16896
17714
  if (!input.operation) throw new Error("A worktree operation is required");
16897
- const branchResult = await git3(
17715
+ const branchResult = await git4(
16898
17716
  folder,
16899
17717
  ["symbolic-ref", "--short", "-q", "HEAD"],
16900
17718
  timeoutMs,
16901
17719
  signal
16902
17720
  );
16903
17721
  const branch = branchResult.exitCode === 0 ? branchResult.stdout.trim() : null;
16904
- const upstreamResult = branch ? await git3(
17722
+ const upstreamResult = branch ? await git4(
16905
17723
  folder,
16906
17724
  ["rev-parse", "--abbrev-ref", "@{upstream}"],
16907
17725
  timeoutMs,
16908
17726
  signal
16909
17727
  ) : null;
16910
17728
  const upstream = upstreamResult?.exitCode === 0 ? upstreamResult.stdout.trim() : null;
16911
- 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
+ );
16912
17755
  switch (input.operation) {
16913
17756
  case "OPEN_EDITOR": {
16914
17757
  if (input.editorVariant === "NONE" || !input.editorVariant) {
16915
17758
  throw new Error("VS Code is disabled in Settings");
16916
17759
  }
16917
17760
  const app = input.editorVariant === "CODE_INSIDERS" ? "Visual Studio Code - Insiders" : "Visual Studio Code";
16918
- requireSuccess3(
17761
+ requireSuccess4(
16919
17762
  await command2("open", ["-a", app, folder], timeoutMs, signal),
16920
17763
  `${app} could not be opened`
16921
17764
  );
@@ -16937,26 +17780,105 @@ var operateWorktree = async (payload, timeoutMs, signal) => {
16937
17780
  if (statusResult.stdout.trim())
16938
17781
  throw new Error("Stash or commit changes before syncing");
16939
17782
  await runGit(["fetch", "origin"], "Could not fetch origin");
16940
- const rebase = await git3(
17783
+ const remoteBase = `refs/remotes/origin/${input.baseBranch}`;
17784
+ const isCurrent = await git4(
16941
17785
  folder,
16942
- ["rebase", `refs/remotes/origin/${input.baseBranch}`],
17786
+ ["merge-base", "--is-ancestor", remoteBase, "HEAD"],
16943
17787
  timeoutMs,
16944
17788
  signal
16945
17789
  );
16946
- if (rebase.exitCode !== 0) {
16947
- 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(
16948
17833
  folder,
16949
17834
  ["status", "--porcelain=v1", "-z"],
16950
17835
  timeoutMs,
16951
17836
  signal
16952
17837
  );
16953
17838
  const conflicts = status2.exitCode === 0 && statusChangeState(status2.stdout).hasConflicts;
16954
- if (!(conflicts && await rebaseInProgress(folder, timeoutMs, signal))) {
16955
- 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();
16956
17866
  }
16957
- throw new Error(cleanError3(rebase.stderr || "Rebase failed"));
17867
+ throw new Error(cleanError4(rebase.stderr || "Rebase failed"));
16958
17868
  }
16959
- 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();
16960
17882
  break;
16961
17883
  }
16962
17884
  case "REBASE": {
@@ -16969,25 +17891,93 @@ var operateWorktree = async (payload, timeoutMs, signal) => {
16969
17891
  if (statusResult.stdout.trim())
16970
17892
  throw new Error("Stash or commit changes before rebasing");
16971
17893
  await runGit(["fetch", "origin"], "Could not fetch origin");
16972
- const rebase = await git3(
17894
+ const remoteBase = `refs/remotes/origin/${input.baseBranch}`;
17895
+ const isCurrent = await git4(
16973
17896
  folder,
16974
- ["rebase", `refs/remotes/origin/${input.baseBranch}`],
17897
+ ["merge-base", "--is-ancestor", remoteBase, "HEAD"],
16975
17898
  timeoutMs,
16976
17899
  signal
16977
17900
  );
16978
- if (rebase.exitCode !== 0) {
16979
- 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(
16980
17944
  folder,
16981
17945
  ["status", "--porcelain=v1", "-z"],
16982
17946
  timeoutMs,
16983
17947
  signal
16984
17948
  );
16985
17949
  const conflicts = status2.exitCode === 0 && statusChangeState(status2.stdout).hasConflicts;
16986
- if (!(conflicts && await rebaseInProgress(folder, timeoutMs, signal))) {
16987
- 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);
16988
17974
  }
16989
- 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"));
16990
17979
  }
17980
+ preparationResults = input.forcePreparations ? await reapplyPreparations() : await inspectPreparations();
16991
17981
  break;
16992
17982
  }
16993
17983
  case "CANCEL_REBASE": {
@@ -16995,6 +17985,7 @@ var operateWorktree = async (payload, timeoutMs, signal) => {
16995
17985
  throw new Error("No rebase is in progress");
16996
17986
  }
16997
17987
  await runGit(["rebase", "--abort"], "Could not cancel rebase");
17988
+ preparationResults = await reapplyPreparations();
16998
17989
  break;
16999
17990
  }
17000
17991
  case "PULL": {
@@ -17033,21 +18024,37 @@ var operateWorktree = async (payload, timeoutMs, signal) => {
17033
18024
  }
17034
18025
  return {
17035
18026
  ...successfulProcess8,
17036
- worktree: await inspectWorktreeItem(
17037
- folder,
17038
- folder,
17039
- input.baseBranch,
17040
- false,
17041
- Math.min(timeoutMs, 3e4),
17042
- signal
17043
- )
18027
+ outcome: operationOutcome,
18028
+ preparationConflictPaths: preparationConflictPathList,
18029
+ checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
18030
+ preparations: preparationResults,
18031
+ worktree: await worktreeResult()
17044
18032
  };
17045
18033
  };
17046
18034
  var autoSyncWorktree = async (payload, timeoutMs, signal) => {
17047
18035
  const input = worktreeAutoSyncJobPayload(payload);
17048
18036
  const folder = await validateWorktree2(input, timeoutMs, signal);
17049
- const runGit = async (args, fallback) => requireSuccess3(await git3(folder, args, timeoutMs, signal), fallback);
17050
- 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(
17051
18058
  folder,
17052
18059
  ["symbolic-ref", "--short", "-q", "HEAD"],
17053
18060
  timeoutMs,
@@ -17060,7 +18067,7 @@ var autoSyncWorktree = async (payload, timeoutMs, signal) => {
17060
18067
  `Auto Sync expected branch ${input.expectedBranch}, but found ${branch ?? "detached HEAD"}`
17061
18068
  );
17062
18069
  }
17063
- const upstreamResult = branch ? await git3(
18070
+ const upstreamResult = branch ? await git4(
17064
18071
  folder,
17065
18072
  ["rev-parse", "--abbrev-ref", "@{upstream}"],
17066
18073
  timeoutMs,
@@ -17081,6 +18088,8 @@ var autoSyncWorktree = async (payload, timeoutMs, signal) => {
17081
18088
  return {
17082
18089
  ...successfulProcess8,
17083
18090
  outcome: "UNRESOLVED",
18091
+ checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
18092
+ preparations: suspendedPreparations(),
17084
18093
  worktree: await inspectWorktreeItem(
17085
18094
  folder,
17086
18095
  folder,
@@ -17109,6 +18118,8 @@ var autoSyncWorktree = async (payload, timeoutMs, signal) => {
17109
18118
  return {
17110
18119
  ...successfulProcess8,
17111
18120
  outcome: "UNRESOLVED",
18121
+ checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
18122
+ preparations: suspendedPreparations(),
17112
18123
  worktree: await inspectWorktreeItem(
17113
18124
  folder,
17114
18125
  folder,
@@ -17129,6 +18140,8 @@ var autoSyncWorktree = async (payload, timeoutMs, signal) => {
17129
18140
  return {
17130
18141
  ...successfulProcess8,
17131
18142
  outcome: "UNRESOLVED",
18143
+ checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
18144
+ preparations: suspendedPreparations(),
17132
18145
  worktree: await inspectWorktreeItem(
17133
18146
  folder,
17134
18147
  folder,
@@ -17139,13 +18152,13 @@ var autoSyncWorktree = async (payload, timeoutMs, signal) => {
17139
18152
  )
17140
18153
  };
17141
18154
  }
17142
- const finalBranch = await git3(
18155
+ const finalBranch = await git4(
17143
18156
  folder,
17144
18157
  ["symbolic-ref", "--short", "-q", "HEAD"],
17145
18158
  timeoutMs,
17146
18159
  signal
17147
18160
  );
17148
- const finalUpstream = finalBranch.exitCode === 0 ? await git3(
18161
+ const finalUpstream = finalBranch.exitCode === 0 ? await git4(
17149
18162
  folder,
17150
18163
  ["rev-parse", "--abbrev-ref", "@{upstream}"],
17151
18164
  timeoutMs,
@@ -17156,10 +18169,22 @@ var autoSyncWorktree = async (payload, timeoutMs, signal) => {
17156
18169
  `Auto Sync expected branch ${input.expectedBranch} with an upstream`
17157
18170
  );
17158
18171
  }
17159
- 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();
17160
18183
  return {
17161
18184
  ...successfulProcess8,
17162
18185
  outcome: "SYNCED",
18186
+ checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
18187
+ preparations,
17163
18188
  worktree: await inspectWorktreeItem(
17164
18189
  folder,
17165
18190
  folder,
@@ -17179,14 +18204,14 @@ var autoSyncWorktree = async (payload, timeoutMs, signal) => {
17179
18204
  }
17180
18205
  await runGit(["fetch", "origin"], "Could not fetch origin");
17181
18206
  const remoteBase = `refs/remotes/origin/${input.baseBranch}`;
17182
- const isCurrent = await git3(
18207
+ const isCurrent = await git4(
17183
18208
  folder,
17184
18209
  ["merge-base", "--is-ancestor", remoteBase, "HEAD"],
17185
18210
  timeoutMs,
17186
18211
  signal
17187
18212
  );
17188
18213
  if (isCurrent.exitCode === 0) {
17189
- const upstreamContainsHead = await git3(
18214
+ const upstreamContainsHead = await git4(
17190
18215
  folder,
17191
18216
  ["merge-base", "--is-ancestor", "HEAD", "@{upstream}"],
17192
18217
  timeoutMs,
@@ -17194,7 +18219,7 @@ var autoSyncWorktree = async (payload, timeoutMs, signal) => {
17194
18219
  );
17195
18220
  if (upstreamContainsHead.exitCode !== 0 && upstreamContainsHead.exitCode !== 1) {
17196
18221
  throw new Error(
17197
- cleanError3(
18222
+ cleanError4(
17198
18223
  upstreamContainsHead.stderr || "Could not compare the upstream branch"
17199
18224
  )
17200
18225
  );
@@ -17204,6 +18229,8 @@ var autoSyncWorktree = async (payload, timeoutMs, signal) => {
17204
18229
  return {
17205
18230
  ...successfulProcess8,
17206
18231
  outcome: "SYNCED",
18232
+ checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
18233
+ preparations: await inspectPreparations(),
17207
18234
  worktree: await inspectWorktreeItem(
17208
18235
  folder,
17209
18236
  folder,
@@ -17217,6 +18244,8 @@ var autoSyncWorktree = async (payload, timeoutMs, signal) => {
17217
18244
  return {
17218
18245
  ...successfulProcess8,
17219
18246
  outcome: "NO_CHANGE",
18247
+ checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
18248
+ preparations: await inspectPreparations(),
17220
18249
  worktree: await inspectWorktreeItem(
17221
18250
  folder,
17222
18251
  folder,
@@ -17227,9 +18256,50 @@ var autoSyncWorktree = async (payload, timeoutMs, signal) => {
17227
18256
  )
17228
18257
  };
17229
18258
  }
17230
- const rebase = await git3(folder, ["rebase", remoteBase], timeoutMs, signal);
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(),
18273
+ worktree: await inspectWorktreeItem(
18274
+ folder,
18275
+ folder,
18276
+ input.baseBranch,
18277
+ false,
18278
+ Math.min(timeoutMs, 3e4),
18279
+ signal
18280
+ )
18281
+ };
18282
+ }
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);
17231
18301
  if (rebase.exitCode !== 0) {
17232
- const conflictStatus = await git3(
18302
+ const conflictStatus = await git4(
17233
18303
  folder,
17234
18304
  ["status", "--porcelain=v1", "-z"],
17235
18305
  timeoutMs,
@@ -17240,6 +18310,8 @@ var autoSyncWorktree = async (payload, timeoutMs, signal) => {
17240
18310
  return {
17241
18311
  ...successfulProcess8,
17242
18312
  outcome: "CONFLICT",
18313
+ checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
18314
+ preparations: suspendedPreparations(),
17243
18315
  worktree: await inspectWorktreeItem(
17244
18316
  folder,
17245
18317
  folder,
@@ -17250,13 +18322,26 @@ var autoSyncWorktree = async (payload, timeoutMs, signal) => {
17250
18322
  )
17251
18323
  };
17252
18324
  }
17253
- await git3(folder, ["rebase", "--abort"], timeoutMs, signal);
17254
- 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"));
17255
18328
  }
17256
- await runGit(["push", "--force-with-lease"], "Auto Sync push failed");
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");
18338
+ }
18339
+ preparationResults = input.forcePreparations ? await reapplyPreparations() : await inspectPreparations();
17257
18340
  return {
17258
18341
  ...successfulProcess8,
17259
18342
  outcome: "SYNCED",
18343
+ checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
18344
+ preparations: preparationResults,
17260
18345
  worktree: await inspectWorktreeItem(
17261
18346
  folder,
17262
18347
  folder,
@@ -17290,6 +18375,7 @@ var handlers = {
17290
18375
  [WORKTREE_MOVE_CHECKOUT_JOB_KIND]: checkoutMovedWorktree,
17291
18376
  [WORKTREE_DELETE_JOB_KIND]: deleteWorktree,
17292
18377
  [WORKTREE_OPERATION_JOB_KIND]: operateWorktree,
18378
+ [WORKTREE_PREPARATION_JOB_KIND]: prepareWorktree,
17293
18379
  [WORKTREE_GIT_INSPECT_JOB_KIND]: inspectWorktreeGit,
17294
18380
  [WORKTREE_GIT_OPERATION_JOB_KIND]: operateWorktreeGit,
17295
18381
  [WORKTREE_WATCH_JOB_KIND]: watchWorktree,
@@ -17328,8 +18414,8 @@ var RepositoryCoordinator = class {
17328
18414
  async run(key, task) {
17329
18415
  const previous = this.tails.get(key) ?? Promise.resolve();
17330
18416
  let release2;
17331
- const current = new Promise((resolve8) => {
17332
- release2 = resolve8;
18417
+ const current = new Promise((resolve9) => {
18418
+ release2 = resolve9;
17333
18419
  });
17334
18420
  const tail = previous.then(() => current);
17335
18421
  this.tails.set(key, tail);
@@ -17433,7 +18519,7 @@ var JobExecutor = class {
17433
18519
  );
17434
18520
  if (this.stopping) return;
17435
18521
  const delay = Math.min(3e4, 1e3 * 2 ** Math.min(retry++, 5));
17436
- await new Promise((resolve8) => setTimeout(resolve8, delay));
18522
+ await new Promise((resolve9) => setTimeout(resolve9, delay));
17437
18523
  }
17438
18524
  }
17439
18525
  }
@@ -17580,21 +18666,21 @@ var CodebaseMonitor = class {
17580
18666
 
17581
18667
  // src/runs/run-manager.ts
17582
18668
  import { execFile as execFile4 } from "node:child_process";
17583
- import { mkdir as mkdir6, rm as rm13 } from "node:fs/promises";
17584
- 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";
17585
18671
  import { promisify as promisify4 } from "node:util";
17586
18672
 
17587
18673
  // src/runs/journal.ts
17588
18674
  import { randomUUID as randomUUID4 } from "node:crypto";
17589
18675
  import {
17590
18676
  appendFile,
17591
- mkdir as mkdir5,
17592
- readFile as readFile9,
18677
+ mkdir as mkdir6,
18678
+ readFile as readFile10,
17593
18679
  rename as rename4,
17594
- rm as rm10,
17595
- writeFile as writeFile7
18680
+ rm as rm11,
18681
+ writeFile as writeFile8
17596
18682
  } from "node:fs/promises";
17597
- import { dirname as dirname8, join as join14 } from "node:path";
18683
+ import { dirname as dirname9, join as join15 } from "node:path";
17598
18684
  var RunJournal = class {
17599
18685
  constructor(runId, attemptId) {
17600
18686
  this.runId = runId;
@@ -17613,13 +18699,13 @@ var RunJournal = class {
17613
18699
  this.attemptId = attemptId;
17614
18700
  }
17615
18701
  get directory() {
17616
- return join14(dirname8(configPath()), "runs", this.runId);
18702
+ return join15(dirname9(configPath()), "runs", this.runId);
17617
18703
  }
17618
18704
  get eventsPath() {
17619
- return join14(this.directory, "events.jsonl");
18705
+ return join15(this.directory, "events.jsonl");
17620
18706
  }
17621
18707
  get statePath() {
17622
- return join14(this.directory, "state.json");
18708
+ return join15(this.directory, "state.json");
17623
18709
  }
17624
18710
  async load() {
17625
18711
  if (this.loaded) return;
@@ -17631,9 +18717,9 @@ var RunJournal = class {
17631
18717
  await this.loading;
17632
18718
  }
17633
18719
  async loadState() {
17634
- await mkdir5(this.directory, { recursive: true, mode: 448 });
18720
+ await mkdir6(this.directory, { recursive: true, mode: 448 });
17635
18721
  try {
17636
- const state = JSON.parse(await readFile9(this.statePath, "utf8"));
18722
+ const state = JSON.parse(await readFile10(this.statePath, "utf8"));
17637
18723
  this.acknowledged = state.acknowledged ?? -1;
17638
18724
  this.nextSequence = state.nextSequence ?? 0;
17639
18725
  } catch {
@@ -17708,7 +18794,7 @@ var RunJournal = class {
17708
18794
  }
17709
18795
  async readEvents() {
17710
18796
  try {
17711
- 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));
17712
18798
  } catch (error) {
17713
18799
  if (error.code === "ENOENT") return [];
17714
18800
  throw error;
@@ -17720,10 +18806,10 @@ var RunJournal = class {
17720
18806
  const operation = this.saving.then(async () => {
17721
18807
  const temporary = `${this.statePath}.${process.pid}.${randomUUID4()}.tmp`;
17722
18808
  try {
17723
- await writeFile7(temporary, contents, { mode: 384 });
18809
+ await writeFile8(temporary, contents, { mode: 384 });
17724
18810
  await rename4(temporary, this.statePath);
17725
18811
  } catch (error) {
17726
- await rm10(temporary, { force: true }).catch(() => void 0);
18812
+ await rm11(temporary, { force: true }).catch(() => void 0);
17727
18813
  throw error;
17728
18814
  }
17729
18815
  });
@@ -26897,7 +27983,7 @@ function Yy(e) {
26897
27983
  var l = {};
26898
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 });
26899
27985
  var Qr = {};
26900
- 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 });
26901
27987
  var Kd = Object.freeze({ status: "aborted" });
26902
27988
  function S(e, t, r) {
26903
27989
  function n(a, c) {
@@ -28445,7 +29531,7 @@ var tm = S("$ZodReadonly", (e, t) => {
28445
29531
  function DC(e) {
28446
29532
  return e.value = Object.freeze(e.value), e;
28447
29533
  }
28448
- var rm11 = S("$ZodTemplateLiteral", (e, t) => {
29534
+ var rm12 = S("$ZodTemplateLiteral", (e, t) => {
28449
29535
  ie.init(e, t);
28450
29536
  let r = [];
28451
29537
  for (let n of t.parts) if (n instanceof ie) {
@@ -32252,7 +33338,7 @@ function hR(e) {
32252
33338
  return new gR({ type: "readonly", innerType: e });
32253
33339
  }
32254
33340
  var _R = S("ZodTemplateLiteral", (e, t) => {
32255
- rm11.init(e, t), de.init(e, t);
33341
+ rm12.init(e, t), de.init(e, t);
32256
33342
  });
32257
33343
  function q9(e, t) {
32258
33344
  return new _R({ type: "template_literal", parts: e, ...M.normalizeParams(t) });
@@ -43579,7 +44665,7 @@ var MessageQueue = class {
43579
44665
  if (value) return Promise.resolve({ value, done: false });
43580
44666
  if (this.closed)
43581
44667
  return Promise.resolve({ value: void 0, done: true });
43582
- return new Promise((resolve8) => this.waiters.push(resolve8));
44668
+ return new Promise((resolve9) => this.waiters.push(resolve9));
43583
44669
  }
43584
44670
  };
43585
44671
  }
@@ -43749,8 +44835,8 @@ var ClaudeAdapter = class {
43749
44835
  const requestId = options.toolUseID || randomUUID5();
43750
44836
  const questions = questionsFromInput(toolInput);
43751
44837
  await callbacks.onQuestion(requestId, questions);
43752
- const answers = await new Promise((resolve8) => {
43753
- pendingQuestions.set(requestId, { input: toolInput, resolve: resolve8 });
44838
+ const answers = await new Promise((resolve9) => {
44839
+ pendingQuestions.set(requestId, { input: toolInput, resolve: resolve9 });
43754
44840
  });
43755
44841
  return {
43756
44842
  behavior: "allow",
@@ -43893,9 +44979,9 @@ import {
43893
44979
  execFile as execFile3,
43894
44980
  spawn as spawn8
43895
44981
  } from "node:child_process";
43896
- 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";
43897
44983
  import { tmpdir as tmpdir7 } from "node:os";
43898
- import { join as join16 } from "node:path";
44984
+ import { join as join17 } from "node:path";
43899
44985
  import { createInterface } from "node:readline";
43900
44986
  import { promisify as promisify3 } from "node:util";
43901
44987
  var SUPPORTED_CODEX_APP_SERVER_MINORS = ["0.144", "0.145"];
@@ -44006,8 +45092,8 @@ var CodexAppServer = class {
44006
45092
  });
44007
45093
  const lines = createInterface({ input: child.stdout });
44008
45094
  lines.on("line", (line) => this.receive(line));
44009
- await new Promise((resolve8, reject) => {
44010
- child.once("spawn", resolve8);
45095
+ await new Promise((resolve9, reject) => {
45096
+ child.once("spawn", resolve9);
44011
45097
  child.once("error", reject);
44012
45098
  });
44013
45099
  const initialized = asRecord(
@@ -44049,7 +45135,7 @@ var CodexAppServer = class {
44049
45135
  }
44050
45136
  }
44051
45137
  async createBundledModelCatalog(executable) {
44052
- const directory = await mkdtemp7(join16(tmpdir7(), "aide-codex-models-"));
45138
+ const directory = await mkdtemp7(join17(tmpdir7(), "aide-codex-models-"));
44053
45139
  try {
44054
45140
  const { stdout } = await execFileAsync2(
44055
45141
  executable,
@@ -44059,12 +45145,12 @@ var CodexAppServer = class {
44059
45145
  maxBuffer: 16 * 1024 * 1024
44060
45146
  }
44061
45147
  );
44062
- const catalogPath = join16(directory, "models.json");
44063
- await writeFile8(catalogPath, stdout, "utf8");
45148
+ const catalogPath = join17(directory, "models.json");
45149
+ await writeFile9(catalogPath, stdout, "utf8");
44064
45150
  this.modelCatalogDirectory = directory;
44065
45151
  return catalogPath;
44066
45152
  } catch (error) {
44067
- await rm12(directory, { recursive: true, force: true }).catch(
45153
+ await rm13(directory, { recursive: true, force: true }).catch(
44068
45154
  () => void 0
44069
45155
  );
44070
45156
  throw error;
@@ -44075,7 +45161,7 @@ var CodexAppServer = class {
44075
45161
  if (this.modelCatalogDirectory === directory) {
44076
45162
  this.modelCatalogDirectory = void 0;
44077
45163
  }
44078
- await rm12(directory, { recursive: true, force: true }).catch(
45164
+ await rm13(directory, { recursive: true, force: true }).catch(
44079
45165
  () => void 0
44080
45166
  );
44081
45167
  }
@@ -44115,8 +45201,8 @@ var CodexAppServer = class {
44115
45201
  }
44116
45202
  requestDirect(method, params) {
44117
45203
  const id2 = this.nextId++;
44118
- return new Promise((resolve8, reject) => {
44119
- this.pending.set(id2, { resolve: resolve8, reject });
45204
+ return new Promise((resolve9, reject) => {
45205
+ this.pending.set(id2, { resolve: resolve9, reject });
44120
45206
  this.write({ id: id2, method, params });
44121
45207
  });
44122
45208
  }
@@ -44279,8 +45365,8 @@ var CodexAdapter = class {
44279
45365
  let lastUsageSignature = "";
44280
45366
  const pendingQuestions = /* @__PURE__ */ new Map();
44281
45367
  let resolveCompletion;
44282
- const completion = new Promise((resolve8) => {
44283
- resolveCompletion = resolve8;
45368
+ const completion = new Promise((resolve9) => {
45369
+ resolveCompletion = resolve9;
44284
45370
  });
44285
45371
  const unsubscribe = this.server.listen(nativeId, (message) => {
44286
45372
  void (async () => {
@@ -44490,13 +45576,13 @@ var CodexAdapter = class {
44490
45576
  };
44491
45577
 
44492
45578
  // src/runs/opencode-adapter.ts
44493
- import { dirname as dirname9 } from "node:path";
45579
+ import { dirname as dirname10 } from "node:path";
44494
45580
  import { pathToFileURL } from "node:url";
44495
45581
 
44496
45582
  // ../../node_modules/@opencode-ai/sdk/dist/v2/gen/core/serverSentEvents.gen.js
44497
45583
  var createSseClient = ({ onRequest, onSseError, onSseEvent, responseTransformer, responseValidator, sseDefaultRetryDelay, sseMaxRetryAttempts, sseMaxRetryDelay, sseSleepFn, url, ...options }) => {
44498
45584
  let lastEventId;
44499
- const sleep = sseSleepFn ?? ((ms) => new Promise((resolve8) => setTimeout(resolve8, ms)));
45585
+ const sleep = sseSleepFn ?? ((ms) => new Promise((resolve9) => setTimeout(resolve9, ms)));
44500
45586
  const createStream = async function* () {
44501
45587
  let retryDelay = sseDefaultRetryDelay ?? 3e3;
44502
45588
  let attempt = 0;
@@ -49948,7 +51034,7 @@ async function createOpencodeServer(options) {
49948
51034
  });
49949
51035
  let clear = () => {
49950
51036
  };
49951
- const url = await new Promise((resolve8, reject) => {
51037
+ const url = await new Promise((resolve9, reject) => {
49952
51038
  const id2 = setTimeout(() => {
49953
51039
  clear();
49954
51040
  stop(proc);
@@ -49973,7 +51059,7 @@ async function createOpencodeServer(options) {
49973
51059
  }
49974
51060
  clearTimeout(id2);
49975
51061
  resolved = true;
49976
- resolve8(match[1]);
51062
+ resolve9(match[1]);
49977
51063
  return;
49978
51064
  }
49979
51065
  }
@@ -50138,11 +51224,11 @@ function responseItems(value) {
50138
51224
  }
50139
51225
  function waitForPoll(signal) {
50140
51226
  if (signal.aborted) return Promise.resolve();
50141
- return new Promise((resolve8) => {
51227
+ return new Promise((resolve9) => {
50142
51228
  const finish = () => {
50143
51229
  clearTimeout(timer);
50144
51230
  signal.removeEventListener("abort", finish);
50145
- resolve8();
51231
+ resolve9();
50146
51232
  };
50147
51233
  const timer = setTimeout(finish, QUESTION_RECONCILIATION_INTERVAL_MS);
50148
51234
  timer.unref();
@@ -50171,7 +51257,7 @@ var OpenCodeAdapter = class {
50171
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."
50172
51258
  );
50173
51259
  }
50174
- prependPathDirectory(dirname9(executable));
51260
+ prependPathDirectory(dirname10(executable));
50175
51261
  this.runtime = await createOpencode({ port: 0 });
50176
51262
  }
50177
51263
  return this.runtime.client;
@@ -50795,7 +51881,7 @@ var RunManager = class {
50795
51881
  5
50796
51882
  );
50797
51883
  await this.completeCommand(command3.id, "SUCCEEDED");
50798
- await rm13(join17(dirname10(configPath()), "runs", run.id, "attachments"), {
51884
+ await rm14(join18(dirname11(configPath()), "runs", run.id, "attachments"), {
50799
51885
  recursive: true,
50800
51886
  force: true
50801
51887
  }).catch(() => void 0);
@@ -50977,7 +52063,7 @@ var RunManager = class {
50977
52063
  this.active.delete(run.id);
50978
52064
  this.interruptionRequests.delete(run.id);
50979
52065
  this.executingCommands.delete(command3.id);
50980
- await rm13(join17(dirname10(configPath()), "runs", run.id, "attachments"), {
52066
+ await rm14(join18(dirname11(configPath()), "runs", run.id, "attachments"), {
50981
52067
  recursive: true,
50982
52068
  force: true
50983
52069
  }).catch(() => void 0);
@@ -51205,11 +52291,11 @@ var RunManager = class {
51205
52291
  }
51206
52292
  async stageAttachments(runId, attachments) {
51207
52293
  if (!attachments.length) return [];
51208
- const directory = join17(dirname10(configPath()), "runs", runId, "attachments");
51209
- await mkdir6(directory, { recursive: true, mode: 448 });
52294
+ const directory = join18(dirname11(configPath()), "runs", runId, "attachments");
52295
+ await mkdir7(directory, { recursive: true, mode: 448 });
51210
52296
  return Promise.all(
51211
52297
  attachments.map(async (attachment) => {
51212
- const path = join17(
52298
+ const path = join18(
51213
52299
  directory,
51214
52300
  `${attachment.id}-${safeFilename(attachment.filename)}`
51215
52301
  );
@@ -51301,7 +52387,7 @@ var RunManager = class {
51301
52387
  return await operation();
51302
52388
  } catch (error) {
51303
52389
  if (this.stopped || attempt >= attempts) throw error;
51304
- await new Promise((resolve8) => setTimeout(resolve8, delay));
52390
+ await new Promise((resolve9) => setTimeout(resolve9, delay));
51305
52391
  delay = Math.min(delay * 2, 3e4);
51306
52392
  }
51307
52393
  }
@@ -51581,9 +52667,9 @@ async function runAgentSession(config, signal, onUnhealthy) {
51581
52667
  }
51582
52668
  }
51583
52669
  );
51584
- await new Promise((resolve8) => {
51585
- if (signal.aborted) resolve8();
51586
- 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 });
51587
52673
  });
51588
52674
  if (heartbeatTimer) clearTimeout(heartbeatTimer);
51589
52675
  if (jobReconciliationTimer) clearTimeout(jobReconciliationTimer);
@@ -51650,7 +52736,7 @@ var defaultDependencies = {
51650
52736
  inventory: collectInventory,
51651
52737
  load: loadConfig,
51652
52738
  save: saveConfig,
51653
- wait: (milliseconds, signal) => new Promise((resolve8, reject) => {
52739
+ wait: (milliseconds, signal) => new Promise((resolve9, reject) => {
51654
52740
  if (signal.aborted) {
51655
52741
  reject(new Error("Development agent startup was cancelled"));
51656
52742
  return;
@@ -51661,7 +52747,7 @@ var defaultDependencies = {
51661
52747
  };
51662
52748
  const timer = setTimeout(() => {
51663
52749
  signal.removeEventListener("abort", onAbort);
51664
- resolve8();
52750
+ resolve9();
51665
52751
  }, milliseconds);
51666
52752
  signal.addEventListener("abort", onAbort, { once: true });
51667
52753
  })
@@ -51905,7 +52991,7 @@ async function unenroll() {
51905
52991
  config = await loadConfig(path);
51906
52992
  } catch {
51907
52993
  }
51908
- await rm14(path, { force: true });
52994
+ await rm15(path, { force: true });
51909
52995
  console.log(
51910
52996
  config ? `Removed the enrollment for ${config.name} (${config.agentId}) from ${path}` : `Removed ${path}`
51911
52997
  );