@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.
- package/dist/control-agent.js +1383 -297
- package/package.json +1 -1
package/dist/control-agent.js
CHANGED
|
@@ -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:
|
|
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 =
|
|
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:
|
|
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 =
|
|
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(
|
|
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
|
-
|
|
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((
|
|
3875
|
+
const step = (i) => new Promise((resolve9, reject) => {
|
|
3876
3876
|
if (i === pathEnv.length)
|
|
3877
|
-
return opt.all && found.length ?
|
|
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
|
-
|
|
3882
|
+
resolve9(subStep(p4, i, 0));
|
|
3883
3883
|
});
|
|
3884
|
-
const subStep = (p4, i, ii) => new Promise((
|
|
3884
|
+
const subStep = (p4, i, ii) => new Promise((resolve9, reject) => {
|
|
3885
3885
|
if (ii === pathExt.length)
|
|
3886
|
-
return
|
|
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
|
|
3893
|
+
return resolve9(p4 + ext);
|
|
3894
3894
|
}
|
|
3895
|
-
return
|
|
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
|
|
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
|
-
(
|
|
4502
|
-
|
|
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((
|
|
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((
|
|
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((
|
|
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
|
-
|
|
6218
|
-
|
|
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 :
|
|
6806
|
-
const previousPath = payload.previousPath === null || payload.previousPath === void 0 ? null :
|
|
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((
|
|
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
|
-
|
|
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((
|
|
8637
|
-
const timer = setTimeout(
|
|
8833
|
+
await new Promise((resolve9) => {
|
|
8834
|
+
const timer = setTimeout(resolve9, TERMINATE_GRACE_MS);
|
|
8638
8835
|
timer.unref();
|
|
8639
|
-
if (signal.aborted)
|
|
8640
|
-
else signal.addEventListener("abort", () =>
|
|
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((
|
|
8893
|
+
await new Promise((resolve9) => {
|
|
8697
8894
|
const onAbort = () => {
|
|
8698
8895
|
clearTimeout(retryTimer);
|
|
8699
|
-
|
|
8896
|
+
resolve9();
|
|
8700
8897
|
};
|
|
8701
8898
|
const retryTimer = setTimeout(() => {
|
|
8702
8899
|
signal.removeEventListener("abort", onAbort);
|
|
8703
|
-
|
|
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((
|
|
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
|
-
() =>
|
|
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((
|
|
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
|
-
() =>
|
|
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((
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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(
|
|
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
|
|
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
|
|
15028
|
-
|
|
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
|
-
|
|
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
|
-
|
|
15755
|
+
git4(
|
|
15075
15756
|
entry.folder,
|
|
15076
15757
|
["symbolic-ref", "--short", "-q", "HEAD"],
|
|
15077
15758
|
entry.timeoutMs,
|
|
15078
15759
|
signal
|
|
15079
15760
|
),
|
|
15080
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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(
|
|
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 =
|
|
15203
|
-
await
|
|
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
|
|
15892
|
+
return realpath9(result.stdout.trim());
|
|
15212
15893
|
}
|
|
15213
15894
|
async function origin(folder, timeoutMs, signal) {
|
|
15214
|
-
const result =
|
|
15215
|
-
await
|
|
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
|
|
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
|
|
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
|
|
15949
|
+
const folder = await realpath9(folderValue2);
|
|
15269
15950
|
const [gitDir, branchResult, headResult, statusResult, rebasing] = await Promise.all([
|
|
15270
15951
|
gitDirectory(folder, timeoutMs, signal),
|
|
15271
|
-
|
|
15952
|
+
git4(
|
|
15272
15953
|
folder,
|
|
15273
15954
|
["symbolic-ref", "--short", "-q", "HEAD"],
|
|
15274
15955
|
timeoutMs,
|
|
15275
15956
|
signal
|
|
15276
15957
|
),
|
|
15277
|
-
|
|
15278
|
-
|
|
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
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
|
15369
|
-
const list =
|
|
15370
|
-
await
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
16156
|
+
git4(
|
|
15476
16157
|
folder,
|
|
15477
16158
|
["status", "--porcelain=v1", "-z", "--untracked-files=all"],
|
|
15478
16159
|
timeoutMs,
|
|
15479
16160
|
signal
|
|
15480
16161
|
),
|
|
15481
|
-
|
|
15482
|
-
|
|
16162
|
+
git4(folder, ["diff", "--cached", "--numstat", "-z"], timeoutMs, signal),
|
|
16163
|
+
git4(folder, ["diff", "--numstat", "-z"], timeoutMs, signal)
|
|
15483
16164
|
]);
|
|
15484
|
-
|
|
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
|
-
|
|
15545
|
-
|
|
16225
|
+
git4(folder, ["diff", "--name-status", "-z", range], timeoutMs, signal),
|
|
16226
|
+
git4(folder, ["diff", "--numstat", "-z", range], timeoutMs, signal)
|
|
15546
16227
|
]);
|
|
15547
|
-
|
|
15548
|
-
|
|
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 =
|
|
15563
|
-
await
|
|
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 =
|
|
15581
|
-
await
|
|
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
|
-
|
|
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
|
|
15633
|
-
await
|
|
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
|
-
|
|
16329
|
+
git4(
|
|
15649
16330
|
folder,
|
|
15650
16331
|
["merge-base", "--is-ancestor", base, commitSha],
|
|
15651
16332
|
timeoutMs,
|
|
15652
16333
|
signal
|
|
15653
16334
|
),
|
|
15654
|
-
|
|
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
|
|
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
|
|
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 =
|
|
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
|
|
15784
|
-
const difference =
|
|
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
|
-
|
|
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 =
|
|
15868
|
-
await
|
|
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
|
|
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
|
|
16603
|
+
result = await git4(folder, args, timeoutMs, signal);
|
|
15923
16604
|
}
|
|
15924
|
-
|
|
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(
|
|
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
|
|
16021
|
-
const difference =
|
|
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 =
|
|
16027
|
-
await
|
|
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(
|
|
16039
|
-
uploadPath =
|
|
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
|
|
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) =>
|
|
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
|
|
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
|
|
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
|
-
|
|
16888
|
+
requireSuccess4(staged, "Could not inspect staged changes");
|
|
16208
16889
|
let signed = input.signed;
|
|
16209
16890
|
if (signed === null) {
|
|
16210
|
-
const configured = await
|
|
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
|
|
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
|
|
16277
|
-
await
|
|
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
|
|
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
|
-
|
|
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 =
|
|
16295
|
-
await
|
|
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
|
|
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
|
|
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" ?
|
|
16394
|
-
|
|
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
|
-
|
|
16440
|
-
|
|
16441
|
-
|
|
16442
|
-
|
|
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
|
-
|
|
16447
|
-
|
|
16448
|
-
|
|
16449
|
-
|
|
16450
|
-
|
|
16451
|
-
|
|
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
|
-
|
|
16463
|
-
|
|
16464
|
-
|
|
16465
|
-
|
|
16466
|
-
|
|
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
|
-
}
|
|
16470
|
-
|
|
16471
|
-
|
|
16472
|
-
|
|
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
|
-
|
|
16520
|
-
await
|
|
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
|
-
|
|
16530
|
-
await
|
|
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
|
-
|
|
16566
|
-
await
|
|
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 =
|
|
16578
|
-
await
|
|
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
|
-
|
|
16595
|
-
await
|
|
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 =
|
|
16634
|
-
|
|
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
|
-
|
|
16653
|
-
|
|
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
|
|
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 =
|
|
16723
|
-
await
|
|
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
|
|
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:
|
|
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
|
-
`${
|
|
17486
|
+
`${cleanError4(switched.stderr || "Could not check out the moved branch")}${stashed ? ". The destination stash was preserved." : ""}`
|
|
16753
17487
|
);
|
|
16754
17488
|
}
|
|
16755
17489
|
}
|
|
16756
|
-
|
|
16757
|
-
await
|
|
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
|
|
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
|
-
|
|
16820
|
-
await
|
|
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
|
|
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
|
-
|
|
16858
|
-
await
|
|
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
|
-
|
|
17685
|
+
requireSuccess4(remote, `Could not inspect origin/${branch}`);
|
|
16868
17686
|
}
|
|
16869
17687
|
}
|
|
16870
|
-
|
|
16871
|
-
await
|
|
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
|
-
|
|
16881
|
-
await
|
|
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
|
|
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
|
|
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) =>
|
|
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
|
-
|
|
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
|
|
17783
|
+
const remoteBase = `refs/remotes/origin/${input.baseBranch}`;
|
|
17784
|
+
const isCurrent = await git4(
|
|
16941
17785
|
folder,
|
|
16942
|
-
["
|
|
17786
|
+
["merge-base", "--is-ancestor", remoteBase, "HEAD"],
|
|
16943
17787
|
timeoutMs,
|
|
16944
17788
|
signal
|
|
16945
17789
|
);
|
|
16946
|
-
if (
|
|
16947
|
-
|
|
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 (
|
|
16955
|
-
|
|
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(
|
|
17867
|
+
throw new Error(cleanError4(rebase.stderr || "Rebase failed"));
|
|
16958
17868
|
}
|
|
16959
|
-
|
|
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
|
|
17894
|
+
const remoteBase = `refs/remotes/origin/${input.baseBranch}`;
|
|
17895
|
+
const isCurrent = await git4(
|
|
16973
17896
|
folder,
|
|
16974
|
-
["
|
|
17897
|
+
["merge-base", "--is-ancestor", remoteBase, "HEAD"],
|
|
16975
17898
|
timeoutMs,
|
|
16976
17899
|
signal
|
|
16977
17900
|
);
|
|
16978
|
-
if (
|
|
16979
|
-
|
|
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 (
|
|
16987
|
-
|
|
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
|
-
|
|
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
|
-
|
|
17037
|
-
|
|
17038
|
-
|
|
17039
|
-
|
|
17040
|
-
|
|
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) =>
|
|
17050
|
-
const
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
17254
|
-
|
|
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
|
-
|
|
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((
|
|
17332
|
-
release2 =
|
|
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((
|
|
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
|
|
17584
|
-
import { dirname as
|
|
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
|
|
17592
|
-
readFile as
|
|
18677
|
+
mkdir as mkdir6,
|
|
18678
|
+
readFile as readFile10,
|
|
17593
18679
|
rename as rename4,
|
|
17594
|
-
rm as
|
|
17595
|
-
writeFile as
|
|
18680
|
+
rm as rm11,
|
|
18681
|
+
writeFile as writeFile8
|
|
17596
18682
|
} from "node:fs/promises";
|
|
17597
|
-
import { dirname as
|
|
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
|
|
18702
|
+
return join15(dirname9(configPath()), "runs", this.runId);
|
|
17617
18703
|
}
|
|
17618
18704
|
get eventsPath() {
|
|
17619
|
-
return
|
|
18705
|
+
return join15(this.directory, "events.jsonl");
|
|
17620
18706
|
}
|
|
17621
18707
|
get statePath() {
|
|
17622
|
-
return
|
|
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
|
|
18720
|
+
await mkdir6(this.directory, { recursive: true, mode: 448 });
|
|
17635
18721
|
try {
|
|
17636
|
-
const state = JSON.parse(await
|
|
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
|
|
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
|
|
18809
|
+
await writeFile8(temporary, contents, { mode: 384 });
|
|
17724
18810
|
await rename4(temporary, this.statePath);
|
|
17725
18811
|
} catch (error) {
|
|
17726
|
-
await
|
|
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: () =>
|
|
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
|
|
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
|
-
|
|
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((
|
|
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((
|
|
43753
|
-
pendingQuestions.set(requestId, { input: toolInput, resolve:
|
|
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
|
|
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
|
|
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((
|
|
44010
|
-
child.once("spawn",
|
|
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(
|
|
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 =
|
|
44063
|
-
await
|
|
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
|
|
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
|
|
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((
|
|
44119
|
-
this.pending.set(id2, { resolve:
|
|
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((
|
|
44283
|
-
resolveCompletion =
|
|
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
|
|
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((
|
|
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((
|
|
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
|
-
|
|
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((
|
|
51227
|
+
return new Promise((resolve9) => {
|
|
50142
51228
|
const finish = () => {
|
|
50143
51229
|
clearTimeout(timer);
|
|
50144
51230
|
signal.removeEventListener("abort", finish);
|
|
50145
|
-
|
|
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(
|
|
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
|
|
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
|
|
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 =
|
|
51209
|
-
await
|
|
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 =
|
|
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((
|
|
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((
|
|
51585
|
-
if (signal.aborted)
|
|
51586
|
-
else signal.addEventListener("abort", () =>
|
|
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((
|
|
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
|
-
|
|
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
|
|
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
|
);
|