@ai-development-environment/control-agent 0.0.89 → 0.0.91
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 +1419 -304
- 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,
|
|
@@ -6170,10 +6172,21 @@ var WORKTREE_OPERATIONS = [
|
|
|
6170
6172
|
"PULL",
|
|
6171
6173
|
"PUSH",
|
|
6172
6174
|
"RESET",
|
|
6175
|
+
"CLEAR_LOCK",
|
|
6173
6176
|
"STASH_ALL",
|
|
6174
6177
|
"STAGE_ALL",
|
|
6175
6178
|
"UNSTAGE_ALL"
|
|
6176
6179
|
];
|
|
6180
|
+
var WORKTREE_PREPARATION_KINDS = [
|
|
6181
|
+
"WRITE",
|
|
6182
|
+
"DELETE",
|
|
6183
|
+
"ASSUME_UNCHANGED"
|
|
6184
|
+
];
|
|
6185
|
+
var WORKTREE_PREPARATION_ACTIONS = [
|
|
6186
|
+
"INSPECT",
|
|
6187
|
+
"APPLY",
|
|
6188
|
+
"UNDO"
|
|
6189
|
+
];
|
|
6177
6190
|
function validGitBranchName(value) {
|
|
6178
6191
|
if (!value || value.length > 255 || value === "@" || value.startsWith("-"))
|
|
6179
6192
|
return false;
|
|
@@ -6214,11 +6227,74 @@ function stashOid2(value, name) {
|
|
|
6214
6227
|
}
|
|
6215
6228
|
function safeRelativePath(value, name) {
|
|
6216
6229
|
const path = stringValue4(value, name).replaceAll("\\", "/");
|
|
6217
|
-
|
|
6218
|
-
|
|
6230
|
+
const parts = path.split("/");
|
|
6231
|
+
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")) {
|
|
6232
|
+
throw new Error(`${name} must be an exact file inside the worktree`);
|
|
6233
|
+
}
|
|
6234
|
+
return path;
|
|
6235
|
+
}
|
|
6236
|
+
function safePreparationPath(value, name) {
|
|
6237
|
+
const path = safeRelativePath(value, name);
|
|
6238
|
+
if (/[*?[\]]/.test(path)) {
|
|
6239
|
+
throw new Error(`${name} must be an exact file inside the worktree`);
|
|
6219
6240
|
}
|
|
6220
6241
|
return path;
|
|
6221
6242
|
}
|
|
6243
|
+
function safeDiffPath(value, name) {
|
|
6244
|
+
try {
|
|
6245
|
+
return safeRelativePath(value, name);
|
|
6246
|
+
} catch {
|
|
6247
|
+
throw new Error(`${name} must stay within the worktree`);
|
|
6248
|
+
}
|
|
6249
|
+
}
|
|
6250
|
+
function preparationDefinitions(value, name) {
|
|
6251
|
+
if (!Array.isArray(value) || value.length > 500) {
|
|
6252
|
+
throw new Error(`${name} must be an array with at most 500 items`);
|
|
6253
|
+
}
|
|
6254
|
+
const definitions = value.map((entry, index) => {
|
|
6255
|
+
const item = objectValue4(entry, `${name}[${index}]`);
|
|
6256
|
+
const allowed = /* @__PURE__ */ new Set([
|
|
6257
|
+
"id",
|
|
6258
|
+
"kind",
|
|
6259
|
+
"path",
|
|
6260
|
+
"contentBase64",
|
|
6261
|
+
"definitionHash"
|
|
6262
|
+
]);
|
|
6263
|
+
const unexpected = Object.keys(item).find((key) => !allowed.has(key));
|
|
6264
|
+
if (unexpected) {
|
|
6265
|
+
throw new Error(`Unexpected ${name}[${index}] field: ${unexpected}`);
|
|
6266
|
+
}
|
|
6267
|
+
if (typeof item.kind !== "string" || !WORKTREE_PREPARATION_KINDS.includes(item.kind)) {
|
|
6268
|
+
throw new Error(`${name}[${index}].kind is invalid`);
|
|
6269
|
+
}
|
|
6270
|
+
const contentBase64 = item.contentBase64 === null || item.contentBase64 === void 0 ? null : typeof item.contentBase64 === "string" ? item.contentBase64 : (() => {
|
|
6271
|
+
throw new Error(
|
|
6272
|
+
`${name}[${index}].contentBase64 must be a string`
|
|
6273
|
+
);
|
|
6274
|
+
})();
|
|
6275
|
+
if (item.kind === "WRITE" && contentBase64 === null) {
|
|
6276
|
+
throw new Error(`${name}[${index}].contentBase64 is required`);
|
|
6277
|
+
}
|
|
6278
|
+
if (item.kind !== "WRITE" && contentBase64 !== null) {
|
|
6279
|
+
throw new Error(`${name}[${index}].contentBase64 is not allowed`);
|
|
6280
|
+
}
|
|
6281
|
+
return {
|
|
6282
|
+
id: stringValue4(item.id, `${name}[${index}].id`),
|
|
6283
|
+
kind: item.kind,
|
|
6284
|
+
path: safePreparationPath(item.path, `${name}[${index}].path`),
|
|
6285
|
+
contentBase64,
|
|
6286
|
+
definitionHash: stringValue4(
|
|
6287
|
+
item.definitionHash,
|
|
6288
|
+
`${name}[${index}].definitionHash`
|
|
6289
|
+
)
|
|
6290
|
+
};
|
|
6291
|
+
});
|
|
6292
|
+
const paths = definitions.map((item) => item.path);
|
|
6293
|
+
if (new Set(paths).size !== paths.length) {
|
|
6294
|
+
throw new Error(`${name} paths must be unique`);
|
|
6295
|
+
}
|
|
6296
|
+
return definitions;
|
|
6297
|
+
}
|
|
6222
6298
|
function worktreeBranchJobPayload(value) {
|
|
6223
6299
|
const payload = objectValue4(value, "worktree branch payload");
|
|
6224
6300
|
const allowed = /* @__PURE__ */ new Set([
|
|
@@ -6231,7 +6307,8 @@ function worktreeBranchJobPayload(value) {
|
|
|
6231
6307
|
"action",
|
|
6232
6308
|
"mode",
|
|
6233
6309
|
"candidates",
|
|
6234
|
-
"stashOnFailure"
|
|
6310
|
+
"stashOnFailure",
|
|
6311
|
+
"preparations"
|
|
6235
6312
|
]);
|
|
6236
6313
|
const unexpected = Object.keys(payload).find((key) => !allowed.has(key));
|
|
6237
6314
|
if (unexpected) {
|
|
@@ -6297,7 +6374,11 @@ function worktreeBranchJobPayload(value) {
|
|
|
6297
6374
|
action: payload.action,
|
|
6298
6375
|
mode: payload.mode,
|
|
6299
6376
|
candidates,
|
|
6300
|
-
stashOnFailure: payload.stashOnFailure
|
|
6377
|
+
stashOnFailure: payload.stashOnFailure,
|
|
6378
|
+
preparations: preparationDefinitions(
|
|
6379
|
+
payload.preparations ?? [],
|
|
6380
|
+
"worktree branch payload.preparations"
|
|
6381
|
+
)
|
|
6301
6382
|
};
|
|
6302
6383
|
}
|
|
6303
6384
|
function worktreeMovePushJobPayload(value) {
|
|
@@ -6357,7 +6438,8 @@ function worktreeMoveCheckoutJobPayload(value) {
|
|
|
6357
6438
|
"expectedHeadSha",
|
|
6358
6439
|
"baseBranch",
|
|
6359
6440
|
"mode",
|
|
6360
|
-
"stashOnFailure"
|
|
6441
|
+
"stashOnFailure",
|
|
6442
|
+
"preparations"
|
|
6361
6443
|
]);
|
|
6362
6444
|
const unexpected = Object.keys(payload).find((key) => !allowed.has(key));
|
|
6363
6445
|
if (unexpected) {
|
|
@@ -6418,7 +6500,11 @@ function worktreeMoveCheckoutJobPayload(value) {
|
|
|
6418
6500
|
"worktree move checkout payload.baseBranch"
|
|
6419
6501
|
),
|
|
6420
6502
|
mode: payload.mode,
|
|
6421
|
-
stashOnFailure: payload.stashOnFailure
|
|
6503
|
+
stashOnFailure: payload.stashOnFailure,
|
|
6504
|
+
preparations: preparationDefinitions(
|
|
6505
|
+
payload.preparations ?? [],
|
|
6506
|
+
"worktree move checkout payload.preparations"
|
|
6507
|
+
)
|
|
6422
6508
|
};
|
|
6423
6509
|
}
|
|
6424
6510
|
function worktreeDeleteJobPayload(value) {
|
|
@@ -6560,7 +6646,9 @@ function worktreeJobPayload(value) {
|
|
|
6560
6646
|
"expectedOrigin",
|
|
6561
6647
|
"baseBranch",
|
|
6562
6648
|
"operation",
|
|
6563
|
-
"editorVariant"
|
|
6649
|
+
"editorVariant",
|
|
6650
|
+
"forcePreparations",
|
|
6651
|
+
"preparations"
|
|
6564
6652
|
]);
|
|
6565
6653
|
const unexpected = Object.keys(payload).find((key) => !allowed.has(key));
|
|
6566
6654
|
if (unexpected)
|
|
@@ -6573,6 +6661,9 @@ function worktreeJobPayload(value) {
|
|
|
6573
6661
|
if (editorVariant !== void 0 && !["CODE", "CODE_INSIDERS", "NONE"].includes(String(editorVariant))) {
|
|
6574
6662
|
throw new Error("worktree payload.editorVariant is invalid");
|
|
6575
6663
|
}
|
|
6664
|
+
if (payload.forcePreparations !== void 0 && typeof payload.forcePreparations !== "boolean") {
|
|
6665
|
+
throw new Error("worktree payload.forcePreparations must be a boolean");
|
|
6666
|
+
}
|
|
6576
6667
|
return {
|
|
6577
6668
|
codebaseId: stringValue4(payload.codebaseId, "worktree payload.codebaseId"),
|
|
6578
6669
|
folder: stringValue4(payload.folder, "worktree payload.folder"),
|
|
@@ -6589,7 +6680,12 @@ function worktreeJobPayload(value) {
|
|
|
6589
6680
|
"worktree payload.baseBranch"
|
|
6590
6681
|
),
|
|
6591
6682
|
...operation === void 0 ? {} : { operation },
|
|
6592
|
-
...editorVariant === void 0 ? {} : { editorVariant }
|
|
6683
|
+
...editorVariant === void 0 ? {} : { editorVariant },
|
|
6684
|
+
forcePreparations: payload.forcePreparations === true,
|
|
6685
|
+
preparations: preparationDefinitions(
|
|
6686
|
+
payload.preparations ?? [],
|
|
6687
|
+
"worktree payload.preparations"
|
|
6688
|
+
)
|
|
6593
6689
|
};
|
|
6594
6690
|
}
|
|
6595
6691
|
function worktreeAutoSyncJobPayload(value) {
|
|
@@ -6601,7 +6697,9 @@ function worktreeAutoSyncJobPayload(value) {
|
|
|
6601
6697
|
"expectedOrigin",
|
|
6602
6698
|
"expectedBranch",
|
|
6603
6699
|
"baseBranch",
|
|
6604
|
-
"phase"
|
|
6700
|
+
"phase",
|
|
6701
|
+
"forcePreparations",
|
|
6702
|
+
"preparations"
|
|
6605
6703
|
]);
|
|
6606
6704
|
const unexpected = Object.keys(payload).find((key) => !allowed.has(key));
|
|
6607
6705
|
if (unexpected) {
|
|
@@ -6612,6 +6710,11 @@ function worktreeAutoSyncJobPayload(value) {
|
|
|
6612
6710
|
if (payload.phase !== "SYNC" && payload.phase !== "FINALIZE") {
|
|
6613
6711
|
throw new Error("worktree auto sync payload.phase is invalid");
|
|
6614
6712
|
}
|
|
6713
|
+
if (payload.forcePreparations !== void 0 && typeof payload.forcePreparations !== "boolean") {
|
|
6714
|
+
throw new Error(
|
|
6715
|
+
"worktree auto sync payload.forcePreparations must be a boolean"
|
|
6716
|
+
);
|
|
6717
|
+
}
|
|
6615
6718
|
return {
|
|
6616
6719
|
codebaseId: stringValue4(
|
|
6617
6720
|
payload.codebaseId,
|
|
@@ -6634,9 +6737,104 @@ function worktreeAutoSyncJobPayload(value) {
|
|
|
6634
6737
|
payload.baseBranch,
|
|
6635
6738
|
"worktree auto sync payload.baseBranch"
|
|
6636
6739
|
),
|
|
6637
|
-
phase: payload.phase
|
|
6740
|
+
phase: payload.phase,
|
|
6741
|
+
forcePreparations: payload.forcePreparations === true,
|
|
6742
|
+
preparations: preparationDefinitions(
|
|
6743
|
+
payload.preparations ?? [],
|
|
6744
|
+
"worktree auto sync payload.preparations"
|
|
6745
|
+
)
|
|
6638
6746
|
};
|
|
6639
6747
|
}
|
|
6748
|
+
function worktreePreparationJobPayload(value) {
|
|
6749
|
+
const payload = objectValue4(value, "worktree preparation payload");
|
|
6750
|
+
const batched = payload.worktrees !== void 0;
|
|
6751
|
+
const allowed = new Set(
|
|
6752
|
+
batched ? ["codebaseId", "expectedOrigin", "action", "preparations", "worktrees"] : [
|
|
6753
|
+
"codebaseId",
|
|
6754
|
+
"folder",
|
|
6755
|
+
"gitDirectory",
|
|
6756
|
+
"expectedOrigin",
|
|
6757
|
+
"action",
|
|
6758
|
+
"preparations"
|
|
6759
|
+
]
|
|
6760
|
+
);
|
|
6761
|
+
const unexpected = Object.keys(payload).find((key) => !allowed.has(key));
|
|
6762
|
+
if (unexpected) {
|
|
6763
|
+
throw new Error(
|
|
6764
|
+
`Unexpected worktree preparation payload field: ${unexpected}`
|
|
6765
|
+
);
|
|
6766
|
+
}
|
|
6767
|
+
if (typeof payload.action !== "string" || !WORKTREE_PREPARATION_ACTIONS.includes(
|
|
6768
|
+
payload.action
|
|
6769
|
+
)) {
|
|
6770
|
+
throw new Error("worktree preparation payload.action is invalid");
|
|
6771
|
+
}
|
|
6772
|
+
const common = {
|
|
6773
|
+
codebaseId: stringValue4(
|
|
6774
|
+
payload.codebaseId,
|
|
6775
|
+
"worktree preparation payload.codebaseId"
|
|
6776
|
+
),
|
|
6777
|
+
expectedOrigin: stringValue4(
|
|
6778
|
+
payload.expectedOrigin,
|
|
6779
|
+
"worktree preparation payload.expectedOrigin"
|
|
6780
|
+
),
|
|
6781
|
+
action: payload.action,
|
|
6782
|
+
preparations: preparationDefinitions(
|
|
6783
|
+
payload.preparations,
|
|
6784
|
+
"worktree preparation payload.preparations"
|
|
6785
|
+
)
|
|
6786
|
+
};
|
|
6787
|
+
if (!batched) {
|
|
6788
|
+
return {
|
|
6789
|
+
...common,
|
|
6790
|
+
folder: stringValue4(
|
|
6791
|
+
payload.folder,
|
|
6792
|
+
"worktree preparation payload.folder"
|
|
6793
|
+
),
|
|
6794
|
+
gitDirectory: stringValue4(
|
|
6795
|
+
payload.gitDirectory,
|
|
6796
|
+
"worktree preparation payload.gitDirectory"
|
|
6797
|
+
)
|
|
6798
|
+
};
|
|
6799
|
+
}
|
|
6800
|
+
if (!Array.isArray(payload.worktrees) || payload.worktrees.length > 500) {
|
|
6801
|
+
throw new Error(
|
|
6802
|
+
"worktree preparation payload.worktrees must be an array with at most 500 items"
|
|
6803
|
+
);
|
|
6804
|
+
}
|
|
6805
|
+
const worktrees = payload.worktrees.map((value2, index) => {
|
|
6806
|
+
const target2 = objectValue4(
|
|
6807
|
+
value2,
|
|
6808
|
+
`worktree preparation payload.worktrees[${index}]`
|
|
6809
|
+
);
|
|
6810
|
+
const unexpectedTarget = Object.keys(target2).find(
|
|
6811
|
+
(key) => !["worktreeId", "folder", "gitDirectory"].includes(key)
|
|
6812
|
+
);
|
|
6813
|
+
if (unexpectedTarget) {
|
|
6814
|
+
throw new Error(
|
|
6815
|
+
`Unexpected worktree preparation payload.worktrees[${index}] field: ${unexpectedTarget}`
|
|
6816
|
+
);
|
|
6817
|
+
}
|
|
6818
|
+
return {
|
|
6819
|
+
worktreeId: stringValue4(
|
|
6820
|
+
target2.worktreeId,
|
|
6821
|
+
`worktree preparation payload.worktrees[${index}].worktreeId`
|
|
6822
|
+
),
|
|
6823
|
+
folder: stringValue4(
|
|
6824
|
+
target2.folder,
|
|
6825
|
+
`worktree preparation payload.worktrees[${index}].folder`
|
|
6826
|
+
),
|
|
6827
|
+
gitDirectory: stringValue4(
|
|
6828
|
+
target2.gitDirectory,
|
|
6829
|
+
`worktree preparation payload.worktrees[${index}].gitDirectory`
|
|
6830
|
+
)
|
|
6831
|
+
};
|
|
6832
|
+
});
|
|
6833
|
+
if (new Set(worktrees.map(({ worktreeId }) => worktreeId)).size !== worktrees.length) {
|
|
6834
|
+
throw new Error("worktree preparation payload.worktreeIds must be unique");
|
|
6835
|
+
}
|
|
6836
|
+
return { ...common, worktrees };
|
|
6837
|
+
}
|
|
6640
6838
|
function worktreeGitInspectPayload(value) {
|
|
6641
6839
|
const payload = objectValue4(value, "worktree Git inspect payload");
|
|
6642
6840
|
const allowed = /* @__PURE__ */ new Set([
|
|
@@ -6802,8 +7000,8 @@ function worktreeDiffPayload(value) {
|
|
|
6802
7000
|
if (payload.side !== null && payload.side !== void 0 && payload.side !== "BEFORE" && payload.side !== "AFTER") {
|
|
6803
7001
|
throw new Error("worktree diff payload.side is invalid");
|
|
6804
7002
|
}
|
|
6805
|
-
const path = payload.path === null || payload.path === void 0 ? null :
|
|
6806
|
-
const previousPath = payload.previousPath === null || payload.previousPath === void 0 ? null :
|
|
7003
|
+
const path = payload.path === null || payload.path === void 0 ? null : safeDiffPath(payload.path, "worktree diff payload.path");
|
|
7004
|
+
const previousPath = payload.previousPath === null || payload.previousPath === void 0 ? null : safeDiffPath(
|
|
6807
7005
|
payload.previousPath,
|
|
6808
7006
|
"worktree diff payload.previousPath"
|
|
6809
7007
|
);
|
|
@@ -8449,7 +8647,7 @@ function captureCommand(options) {
|
|
|
8449
8647
|
outputTruncated: false
|
|
8450
8648
|
});
|
|
8451
8649
|
}
|
|
8452
|
-
return new Promise((
|
|
8650
|
+
return new Promise((resolve9, reject) => {
|
|
8453
8651
|
const stdoutChunks = [];
|
|
8454
8652
|
const stderrChunks = [];
|
|
8455
8653
|
let stdoutBytes = 0;
|
|
@@ -8545,7 +8743,7 @@ function captureCommand(options) {
|
|
|
8545
8743
|
clearTimeout(timeout);
|
|
8546
8744
|
if (killTimer) clearTimeout(killTimer);
|
|
8547
8745
|
options.signal.removeEventListener("abort", abort);
|
|
8548
|
-
|
|
8746
|
+
resolve9({
|
|
8549
8747
|
exitCode,
|
|
8550
8748
|
signal,
|
|
8551
8749
|
timedOut,
|
|
@@ -8633,11 +8831,11 @@ async function reapOrphanedCommandProcesses(agentId, signal = new AbortControlle
|
|
|
8633
8831
|
console.error(
|
|
8634
8832
|
`Terminating ${signalled.length} command process(es) left by a previous agent run.`
|
|
8635
8833
|
);
|
|
8636
|
-
await new Promise((
|
|
8637
|
-
const timer = setTimeout(
|
|
8834
|
+
await new Promise((resolve9) => {
|
|
8835
|
+
const timer = setTimeout(resolve9, TERMINATE_GRACE_MS);
|
|
8638
8836
|
timer.unref();
|
|
8639
|
-
if (signal.aborted)
|
|
8640
|
-
else signal.addEventListener("abort", () =>
|
|
8837
|
+
if (signal.aborted) resolve9();
|
|
8838
|
+
else signal.addEventListener("abort", () => resolve9(), { once: true });
|
|
8641
8839
|
});
|
|
8642
8840
|
for (const orphan of signalled) signalGroup(orphan.processGroup, "SIGKILL");
|
|
8643
8841
|
return signalled;
|
|
@@ -8693,14 +8891,14 @@ var runCommand = async (rawPayload, _timeoutMs, signal, _onLog, context) => {
|
|
|
8693
8891
|
`Could not append command output; retrying in ${delay}ms:`,
|
|
8694
8892
|
error instanceof Error ? error.message : error
|
|
8695
8893
|
);
|
|
8696
|
-
await new Promise((
|
|
8894
|
+
await new Promise((resolve9) => {
|
|
8697
8895
|
const onAbort = () => {
|
|
8698
8896
|
clearTimeout(retryTimer);
|
|
8699
|
-
|
|
8897
|
+
resolve9();
|
|
8700
8898
|
};
|
|
8701
8899
|
const retryTimer = setTimeout(() => {
|
|
8702
8900
|
signal.removeEventListener("abort", onAbort);
|
|
8703
|
-
|
|
8901
|
+
resolve9();
|
|
8704
8902
|
}, delay);
|
|
8705
8903
|
retryTimer.unref();
|
|
8706
8904
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
@@ -8738,7 +8936,7 @@ var runCommand = async (rawPayload, _timeoutMs, signal, _onLog, context) => {
|
|
|
8738
8936
|
}
|
|
8739
8937
|
};
|
|
8740
8938
|
try {
|
|
8741
|
-
return await new Promise((
|
|
8939
|
+
return await new Promise((resolve9, reject) => {
|
|
8742
8940
|
let cancelled = false;
|
|
8743
8941
|
let settled = false;
|
|
8744
8942
|
const child = spawn2(process.env.SHELL || "/bin/sh", ["-l", scriptPath], {
|
|
@@ -8805,7 +9003,7 @@ var runCommand = async (rawPayload, _timeoutMs, signal, _onLog, context) => {
|
|
|
8805
9003
|
signal.removeEventListener("abort", abort);
|
|
8806
9004
|
flush();
|
|
8807
9005
|
void uploadChain.then(
|
|
8808
|
-
() =>
|
|
9006
|
+
() => resolve9({
|
|
8809
9007
|
exitCode,
|
|
8810
9008
|
signal: closeSignal,
|
|
8811
9009
|
timedOut: false,
|
|
@@ -12624,7 +12822,7 @@ function prependPathDirectory(directory, env = process.env) {
|
|
|
12624
12822
|
// src/process-runner.ts
|
|
12625
12823
|
import { spawn as spawn5 } from "node:child_process";
|
|
12626
12824
|
async function runProcess(options) {
|
|
12627
|
-
return new Promise((
|
|
12825
|
+
return new Promise((resolve9, reject) => {
|
|
12628
12826
|
let sequence = 0;
|
|
12629
12827
|
let timedOut = false;
|
|
12630
12828
|
let cancelled = false;
|
|
@@ -12719,7 +12917,7 @@ async function runProcess(options) {
|
|
|
12719
12917
|
clearTimeout(timeout);
|
|
12720
12918
|
options.signal.removeEventListener("abort", abort);
|
|
12721
12919
|
void logChain.then(
|
|
12722
|
-
() =>
|
|
12920
|
+
() => resolve9({ exitCode, signal, timedOut, cancelled })
|
|
12723
12921
|
);
|
|
12724
12922
|
});
|
|
12725
12923
|
});
|
|
@@ -14158,6 +14356,20 @@ function rootPath(location) {
|
|
|
14158
14356
|
}
|
|
14159
14357
|
return path;
|
|
14160
14358
|
}
|
|
14359
|
+
function isContainedPath(base, candidate) {
|
|
14360
|
+
return candidate === base || candidate.startsWith(`${base}${sep6}`);
|
|
14361
|
+
}
|
|
14362
|
+
async function resolvedSkillRoot(location) {
|
|
14363
|
+
const root = rootPath(location);
|
|
14364
|
+
const resolvedRoot = await realpath6(root);
|
|
14365
|
+
if (location.scope === "PROJECT") {
|
|
14366
|
+
const resolvedProject = await realpath6(location.folder);
|
|
14367
|
+
if (!isContainedPath(resolvedProject, resolvedRoot)) {
|
|
14368
|
+
throw new Error("Project skill root resolves outside the project folder");
|
|
14369
|
+
}
|
|
14370
|
+
}
|
|
14371
|
+
return { root, resolvedRoot };
|
|
14372
|
+
}
|
|
14161
14373
|
function targetForFolder(targets, folder) {
|
|
14162
14374
|
return folder ? targets.find((target2) => resolve6(target2.folder) === resolve6(folder)) : void 0;
|
|
14163
14375
|
}
|
|
@@ -14198,14 +14410,15 @@ async function listPackageFiles(skillDirectory) {
|
|
|
14198
14410
|
await visit(skillDirectory);
|
|
14199
14411
|
return files;
|
|
14200
14412
|
}
|
|
14201
|
-
async function readPackage(directory) {
|
|
14413
|
+
async function readPackage(directory, resolvedRoot) {
|
|
14202
14414
|
const metadata = await lstat3(directory);
|
|
14203
|
-
|
|
14204
|
-
if (metadata.isSymbolicLink()) {
|
|
14205
|
-
resolvedDirectory = await realpath6(directory);
|
|
14206
|
-
} else if (!metadata.isDirectory()) {
|
|
14415
|
+
if (!metadata.isSymbolicLink() && !metadata.isDirectory()) {
|
|
14207
14416
|
throw new Error("Skill path is not a directory");
|
|
14208
14417
|
}
|
|
14418
|
+
const resolvedDirectory = await realpath6(directory);
|
|
14419
|
+
if (!isContainedPath(resolvedRoot, resolvedDirectory)) {
|
|
14420
|
+
throw new Error("Skill package resolves outside its configured root");
|
|
14421
|
+
}
|
|
14209
14422
|
const files = await listPackageFiles(resolvedDirectory);
|
|
14210
14423
|
const definition = files.find((file) => file.path === "SKILL.md");
|
|
14211
14424
|
if (!definition) throw new Error("Skill does not contain SKILL.md");
|
|
@@ -14245,6 +14458,15 @@ function consumersForRoot(configured, rootKind, scope) {
|
|
|
14245
14458
|
async function scanRoot2(location, configured, targets, warnings) {
|
|
14246
14459
|
const root = rootPath(location);
|
|
14247
14460
|
if (!await directoryExists(root)) return [];
|
|
14461
|
+
let resolvedRoot;
|
|
14462
|
+
try {
|
|
14463
|
+
resolvedRoot = (await resolvedSkillRoot(location)).resolvedRoot;
|
|
14464
|
+
} catch (error) {
|
|
14465
|
+
warnings.push(
|
|
14466
|
+
`${root}: ${error instanceof Error ? error.message : String(error)}`
|
|
14467
|
+
);
|
|
14468
|
+
return [];
|
|
14469
|
+
}
|
|
14248
14470
|
const consumers = consumersForRoot(
|
|
14249
14471
|
configured,
|
|
14250
14472
|
location.rootKind,
|
|
@@ -14257,7 +14479,7 @@ async function scanRoot2(location, configured, targets, warnings) {
|
|
|
14257
14479
|
if (!entry.isDirectory() && !entry.isSymbolicLink()) continue;
|
|
14258
14480
|
const directory = join9(root, entry.name);
|
|
14259
14481
|
try {
|
|
14260
|
-
const skillPackage = await readPackage(directory);
|
|
14482
|
+
const skillPackage = await readPackage(directory, resolvedRoot);
|
|
14261
14483
|
const relativeDirectory = location.folder ? relative6(location.folder, directory).split(sep6).join("/") : "";
|
|
14262
14484
|
installations.push({
|
|
14263
14485
|
...location,
|
|
@@ -14332,9 +14554,10 @@ var readSkills = async (payload) => {
|
|
|
14332
14554
|
if (!allowed.has(`${request.scope}:${root}`)) {
|
|
14333
14555
|
throw new Error("Requested skill root is not enabled or configured");
|
|
14334
14556
|
}
|
|
14557
|
+
const { resolvedRoot } = await resolvedSkillRoot(request);
|
|
14335
14558
|
packages.push({
|
|
14336
14559
|
...request,
|
|
14337
|
-
package: await readPackage(join9(root, request.skillName))
|
|
14560
|
+
package: await readPackage(join9(root, request.skillName), resolvedRoot)
|
|
14338
14561
|
});
|
|
14339
14562
|
}
|
|
14340
14563
|
return { ...successfulProcess6, packages };
|
|
@@ -14588,7 +14811,7 @@ async function optionalGit(cwd, args) {
|
|
|
14588
14811
|
}
|
|
14589
14812
|
function cappedGit(cwd, args, limit) {
|
|
14590
14813
|
const budget = limit - TRUNCATION_RESERVE;
|
|
14591
|
-
return new Promise((
|
|
14814
|
+
return new Promise((resolve9, reject) => {
|
|
14592
14815
|
const child = spawn6("git", args, {
|
|
14593
14816
|
cwd,
|
|
14594
14817
|
env: {
|
|
@@ -14638,7 +14861,7 @@ function cappedGit(cwd, args, limit) {
|
|
|
14638
14861
|
return;
|
|
14639
14862
|
}
|
|
14640
14863
|
const output = Buffer.concat(chunks).toString("utf8");
|
|
14641
|
-
|
|
14864
|
+
resolve9(
|
|
14642
14865
|
truncated ? `${output.trimEnd()}
|
|
14643
14866
|
|
|
14644
14867
|
[Truncated after ${budget} bytes]` : output.trim()
|
|
@@ -14948,10 +15171,494 @@ var runWorkflowGitCheckpoint = async (payloadValue, _timeoutMs, signal) => {
|
|
|
14948
15171
|
|
|
14949
15172
|
// src/handlers/worktrees.ts
|
|
14950
15173
|
import { createWriteStream as createWriteStream2, watch } from "node:fs";
|
|
14951
|
-
import { mkdtemp as mkdtemp6, open as open2, readFile as
|
|
15174
|
+
import { mkdtemp as mkdtemp6, open as open2, readFile as readFile9, realpath as realpath9, rm as rm10, stat as stat10 } from "node:fs/promises";
|
|
14952
15175
|
import { tmpdir as tmpdir6 } from "node:os";
|
|
14953
|
-
import { basename as basename5, dirname as
|
|
15176
|
+
import { basename as basename5, dirname as dirname8, isAbsolute as isAbsolute7, join as join14, relative as relative8 } from "node:path";
|
|
14954
15177
|
import { spawn as spawn7 } from "node:child_process";
|
|
15178
|
+
|
|
15179
|
+
// src/handlers/worktree-preparations.ts
|
|
15180
|
+
import { createHash as createHash7 } from "node:crypto";
|
|
15181
|
+
import {
|
|
15182
|
+
chmod as chmod4,
|
|
15183
|
+
lstat as lstat4,
|
|
15184
|
+
mkdir as mkdir5,
|
|
15185
|
+
readFile as readFile8,
|
|
15186
|
+
realpath as realpath8,
|
|
15187
|
+
rm as rm9,
|
|
15188
|
+
writeFile as writeFile7
|
|
15189
|
+
} from "node:fs/promises";
|
|
15190
|
+
import { dirname as dirname7, isAbsolute as isAbsolute6, join as join13, relative as relative7, resolve as resolve7 } from "node:path";
|
|
15191
|
+
var EXCLUDE_BEGIN = "# BEGIN AIDE PREPARATIONS";
|
|
15192
|
+
var EXCLUDE_END = "# END AIDE PREPARATIONS";
|
|
15193
|
+
function cleanError3(value) {
|
|
15194
|
+
return (value instanceof Error ? value.message : String(value)).replace(/([a-z][a-z0-9+.-]*:\/\/)[^\s/@]+@/gi, "$1").slice(0, 2e3);
|
|
15195
|
+
}
|
|
15196
|
+
async function git3(folder, args, timeoutMs, signal) {
|
|
15197
|
+
return captureCommand({
|
|
15198
|
+
command: "git",
|
|
15199
|
+
args: ["-C", folder, ...args],
|
|
15200
|
+
timeoutMs,
|
|
15201
|
+
signal,
|
|
15202
|
+
env: {
|
|
15203
|
+
...process.env,
|
|
15204
|
+
GIT_LITERAL_PATHSPECS: "1",
|
|
15205
|
+
GIT_OPTIONAL_LOCKS: "0",
|
|
15206
|
+
GIT_TERMINAL_PROMPT: "0"
|
|
15207
|
+
}
|
|
15208
|
+
});
|
|
15209
|
+
}
|
|
15210
|
+
function requireSuccess3(result, fallback) {
|
|
15211
|
+
if (result.cancelled) throw new Error("Preparation was cancelled");
|
|
15212
|
+
if (result.timedOut) throw new Error("Preparation timed out");
|
|
15213
|
+
if (result.exitCode !== 0) {
|
|
15214
|
+
throw new Error(cleanError3(result.stderr || fallback));
|
|
15215
|
+
}
|
|
15216
|
+
return result;
|
|
15217
|
+
}
|
|
15218
|
+
async function exists(path) {
|
|
15219
|
+
try {
|
|
15220
|
+
await lstat4(path);
|
|
15221
|
+
return true;
|
|
15222
|
+
} catch (error) {
|
|
15223
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
15224
|
+
return false;
|
|
15225
|
+
}
|
|
15226
|
+
throw error;
|
|
15227
|
+
}
|
|
15228
|
+
}
|
|
15229
|
+
async function safeTarget(folder, path) {
|
|
15230
|
+
const root = await realpath8(folder);
|
|
15231
|
+
const target2 = resolve7(root, path);
|
|
15232
|
+
const fromRoot = relative7(root, target2);
|
|
15233
|
+
if (!fromRoot || fromRoot.startsWith("..") || isAbsolute6(fromRoot) || path.includes("\0")) {
|
|
15234
|
+
throw new Error(
|
|
15235
|
+
"Preparation path must be an exact file inside the worktree"
|
|
15236
|
+
);
|
|
15237
|
+
}
|
|
15238
|
+
let current = root;
|
|
15239
|
+
const segments = fromRoot.split(/[\\/]/);
|
|
15240
|
+
for (const segment of segments.slice(0, -1)) {
|
|
15241
|
+
current = join13(current, segment);
|
|
15242
|
+
try {
|
|
15243
|
+
const info = await lstat4(current);
|
|
15244
|
+
if (info.isSymbolicLink()) {
|
|
15245
|
+
throw new Error(`Preparation path crosses symbolic link: ${path}`);
|
|
15246
|
+
}
|
|
15247
|
+
if (!info.isDirectory()) {
|
|
15248
|
+
throw new Error(`Preparation parent is not a directory: ${path}`);
|
|
15249
|
+
}
|
|
15250
|
+
} catch (error) {
|
|
15251
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
15252
|
+
break;
|
|
15253
|
+
}
|
|
15254
|
+
throw error;
|
|
15255
|
+
}
|
|
15256
|
+
}
|
|
15257
|
+
return target2;
|
|
15258
|
+
}
|
|
15259
|
+
async function isTracked(folder, path, timeoutMs, signal) {
|
|
15260
|
+
const result = await git3(
|
|
15261
|
+
folder,
|
|
15262
|
+
["ls-files", "--error-unmatch", "--", path],
|
|
15263
|
+
timeoutMs,
|
|
15264
|
+
signal
|
|
15265
|
+
);
|
|
15266
|
+
if (result.exitCode === 0) return true;
|
|
15267
|
+
if (result.exitCode === 1) return false;
|
|
15268
|
+
requireSuccess3(result, `Could not inspect tracked path ${path}`);
|
|
15269
|
+
return false;
|
|
15270
|
+
}
|
|
15271
|
+
async function isAssumeUnchanged(folder, path, timeoutMs, signal) {
|
|
15272
|
+
const result = requireSuccess3(
|
|
15273
|
+
await git3(folder, ["ls-files", "-v", "--", path], timeoutMs, signal),
|
|
15274
|
+
`Could not inspect assume-unchanged state for ${path}`
|
|
15275
|
+
);
|
|
15276
|
+
const marker = result.stdout[0];
|
|
15277
|
+
return Boolean(marker && /[a-z]/.test(marker));
|
|
15278
|
+
}
|
|
15279
|
+
async function setAssumeUnchanged(folder, path, assumed, timeoutMs, signal) {
|
|
15280
|
+
requireSuccess3(
|
|
15281
|
+
await git3(
|
|
15282
|
+
folder,
|
|
15283
|
+
[
|
|
15284
|
+
"update-index",
|
|
15285
|
+
assumed ? "--assume-unchanged" : "--no-assume-unchanged",
|
|
15286
|
+
"--",
|
|
15287
|
+
path
|
|
15288
|
+
],
|
|
15289
|
+
timeoutMs,
|
|
15290
|
+
signal
|
|
15291
|
+
),
|
|
15292
|
+
`Could not ${assumed ? "mark" : "unmark"} ${path} as assume unchanged`
|
|
15293
|
+
);
|
|
15294
|
+
}
|
|
15295
|
+
function excludeEntry(path) {
|
|
15296
|
+
return `/${path}`;
|
|
15297
|
+
}
|
|
15298
|
+
function withoutAideExcludeBlock(value) {
|
|
15299
|
+
const lines = value.split(/\r?\n/);
|
|
15300
|
+
const output = [];
|
|
15301
|
+
let inBlock = false;
|
|
15302
|
+
for (const line of lines) {
|
|
15303
|
+
if (line === EXCLUDE_BEGIN) {
|
|
15304
|
+
inBlock = true;
|
|
15305
|
+
continue;
|
|
15306
|
+
}
|
|
15307
|
+
if (line === EXCLUDE_END) {
|
|
15308
|
+
inBlock = false;
|
|
15309
|
+
continue;
|
|
15310
|
+
}
|
|
15311
|
+
if (!inBlock) output.push(line);
|
|
15312
|
+
}
|
|
15313
|
+
return output.join("\n").replace(/\n+$/, "");
|
|
15314
|
+
}
|
|
15315
|
+
async function excludeFile(folder, timeoutMs, signal) {
|
|
15316
|
+
const result = requireSuccess3(
|
|
15317
|
+
await git3(
|
|
15318
|
+
folder,
|
|
15319
|
+
["rev-parse", "--git-path", "info/exclude"],
|
|
15320
|
+
timeoutMs,
|
|
15321
|
+
signal
|
|
15322
|
+
),
|
|
15323
|
+
"Could not locate the repository exclude file"
|
|
15324
|
+
);
|
|
15325
|
+
const candidate = result.stdout.trim();
|
|
15326
|
+
return isAbsolute6(candidate) ? candidate : resolve7(folder, candidate);
|
|
15327
|
+
}
|
|
15328
|
+
async function readExcludeEntries(folder, timeoutMs, signal) {
|
|
15329
|
+
const path = await excludeFile(folder, timeoutMs, signal);
|
|
15330
|
+
let value = "";
|
|
15331
|
+
try {
|
|
15332
|
+
value = await readFile8(path, "utf8");
|
|
15333
|
+
} catch (error) {
|
|
15334
|
+
if (!(error instanceof Error) || !("code" in error) || error.code !== "ENOENT") {
|
|
15335
|
+
throw error;
|
|
15336
|
+
}
|
|
15337
|
+
}
|
|
15338
|
+
const start = value.split(/\r?\n/).indexOf(EXCLUDE_BEGIN);
|
|
15339
|
+
const end = value.split(/\r?\n/).indexOf(EXCLUDE_END);
|
|
15340
|
+
if (start < 0 || end <= start) return /* @__PURE__ */ new Set();
|
|
15341
|
+
return new Set(value.split(/\r?\n/).slice(start + 1, end));
|
|
15342
|
+
}
|
|
15343
|
+
async function reconcileExcludeFile(folder, definitions, timeoutMs, signal) {
|
|
15344
|
+
const path = await excludeFile(folder, timeoutMs, signal);
|
|
15345
|
+
let existing = "";
|
|
15346
|
+
try {
|
|
15347
|
+
existing = await readFile8(path, "utf8");
|
|
15348
|
+
} catch (error) {
|
|
15349
|
+
if (!(error instanceof Error) || !("code" in error) || error.code !== "ENOENT") {
|
|
15350
|
+
throw error;
|
|
15351
|
+
}
|
|
15352
|
+
}
|
|
15353
|
+
const base = withoutAideExcludeBlock(existing);
|
|
15354
|
+
const entries = definitions.filter((definition) => definition.kind === "WRITE").map((definition) => excludeEntry(definition.path)).sort((left, right) => left.localeCompare(right));
|
|
15355
|
+
const block = entries.length ? [EXCLUDE_BEGIN, ...entries, EXCLUDE_END].join("\n") : "";
|
|
15356
|
+
const next = [base, block].filter(Boolean).join("\n\n");
|
|
15357
|
+
await mkdir5(dirname7(path), { recursive: true });
|
|
15358
|
+
await writeFile7(path, next ? `${next}
|
|
15359
|
+
` : "", "utf8");
|
|
15360
|
+
}
|
|
15361
|
+
function decodeContents(definition) {
|
|
15362
|
+
if (definition.contentBase64 === null) {
|
|
15363
|
+
throw new Error(`Write preparation ${definition.path} has no contents`);
|
|
15364
|
+
}
|
|
15365
|
+
const contents = Buffer.from(definition.contentBase64, "base64");
|
|
15366
|
+
const canonicalInput = definition.contentBase64.replace(/=+$/, "");
|
|
15367
|
+
if (contents.toString("base64").replace(/=+$/, "") !== canonicalInput) {
|
|
15368
|
+
throw new Error(
|
|
15369
|
+
`Write preparation ${definition.path} has invalid base64 contents`
|
|
15370
|
+
);
|
|
15371
|
+
}
|
|
15372
|
+
return contents;
|
|
15373
|
+
}
|
|
15374
|
+
async function removeTarget(target2, path) {
|
|
15375
|
+
try {
|
|
15376
|
+
const info = await lstat4(target2);
|
|
15377
|
+
if (info.isDirectory() && !info.isSymbolicLink()) {
|
|
15378
|
+
throw new Error(`Preparation path is a directory: ${path}`);
|
|
15379
|
+
}
|
|
15380
|
+
await rm9(target2, { force: true });
|
|
15381
|
+
} catch (error) {
|
|
15382
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
15383
|
+
return;
|
|
15384
|
+
}
|
|
15385
|
+
throw error;
|
|
15386
|
+
}
|
|
15387
|
+
}
|
|
15388
|
+
async function restoreFromHead(folder, definition, timeoutMs, signal) {
|
|
15389
|
+
const target2 = await safeTarget(folder, definition.path);
|
|
15390
|
+
if (await isTracked(folder, definition.path, timeoutMs, signal)) {
|
|
15391
|
+
await setAssumeUnchanged(folder, definition.path, false, timeoutMs, signal);
|
|
15392
|
+
const atHead = await git3(
|
|
15393
|
+
folder,
|
|
15394
|
+
["cat-file", "-e", `HEAD:${definition.path}`],
|
|
15395
|
+
timeoutMs,
|
|
15396
|
+
signal
|
|
15397
|
+
);
|
|
15398
|
+
if (atHead.exitCode === 0) {
|
|
15399
|
+
requireSuccess3(
|
|
15400
|
+
await git3(
|
|
15401
|
+
folder,
|
|
15402
|
+
["restore", "--source=HEAD", "--worktree", "--", definition.path],
|
|
15403
|
+
timeoutMs,
|
|
15404
|
+
signal
|
|
15405
|
+
),
|
|
15406
|
+
`Could not restore ${definition.path} from HEAD`
|
|
15407
|
+
);
|
|
15408
|
+
return;
|
|
15409
|
+
}
|
|
15410
|
+
if (atHead.exitCode !== 1 && atHead.exitCode !== 128) {
|
|
15411
|
+
requireSuccess3(atHead, `Could not inspect ${definition.path} in HEAD`);
|
|
15412
|
+
}
|
|
15413
|
+
}
|
|
15414
|
+
await removeTarget(target2, definition.path);
|
|
15415
|
+
}
|
|
15416
|
+
async function applyOne(folder, definition, timeoutMs, signal) {
|
|
15417
|
+
const target2 = await safeTarget(folder, definition.path);
|
|
15418
|
+
const tracked = await isTracked(folder, definition.path, timeoutMs, signal);
|
|
15419
|
+
if (definition.kind === "ASSUME_UNCHANGED") {
|
|
15420
|
+
if (!tracked) return "NOT_APPLICABLE";
|
|
15421
|
+
await setAssumeUnchanged(folder, definition.path, true, timeoutMs, signal);
|
|
15422
|
+
return "APPLIED";
|
|
15423
|
+
}
|
|
15424
|
+
if (definition.kind === "DELETE") {
|
|
15425
|
+
await removeTarget(target2, definition.path);
|
|
15426
|
+
} else {
|
|
15427
|
+
const contents = decodeContents(definition);
|
|
15428
|
+
let executable = false;
|
|
15429
|
+
try {
|
|
15430
|
+
const info = await lstat4(target2);
|
|
15431
|
+
if (info.isDirectory() && !info.isSymbolicLink()) {
|
|
15432
|
+
throw new Error(`Preparation path is a directory: ${definition.path}`);
|
|
15433
|
+
}
|
|
15434
|
+
executable = info.isFile() && (info.mode & 73) !== 0;
|
|
15435
|
+
if (info.isSymbolicLink()) await rm9(target2, { force: true });
|
|
15436
|
+
} catch (error) {
|
|
15437
|
+
if (!(error instanceof Error) || !("code" in error) || error.code !== "ENOENT") {
|
|
15438
|
+
throw error;
|
|
15439
|
+
}
|
|
15440
|
+
}
|
|
15441
|
+
await mkdir5(dirname7(target2), { recursive: true, mode: 493 });
|
|
15442
|
+
await safeTarget(folder, definition.path);
|
|
15443
|
+
await writeFile7(target2, contents, { mode: executable ? 493 : 420 });
|
|
15444
|
+
if (executable) await chmod4(target2, 493);
|
|
15445
|
+
}
|
|
15446
|
+
if (tracked) {
|
|
15447
|
+
await setAssumeUnchanged(folder, definition.path, true, timeoutMs, signal);
|
|
15448
|
+
}
|
|
15449
|
+
return "APPLIED";
|
|
15450
|
+
}
|
|
15451
|
+
async function undoOne(folder, definition, timeoutMs, signal) {
|
|
15452
|
+
if (definition.kind === "ASSUME_UNCHANGED") {
|
|
15453
|
+
if (!await isTracked(folder, definition.path, timeoutMs, signal)) {
|
|
15454
|
+
return "NOT_APPLICABLE";
|
|
15455
|
+
}
|
|
15456
|
+
await setAssumeUnchanged(folder, definition.path, false, timeoutMs, signal);
|
|
15457
|
+
return "UNDONE";
|
|
15458
|
+
}
|
|
15459
|
+
await restoreFromHead(folder, definition, timeoutMs, signal);
|
|
15460
|
+
return "UNDONE";
|
|
15461
|
+
}
|
|
15462
|
+
async function inspectOne(folder, definition, excludeEntries, timeoutMs, signal) {
|
|
15463
|
+
const target2 = await safeTarget(folder, definition.path);
|
|
15464
|
+
const tracked = await isTracked(folder, definition.path, timeoutMs, signal);
|
|
15465
|
+
const assumed = tracked ? await isAssumeUnchanged(folder, definition.path, timeoutMs, signal) : false;
|
|
15466
|
+
if (definition.kind === "ASSUME_UNCHANGED") {
|
|
15467
|
+
return tracked ? assumed ? "APPLIED" : "DRIFTED" : "NOT_APPLICABLE";
|
|
15468
|
+
}
|
|
15469
|
+
if (definition.kind === "DELETE") {
|
|
15470
|
+
return !await exists(target2) && (!tracked || assumed) ? "APPLIED" : "DRIFTED";
|
|
15471
|
+
}
|
|
15472
|
+
let matches = false;
|
|
15473
|
+
try {
|
|
15474
|
+
const info = await lstat4(target2);
|
|
15475
|
+
if (info.isFile()) {
|
|
15476
|
+
const expected = createHash7("sha256").update(decodeContents(definition)).digest("hex");
|
|
15477
|
+
const actual = createHash7("sha256").update(await readFile8(target2)).digest("hex");
|
|
15478
|
+
matches = actual === expected;
|
|
15479
|
+
}
|
|
15480
|
+
} catch (error) {
|
|
15481
|
+
if (!(error instanceof Error) || !("code" in error) || error.code !== "ENOENT") {
|
|
15482
|
+
throw error;
|
|
15483
|
+
}
|
|
15484
|
+
}
|
|
15485
|
+
const hidden = tracked ? assumed : excludeEntries.has(excludeEntry(definition.path));
|
|
15486
|
+
return matches && hidden ? "APPLIED" : "DRIFTED";
|
|
15487
|
+
}
|
|
15488
|
+
async function executeWorktreePreparations(folder, definitions, action, timeoutMs, signal) {
|
|
15489
|
+
let excludeError = null;
|
|
15490
|
+
if (action !== "INSPECT") {
|
|
15491
|
+
try {
|
|
15492
|
+
await reconcileExcludeFile(folder, definitions, timeoutMs, signal);
|
|
15493
|
+
} catch (error) {
|
|
15494
|
+
excludeError = cleanError3(error);
|
|
15495
|
+
}
|
|
15496
|
+
}
|
|
15497
|
+
let excludeEntries = /* @__PURE__ */ new Set();
|
|
15498
|
+
try {
|
|
15499
|
+
excludeEntries = await readExcludeEntries(folder, timeoutMs, signal);
|
|
15500
|
+
} catch (error) {
|
|
15501
|
+
excludeError ??= cleanError3(error);
|
|
15502
|
+
}
|
|
15503
|
+
const results = [];
|
|
15504
|
+
for (const definition of definitions) {
|
|
15505
|
+
if (definition.kind === "WRITE" && excludeError) {
|
|
15506
|
+
results.push({
|
|
15507
|
+
id: definition.id,
|
|
15508
|
+
definitionHash: definition.definitionHash,
|
|
15509
|
+
state: "ERROR",
|
|
15510
|
+
message: excludeError
|
|
15511
|
+
});
|
|
15512
|
+
continue;
|
|
15513
|
+
}
|
|
15514
|
+
try {
|
|
15515
|
+
const state = action === "APPLY" ? await applyOne(folder, definition, timeoutMs, signal) : action === "UNDO" ? await undoOne(folder, definition, timeoutMs, signal) : await inspectOne(
|
|
15516
|
+
folder,
|
|
15517
|
+
definition,
|
|
15518
|
+
excludeEntries,
|
|
15519
|
+
timeoutMs,
|
|
15520
|
+
signal
|
|
15521
|
+
);
|
|
15522
|
+
results.push({
|
|
15523
|
+
id: definition.id,
|
|
15524
|
+
definitionHash: definition.definitionHash,
|
|
15525
|
+
state
|
|
15526
|
+
});
|
|
15527
|
+
} catch (error) {
|
|
15528
|
+
results.push({
|
|
15529
|
+
id: definition.id,
|
|
15530
|
+
definitionHash: definition.definitionHash,
|
|
15531
|
+
state: "ERROR",
|
|
15532
|
+
message: cleanError3(error)
|
|
15533
|
+
});
|
|
15534
|
+
}
|
|
15535
|
+
}
|
|
15536
|
+
return results;
|
|
15537
|
+
}
|
|
15538
|
+
async function suspendWorktreePreparations(folder, definitions, timeoutMs, signal, preserveAssumeUnchangedContents = false) {
|
|
15539
|
+
let excludeError = null;
|
|
15540
|
+
try {
|
|
15541
|
+
await reconcileExcludeFile(folder, definitions, timeoutMs, signal);
|
|
15542
|
+
} catch (error) {
|
|
15543
|
+
excludeError = cleanError3(error);
|
|
15544
|
+
}
|
|
15545
|
+
const results = [];
|
|
15546
|
+
for (const definition of definitions) {
|
|
15547
|
+
if (definition.kind === "WRITE" && excludeError) {
|
|
15548
|
+
results.push({
|
|
15549
|
+
id: definition.id,
|
|
15550
|
+
definitionHash: definition.definitionHash,
|
|
15551
|
+
state: "ERROR",
|
|
15552
|
+
message: excludeError
|
|
15553
|
+
});
|
|
15554
|
+
continue;
|
|
15555
|
+
}
|
|
15556
|
+
try {
|
|
15557
|
+
if (definition.kind === "ASSUME_UNCHANGED") {
|
|
15558
|
+
if (await isTracked(folder, definition.path, timeoutMs, signal)) {
|
|
15559
|
+
if (preserveAssumeUnchangedContents) {
|
|
15560
|
+
await setAssumeUnchanged(
|
|
15561
|
+
folder,
|
|
15562
|
+
definition.path,
|
|
15563
|
+
false,
|
|
15564
|
+
timeoutMs,
|
|
15565
|
+
signal
|
|
15566
|
+
);
|
|
15567
|
+
} else {
|
|
15568
|
+
await restoreFromHead(folder, definition, timeoutMs, signal);
|
|
15569
|
+
}
|
|
15570
|
+
results.push({
|
|
15571
|
+
id: definition.id,
|
|
15572
|
+
definitionHash: definition.definitionHash,
|
|
15573
|
+
state: "SUSPENDED"
|
|
15574
|
+
});
|
|
15575
|
+
} else {
|
|
15576
|
+
results.push({
|
|
15577
|
+
id: definition.id,
|
|
15578
|
+
definitionHash: definition.definitionHash,
|
|
15579
|
+
state: "NOT_APPLICABLE"
|
|
15580
|
+
});
|
|
15581
|
+
}
|
|
15582
|
+
} else {
|
|
15583
|
+
await restoreFromHead(folder, definition, timeoutMs, signal);
|
|
15584
|
+
results.push({
|
|
15585
|
+
id: definition.id,
|
|
15586
|
+
definitionHash: definition.definitionHash,
|
|
15587
|
+
state: "SUSPENDED"
|
|
15588
|
+
});
|
|
15589
|
+
}
|
|
15590
|
+
} catch (error) {
|
|
15591
|
+
results.push({
|
|
15592
|
+
id: definition.id,
|
|
15593
|
+
definitionHash: definition.definitionHash,
|
|
15594
|
+
state: "ERROR",
|
|
15595
|
+
message: cleanError3(error)
|
|
15596
|
+
});
|
|
15597
|
+
}
|
|
15598
|
+
}
|
|
15599
|
+
return results;
|
|
15600
|
+
}
|
|
15601
|
+
async function preparationConflictPaths(folder, definitions, remoteBase, timeoutMs, signal) {
|
|
15602
|
+
const paths = [];
|
|
15603
|
+
for (const definition of definitions) {
|
|
15604
|
+
const changedByBase = await git3(
|
|
15605
|
+
folder,
|
|
15606
|
+
["diff", "--quiet", `HEAD...${remoteBase}`, "--", definition.path],
|
|
15607
|
+
timeoutMs,
|
|
15608
|
+
signal
|
|
15609
|
+
);
|
|
15610
|
+
if (changedByBase.exitCode === 1) {
|
|
15611
|
+
const tracked = await isTracked(
|
|
15612
|
+
folder,
|
|
15613
|
+
definition.path,
|
|
15614
|
+
timeoutMs,
|
|
15615
|
+
signal
|
|
15616
|
+
);
|
|
15617
|
+
let managedChange = false;
|
|
15618
|
+
if (tracked) {
|
|
15619
|
+
const head = await git3(
|
|
15620
|
+
folder,
|
|
15621
|
+
["rev-parse", `HEAD:${definition.path}`],
|
|
15622
|
+
timeoutMs,
|
|
15623
|
+
signal
|
|
15624
|
+
);
|
|
15625
|
+
const working = await git3(
|
|
15626
|
+
folder,
|
|
15627
|
+
["hash-object", "--", definition.path],
|
|
15628
|
+
timeoutMs,
|
|
15629
|
+
signal
|
|
15630
|
+
);
|
|
15631
|
+
managedChange = head.exitCode !== 0 || working.exitCode !== 0 || head.stdout.trim() !== working.stdout.trim();
|
|
15632
|
+
} else if (definition.kind === "WRITE") {
|
|
15633
|
+
managedChange = await exists(await safeTarget(folder, definition.path));
|
|
15634
|
+
} else {
|
|
15635
|
+
const presentOnBase = await git3(
|
|
15636
|
+
folder,
|
|
15637
|
+
["cat-file", "-e", `${remoteBase}:${definition.path}`],
|
|
15638
|
+
timeoutMs,
|
|
15639
|
+
signal
|
|
15640
|
+
);
|
|
15641
|
+
if (presentOnBase.exitCode === 0) {
|
|
15642
|
+
managedChange = true;
|
|
15643
|
+
} else if (presentOnBase.exitCode !== 1 && presentOnBase.exitCode !== 128) {
|
|
15644
|
+
requireSuccess3(
|
|
15645
|
+
presentOnBase,
|
|
15646
|
+
`Could not inspect ${definition.path} on the base branch`
|
|
15647
|
+
);
|
|
15648
|
+
}
|
|
15649
|
+
}
|
|
15650
|
+
if (managedChange) paths.push(definition.path);
|
|
15651
|
+
continue;
|
|
15652
|
+
}
|
|
15653
|
+
requireSuccess3(
|
|
15654
|
+
changedByBase,
|
|
15655
|
+
`Could not inspect preparation conflict for ${definition.path}`
|
|
15656
|
+
);
|
|
15657
|
+
}
|
|
15658
|
+
return paths;
|
|
15659
|
+
}
|
|
15660
|
+
|
|
15661
|
+
// src/handlers/worktrees.ts
|
|
14955
15662
|
var successfulProcess8 = {
|
|
14956
15663
|
exitCode: 0,
|
|
14957
15664
|
signal: null,
|
|
@@ -14995,7 +15702,7 @@ function statusChangeState(value) {
|
|
|
14995
15702
|
}
|
|
14996
15703
|
async function rebaseInProgress(folder, timeoutMs, signal) {
|
|
14997
15704
|
for (const name of ["rebase-merge", "rebase-apply"]) {
|
|
14998
|
-
const pathResult = await
|
|
15705
|
+
const pathResult = await git4(
|
|
14999
15706
|
folder,
|
|
15000
15707
|
["rev-parse", "--git-path", name],
|
|
15001
15708
|
timeoutMs,
|
|
@@ -15005,7 +15712,7 @@ async function rebaseInProgress(folder, timeoutMs, signal) {
|
|
|
15005
15712
|
const candidate = pathResult.stdout.trim();
|
|
15006
15713
|
if (!candidate) continue;
|
|
15007
15714
|
try {
|
|
15008
|
-
await stat10(
|
|
15715
|
+
await stat10(isAbsolute7(candidate) ? candidate : join14(folder, candidate));
|
|
15009
15716
|
return true;
|
|
15010
15717
|
} catch {
|
|
15011
15718
|
}
|
|
@@ -15014,7 +15721,7 @@ async function rebaseInProgress(folder, timeoutMs, signal) {
|
|
|
15014
15721
|
}
|
|
15015
15722
|
async function rebaseBranch(folder, timeoutMs, signal) {
|
|
15016
15723
|
for (const name of ["rebase-merge/head-name", "rebase-apply/head-name"]) {
|
|
15017
|
-
const pathResult = await
|
|
15724
|
+
const pathResult = await git4(
|
|
15018
15725
|
folder,
|
|
15019
15726
|
["rev-parse", "--git-path", name],
|
|
15020
15727
|
timeoutMs,
|
|
@@ -15024,8 +15731,8 @@ async function rebaseBranch(folder, timeoutMs, signal) {
|
|
|
15024
15731
|
const candidate = pathResult.stdout.trim();
|
|
15025
15732
|
if (!candidate) continue;
|
|
15026
15733
|
try {
|
|
15027
|
-
const headName = (await
|
|
15028
|
-
|
|
15734
|
+
const headName = (await readFile9(
|
|
15735
|
+
isAbsolute7(candidate) ? candidate : join14(folder, candidate),
|
|
15029
15736
|
"utf8"
|
|
15030
15737
|
)).trim();
|
|
15031
15738
|
if (headName.startsWith("refs/heads/")) {
|
|
@@ -15059,7 +15766,7 @@ async function flushWorktreeActivity(entry) {
|
|
|
15059
15766
|
try {
|
|
15060
15767
|
const signal = new AbortController().signal;
|
|
15061
15768
|
const [status2, branchResult, headResult, codeStateHash, rebasing] = await Promise.all([
|
|
15062
|
-
|
|
15769
|
+
git4(
|
|
15063
15770
|
entry.folder,
|
|
15064
15771
|
[
|
|
15065
15772
|
"--no-optional-locks",
|
|
@@ -15071,13 +15778,13 @@ async function flushWorktreeActivity(entry) {
|
|
|
15071
15778
|
entry.timeoutMs,
|
|
15072
15779
|
signal
|
|
15073
15780
|
),
|
|
15074
|
-
|
|
15781
|
+
git4(
|
|
15075
15782
|
entry.folder,
|
|
15076
15783
|
["symbolic-ref", "--short", "-q", "HEAD"],
|
|
15077
15784
|
entry.timeoutMs,
|
|
15078
15785
|
signal
|
|
15079
15786
|
),
|
|
15080
|
-
|
|
15787
|
+
git4(entry.folder, ["rev-parse", "HEAD"], entry.timeoutMs, signal),
|
|
15081
15788
|
worktreeCodeStateHash(entry.folder, entry.timeoutMs, signal),
|
|
15082
15789
|
rebaseInProgress(entry.folder, entry.timeoutMs, signal)
|
|
15083
15790
|
]);
|
|
@@ -15106,7 +15813,7 @@ async function flushWorktreeActivity(entry) {
|
|
|
15106
15813
|
observedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
15107
15814
|
};
|
|
15108
15815
|
if (headIdentity && headIdentity !== entry.headIdentity) {
|
|
15109
|
-
const upstreamResult = branch ? await
|
|
15816
|
+
const upstreamResult = branch ? await git4(
|
|
15110
15817
|
entry.folder,
|
|
15111
15818
|
[
|
|
15112
15819
|
"rev-parse",
|
|
@@ -15164,24 +15871,24 @@ function scheduleWorktreeActivity(entry) {
|
|
|
15164
15871
|
}, WATCH_DEBOUNCE_MS);
|
|
15165
15872
|
entry.timer.unref();
|
|
15166
15873
|
}
|
|
15167
|
-
function
|
|
15874
|
+
function cleanError4(value) {
|
|
15168
15875
|
return (value instanceof Error ? value.message : String(value)).replace(/([a-z][a-z0-9+.-]*:\/\/)[^\s/@]+@/gi, "$1").slice(0, 2e3);
|
|
15169
15876
|
}
|
|
15170
15877
|
async function command2(executable, args, timeoutMs, signal, env = process.env) {
|
|
15171
15878
|
return captureCommand({ command: executable, args, timeoutMs, signal, env });
|
|
15172
15879
|
}
|
|
15173
|
-
async function
|
|
15880
|
+
async function git4(folder, args, timeoutMs, signal) {
|
|
15174
15881
|
return command2("git", ["-C", folder, ...args], timeoutMs, signal, {
|
|
15175
15882
|
...process.env,
|
|
15176
15883
|
GIT_TERMINAL_PROMPT: "0",
|
|
15177
15884
|
GIT_OPTIONAL_LOCKS: "0"
|
|
15178
15885
|
});
|
|
15179
15886
|
}
|
|
15180
|
-
function
|
|
15887
|
+
function requireSuccess4(result, fallback) {
|
|
15181
15888
|
if (result.cancelled) throw new Error("Worktree operation was cancelled");
|
|
15182
15889
|
if (result.timedOut) throw new Error("Worktree operation timed out");
|
|
15183
15890
|
if (result.exitCode !== 0)
|
|
15184
|
-
throw new Error(
|
|
15891
|
+
throw new Error(cleanError4(result.stderr || fallback));
|
|
15185
15892
|
return result;
|
|
15186
15893
|
}
|
|
15187
15894
|
function parseWorktreeList(value) {
|
|
@@ -15199,8 +15906,8 @@ function parseWorktreeList(value) {
|
|
|
15199
15906
|
}).filter((entry) => Boolean(entry.folder));
|
|
15200
15907
|
}
|
|
15201
15908
|
async function gitDirectory(folder, timeoutMs, signal) {
|
|
15202
|
-
const result =
|
|
15203
|
-
await
|
|
15909
|
+
const result = requireSuccess4(
|
|
15910
|
+
await git4(
|
|
15204
15911
|
folder,
|
|
15205
15912
|
["rev-parse", "--path-format=absolute", "--git-dir"],
|
|
15206
15913
|
timeoutMs,
|
|
@@ -15208,17 +15915,17 @@ async function gitDirectory(folder, timeoutMs, signal) {
|
|
|
15208
15915
|
),
|
|
15209
15916
|
"Could not resolve the worktree Git directory"
|
|
15210
15917
|
);
|
|
15211
|
-
return
|
|
15918
|
+
return realpath9(result.stdout.trim());
|
|
15212
15919
|
}
|
|
15213
15920
|
async function origin(folder, timeoutMs, signal) {
|
|
15214
|
-
const result =
|
|
15215
|
-
await
|
|
15921
|
+
const result = requireSuccess4(
|
|
15922
|
+
await git4(folder, ["remote", "get-url", "origin"], timeoutMs, signal),
|
|
15216
15923
|
"Repository does not have an origin remote"
|
|
15217
15924
|
);
|
|
15218
15925
|
return normalizeGitOrigin(result.stdout.trim()).canonicalOrigin;
|
|
15219
15926
|
}
|
|
15220
15927
|
async function validateWorktree2(input, timeoutMs, signal) {
|
|
15221
|
-
const folder = await
|
|
15928
|
+
const folder = await realpath9(input.folder);
|
|
15222
15929
|
if (!(await stat10(folder)).isDirectory())
|
|
15223
15930
|
throw new Error("Worktree is missing");
|
|
15224
15931
|
const observedGitDirectory = await gitDirectory(folder, timeoutMs, signal);
|
|
@@ -15231,7 +15938,7 @@ async function validateWorktree2(input, timeoutMs, signal) {
|
|
|
15231
15938
|
return folder;
|
|
15232
15939
|
}
|
|
15233
15940
|
async function counts(folder, range, timeoutMs, signal) {
|
|
15234
|
-
const result = await
|
|
15941
|
+
const result = await git4(
|
|
15235
15942
|
folder,
|
|
15236
15943
|
["rev-list", "--left-right", "--count", range],
|
|
15237
15944
|
timeoutMs,
|
|
@@ -15265,17 +15972,17 @@ async function worktreePushStatus(folder, branch, changes, timeoutMs, signal) {
|
|
|
15265
15972
|
async function inspectWorktreeItem(folderValue2, rootFolder, baseBranch, primary, timeoutMs, signal) {
|
|
15266
15973
|
const checkedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
15267
15974
|
try {
|
|
15268
|
-
const folder = await
|
|
15975
|
+
const folder = await realpath9(folderValue2);
|
|
15269
15976
|
const [gitDir, branchResult, headResult, statusResult, rebasing] = await Promise.all([
|
|
15270
15977
|
gitDirectory(folder, timeoutMs, signal),
|
|
15271
|
-
|
|
15978
|
+
git4(
|
|
15272
15979
|
folder,
|
|
15273
15980
|
["symbolic-ref", "--short", "-q", "HEAD"],
|
|
15274
15981
|
timeoutMs,
|
|
15275
15982
|
signal
|
|
15276
15983
|
),
|
|
15277
|
-
|
|
15278
|
-
|
|
15984
|
+
git4(folder, ["rev-parse", "HEAD"], timeoutMs, signal),
|
|
15985
|
+
git4(
|
|
15279
15986
|
folder,
|
|
15280
15987
|
[
|
|
15281
15988
|
"--no-optional-locks",
|
|
@@ -15291,7 +15998,7 @@ async function inspectWorktreeItem(folderValue2, rootFolder, baseBranch, primary
|
|
|
15291
15998
|
]);
|
|
15292
15999
|
const symbolicBranch = branchResult.exitCode === 0 ? branchResult.stdout.trim() : null;
|
|
15293
16000
|
const branch = symbolicBranch ?? (rebasing ? await rebaseBranch(folder, timeoutMs, signal) : null);
|
|
15294
|
-
const upstreamResult = branch ? await
|
|
16001
|
+
const upstreamResult = branch ? await git4(
|
|
15295
16002
|
folder,
|
|
15296
16003
|
["rev-parse", "--abbrev-ref", "--symbolic-full-name", "@{upstream}"],
|
|
15297
16004
|
timeoutMs,
|
|
@@ -15314,7 +16021,7 @@ async function inspectWorktreeItem(folderValue2, rootFolder, baseBranch, primary
|
|
|
15314
16021
|
return {
|
|
15315
16022
|
gitDirectory: gitDir,
|
|
15316
16023
|
folder,
|
|
15317
|
-
relativePath:
|
|
16024
|
+
relativePath: relative8(rootFolder, folder) || ".",
|
|
15318
16025
|
primary,
|
|
15319
16026
|
branch,
|
|
15320
16027
|
headSha: headResult.exitCode === 0 ? headResult.stdout.trim() : null,
|
|
@@ -15342,7 +16049,7 @@ async function inspectWorktreeItem(folderValue2, rootFolder, baseBranch, primary
|
|
|
15342
16049
|
return {
|
|
15343
16050
|
gitDirectory: folderValue2,
|
|
15344
16051
|
folder: folderValue2,
|
|
15345
|
-
relativePath:
|
|
16052
|
+
relativePath: relative8(rootFolder, folderValue2) || ".",
|
|
15346
16053
|
primary,
|
|
15347
16054
|
branch: null,
|
|
15348
16055
|
headSha: null,
|
|
@@ -15359,15 +16066,15 @@ async function inspectWorktreeItem(folderValue2, rootFolder, baseBranch, primary
|
|
|
15359
16066
|
hasConflicts: false,
|
|
15360
16067
|
pushStatus: "UNKNOWN",
|
|
15361
16068
|
availability: "ERROR",
|
|
15362
|
-
error:
|
|
16069
|
+
error: cleanError4(error),
|
|
15363
16070
|
checkedAt
|
|
15364
16071
|
};
|
|
15365
16072
|
}
|
|
15366
16073
|
}
|
|
15367
16074
|
async function discoverWorktrees(rootFolderValue, baseOverrides, knownDefaultBranch, timeoutMs, signal) {
|
|
15368
|
-
const rootFolder = await
|
|
15369
|
-
const list =
|
|
15370
|
-
await
|
|
16075
|
+
const rootFolder = await realpath9(rootFolderValue);
|
|
16076
|
+
const list = requireSuccess4(
|
|
16077
|
+
await git4(
|
|
15371
16078
|
rootFolder,
|
|
15372
16079
|
["worktree", "list", "--porcelain"],
|
|
15373
16080
|
timeoutMs,
|
|
@@ -15375,14 +16082,14 @@ async function discoverWorktrees(rootFolderValue, baseOverrides, knownDefaultBra
|
|
|
15375
16082
|
),
|
|
15376
16083
|
"Could not list Git worktrees"
|
|
15377
16084
|
);
|
|
15378
|
-
const remoteHead = await
|
|
16085
|
+
const remoteHead = await git4(
|
|
15379
16086
|
rootFolder,
|
|
15380
16087
|
["ls-remote", "--symref", "origin", "HEAD"],
|
|
15381
16088
|
timeoutMs,
|
|
15382
16089
|
signal
|
|
15383
16090
|
);
|
|
15384
16091
|
let defaultBranch = remoteHead.stdout.match(/^ref:\s+refs\/heads\/([^\s]+)\s+HEAD/m)?.[1] ?? null;
|
|
15385
|
-
const defaultResult = await
|
|
16092
|
+
const defaultResult = await git4(
|
|
15386
16093
|
rootFolder,
|
|
15387
16094
|
["symbolic-ref", "--short", "refs/remotes/origin/HEAD"],
|
|
15388
16095
|
timeoutMs,
|
|
@@ -15393,13 +16100,13 @@ async function discoverWorktrees(rootFolderValue, baseOverrides, knownDefaultBra
|
|
|
15393
16100
|
defaultBranch = localDefaultBranch || knownDefaultBranch;
|
|
15394
16101
|
}
|
|
15395
16102
|
const [localBranchesResult, remoteBranchesResult] = await Promise.all([
|
|
15396
|
-
|
|
16103
|
+
git4(
|
|
15397
16104
|
rootFolder,
|
|
15398
16105
|
["for-each-ref", "--format=%(refname:strip=2)", "refs/heads"],
|
|
15399
16106
|
timeoutMs,
|
|
15400
16107
|
signal
|
|
15401
16108
|
),
|
|
15402
|
-
|
|
16109
|
+
git4(
|
|
15403
16110
|
rootFolder,
|
|
15404
16111
|
["for-each-ref", "--format=%(refname:strip=3)", "refs/remotes/origin"],
|
|
15405
16112
|
timeoutMs,
|
|
@@ -15462,7 +16169,7 @@ async function untrackedLines(folder, path) {
|
|
|
15462
16169
|
try {
|
|
15463
16170
|
const file = await stat10(`${folder}/${path}`);
|
|
15464
16171
|
if (!file.isFile() || file.size > 1024 * 1024) return null;
|
|
15465
|
-
const contents = await
|
|
16172
|
+
const contents = await readFile9(`${folder}/${path}`);
|
|
15466
16173
|
if (contents.includes(0)) return null;
|
|
15467
16174
|
const text2 = contents.toString("utf8");
|
|
15468
16175
|
return text2 ? text2.split("\n").length - (text2.endsWith("\n") ? 1 : 0) : 0;
|
|
@@ -15472,16 +16179,16 @@ async function untrackedLines(folder, path) {
|
|
|
15472
16179
|
}
|
|
15473
16180
|
async function inspectChanges(folder, timeoutMs, signal) {
|
|
15474
16181
|
const [statusResult, stagedResult, unstagedResult] = await Promise.all([
|
|
15475
|
-
|
|
16182
|
+
git4(
|
|
15476
16183
|
folder,
|
|
15477
16184
|
["status", "--porcelain=v1", "-z", "--untracked-files=all"],
|
|
15478
16185
|
timeoutMs,
|
|
15479
16186
|
signal
|
|
15480
16187
|
),
|
|
15481
|
-
|
|
15482
|
-
|
|
16188
|
+
git4(folder, ["diff", "--cached", "--numstat", "-z"], timeoutMs, signal),
|
|
16189
|
+
git4(folder, ["diff", "--numstat", "-z"], timeoutMs, signal)
|
|
15483
16190
|
]);
|
|
15484
|
-
|
|
16191
|
+
requireSuccess4(statusResult, "Could not inspect worktree changes");
|
|
15485
16192
|
const stagedCounts = parseNumstat(stagedResult.stdout);
|
|
15486
16193
|
const unstagedCounts = parseNumstat(unstagedResult.stdout);
|
|
15487
16194
|
const values = statusResult.stdout.split("\0").filter(Boolean);
|
|
@@ -15541,11 +16248,11 @@ function parseNameStatus(value) {
|
|
|
15541
16248
|
}
|
|
15542
16249
|
async function diffFiles(folder, range, timeoutMs, signal) {
|
|
15543
16250
|
const [status2, counts2] = await Promise.all([
|
|
15544
|
-
|
|
15545
|
-
|
|
16251
|
+
git4(folder, ["diff", "--name-status", "-z", range], timeoutMs, signal),
|
|
16252
|
+
git4(folder, ["diff", "--numstat", "-z", range], timeoutMs, signal)
|
|
15546
16253
|
]);
|
|
15547
|
-
|
|
15548
|
-
|
|
16254
|
+
requireSuccess4(status2, "Could not inspect changed files");
|
|
16255
|
+
requireSuccess4(counts2, "Could not inspect changed line counts");
|
|
15549
16256
|
const numstat = parseNumstat(counts2.stdout);
|
|
15550
16257
|
return parseNameStatus(status2.stdout).map((file) => {
|
|
15551
16258
|
const [additions, deletions] = numstat.get(file.path) ?? [null, null];
|
|
@@ -15559,8 +16266,8 @@ async function diffFiles(folder, range, timeoutMs, signal) {
|
|
|
15559
16266
|
});
|
|
15560
16267
|
}
|
|
15561
16268
|
async function inspectBranchChanges(folder, baseBranch, timeoutMs, signal) {
|
|
15562
|
-
const mergeBase =
|
|
15563
|
-
await
|
|
16269
|
+
const mergeBase = requireSuccess4(
|
|
16270
|
+
await git4(
|
|
15564
16271
|
folder,
|
|
15565
16272
|
["merge-base", `refs/remotes/origin/${baseBranch}`, "HEAD"],
|
|
15566
16273
|
timeoutMs,
|
|
@@ -15577,8 +16284,8 @@ async function inspectBranchChanges(folder, baseBranch, timeoutMs, signal) {
|
|
|
15577
16284
|
return { changes: files.slice(0, 500), truncated: files.length > 500 };
|
|
15578
16285
|
}
|
|
15579
16286
|
async function inspectCommits(folder, baseBranch, timeoutMs, signal) {
|
|
15580
|
-
const result =
|
|
15581
|
-
await
|
|
16287
|
+
const result = requireSuccess4(
|
|
16288
|
+
await git4(
|
|
15582
16289
|
folder,
|
|
15583
16290
|
[
|
|
15584
16291
|
"log",
|
|
@@ -15611,7 +16318,7 @@ async function inspectWorktreeDetail(folder, baseBranch, timeoutMs, signal) {
|
|
|
15611
16318
|
inspectCommits(folder, baseBranch, timeoutMs, signal),
|
|
15612
16319
|
inspectChanges(folder, timeoutMs, signal),
|
|
15613
16320
|
inspectBranchChanges(folder, baseBranch, timeoutMs, signal),
|
|
15614
|
-
|
|
16321
|
+
git4(
|
|
15615
16322
|
folder,
|
|
15616
16323
|
["config", "--bool", "--get", "commit.gpgsign"],
|
|
15617
16324
|
timeoutMs,
|
|
@@ -15629,8 +16336,8 @@ async function inspectWorktreeDetail(folder, baseBranch, timeoutMs, signal) {
|
|
|
15629
16336
|
};
|
|
15630
16337
|
}
|
|
15631
16338
|
async function baseMergeCommit(folder, baseBranch, timeoutMs, signal) {
|
|
15632
|
-
return
|
|
15633
|
-
await
|
|
16339
|
+
return requireSuccess4(
|
|
16340
|
+
await git4(
|
|
15634
16341
|
folder,
|
|
15635
16342
|
["merge-base", `refs/remotes/origin/${baseBranch}`, "HEAD"],
|
|
15636
16343
|
timeoutMs,
|
|
@@ -15645,13 +16352,13 @@ async function validateDisplayedCommit(folder, baseBranch, commitSha, timeoutMs,
|
|
|
15645
16352
|
}
|
|
15646
16353
|
const base = await baseMergeCommit(folder, baseBranch, timeoutMs, signal);
|
|
15647
16354
|
const [afterBase, beforeHead] = await Promise.all([
|
|
15648
|
-
|
|
16355
|
+
git4(
|
|
15649
16356
|
folder,
|
|
15650
16357
|
["merge-base", "--is-ancestor", base, commitSha],
|
|
15651
16358
|
timeoutMs,
|
|
15652
16359
|
signal
|
|
15653
16360
|
),
|
|
15654
|
-
|
|
16361
|
+
git4(
|
|
15655
16362
|
folder,
|
|
15656
16363
|
["merge-base", "--is-ancestor", commitSha, "HEAD"],
|
|
15657
16364
|
timeoutMs,
|
|
@@ -15663,7 +16370,7 @@ async function validateDisplayedCommit(folder, baseBranch, commitSha, timeoutMs,
|
|
|
15663
16370
|
}
|
|
15664
16371
|
}
|
|
15665
16372
|
async function parentCommit(folder, commitSha, timeoutMs, signal) {
|
|
15666
|
-
const result = await
|
|
16373
|
+
const result = await git4(
|
|
15667
16374
|
folder,
|
|
15668
16375
|
["rev-parse", `${commitSha}^`],
|
|
15669
16376
|
timeoutMs,
|
|
@@ -15672,13 +16379,13 @@ async function parentCommit(folder, commitSha, timeoutMs, signal) {
|
|
|
15672
16379
|
return result.exitCode === 0 ? result.stdout.trim() : null;
|
|
15673
16380
|
}
|
|
15674
16381
|
async function gitObjectExists(folder, specification, timeoutMs, signal) {
|
|
15675
|
-
return (await
|
|
16382
|
+
return (await git4(folder, ["cat-file", "-e", specification], timeoutMs, signal)).exitCode === 0;
|
|
15676
16383
|
}
|
|
15677
16384
|
async function comparisonSides(input, folder, timeoutMs, signal) {
|
|
15678
16385
|
if (!input.path) return { before: null, after: null };
|
|
15679
16386
|
const path = input.path;
|
|
15680
16387
|
const previousPath = input.previousPath ?? path;
|
|
15681
|
-
const currentPath =
|
|
16388
|
+
const currentPath = join14(folder, path);
|
|
15682
16389
|
if (input.scope === "UNTRACKED") {
|
|
15683
16390
|
return { before: null, after: { kind: "FILE", path: currentPath } };
|
|
15684
16391
|
}
|
|
@@ -15780,8 +16487,8 @@ async function availableSide(side, folder, timeoutMs, signal) {
|
|
|
15780
16487
|
return gitObjectExists(folder, side.specification, timeoutMs, signal);
|
|
15781
16488
|
}
|
|
15782
16489
|
try {
|
|
15783
|
-
const resolved = await
|
|
15784
|
-
const difference =
|
|
16490
|
+
const resolved = await realpath9(side.path);
|
|
16491
|
+
const difference = relative8(folder, resolved);
|
|
15785
16492
|
return difference !== ".." && !difference.startsWith("../") && (await stat10(resolved)).isFile();
|
|
15786
16493
|
} catch {
|
|
15787
16494
|
return false;
|
|
@@ -15853,7 +16560,7 @@ async function inspectRequestedDiff(input, folder, timeoutMs, signal) {
|
|
|
15853
16560
|
let patch;
|
|
15854
16561
|
if (input.scope === "UNTRACKED") {
|
|
15855
16562
|
const bounded = await readBoundedFile(
|
|
15856
|
-
|
|
16563
|
+
join14(folder, input.path),
|
|
15857
16564
|
MAX_DIFF_BYTES
|
|
15858
16565
|
);
|
|
15859
16566
|
const contents = bounded.contents;
|
|
@@ -15864,8 +16571,8 @@ async function inspectRequestedDiff(input, folder, timeoutMs, signal) {
|
|
|
15864
16571
|
patch = untrackedTextPatch(input.path, contents);
|
|
15865
16572
|
}
|
|
15866
16573
|
} else {
|
|
15867
|
-
patch =
|
|
15868
|
-
await
|
|
16574
|
+
patch = requireSuccess4(
|
|
16575
|
+
await git4(folder, args, timeoutMs, signal),
|
|
15869
16576
|
"Could not load the file diff"
|
|
15870
16577
|
).stdout;
|
|
15871
16578
|
}
|
|
@@ -15888,7 +16595,7 @@ async function validateChangedPath(input, folder, timeoutMs, signal) {
|
|
|
15888
16595
|
if (!input.path) throw new Error("A changed file path is required");
|
|
15889
16596
|
let result;
|
|
15890
16597
|
if (input.scope === "UNTRACKED") {
|
|
15891
|
-
result = await
|
|
16598
|
+
result = await git4(
|
|
15892
16599
|
folder,
|
|
15893
16600
|
["ls-files", "--others", "--exclude-standard", "-z", "--", input.path],
|
|
15894
16601
|
timeoutMs,
|
|
@@ -15919,9 +16626,9 @@ async function validateChangedPath(input, folder, timeoutMs, signal) {
|
|
|
15919
16626
|
);
|
|
15920
16627
|
}
|
|
15921
16628
|
args.push("--", ...requestedDiffPaths(input));
|
|
15922
|
-
result = await
|
|
16629
|
+
result = await git4(folder, args, timeoutMs, signal);
|
|
15923
16630
|
}
|
|
15924
|
-
|
|
16631
|
+
requireSuccess4(result, "Could not validate the changed file");
|
|
15925
16632
|
const requested = input.scope === "UNTRACKED" ? result.stdout.split("\0").filter(Boolean).includes(input.path) : parseNameStatus(result.stdout).some(
|
|
15926
16633
|
(file) => file.path === input.path && (!input.previousPath || file.previousPath === input.previousPath)
|
|
15927
16634
|
);
|
|
@@ -15986,7 +16693,7 @@ async function writeGitObject(folder, specification, destination, timeoutMs, sig
|
|
|
15986
16693
|
signal.removeEventListener("abort", abort);
|
|
15987
16694
|
if (settled) return;
|
|
15988
16695
|
if (code !== 0) {
|
|
15989
|
-
fail(new Error(
|
|
16696
|
+
fail(new Error(cleanError4(stderr || "Could not extract image")));
|
|
15990
16697
|
return;
|
|
15991
16698
|
}
|
|
15992
16699
|
output.end(() => {
|
|
@@ -16017,14 +16724,14 @@ var downloadWorktreeDiffAsset = async (payload, timeoutMs, signal, _onLog, conte
|
|
|
16017
16724
|
let temporaryDirectory = null;
|
|
16018
16725
|
try {
|
|
16019
16726
|
if (selected.kind === "FILE") {
|
|
16020
|
-
uploadPath = await
|
|
16021
|
-
const difference =
|
|
16727
|
+
uploadPath = await realpath9(selected.path);
|
|
16728
|
+
const difference = relative8(folder, uploadPath);
|
|
16022
16729
|
if (difference === ".." || difference.startsWith("../")) {
|
|
16023
16730
|
throw new Error("Diff image resolves outside the worktree");
|
|
16024
16731
|
}
|
|
16025
16732
|
} else {
|
|
16026
|
-
const size =
|
|
16027
|
-
await
|
|
16733
|
+
const size = requireSuccess4(
|
|
16734
|
+
await git4(
|
|
16028
16735
|
folder,
|
|
16029
16736
|
["cat-file", "-s", selected.specification],
|
|
16030
16737
|
timeoutMs,
|
|
@@ -16035,8 +16742,8 @@ var downloadWorktreeDiffAsset = async (payload, timeoutMs, signal, _onLog, conte
|
|
|
16035
16742
|
if (!/^\d+$/.test(size) || Number(size) > 20 * 1024 * 1024) {
|
|
16036
16743
|
throw new Error("Diff image exceeds the 20 MiB limit");
|
|
16037
16744
|
}
|
|
16038
|
-
temporaryDirectory = await mkdtemp6(
|
|
16039
|
-
uploadPath =
|
|
16745
|
+
temporaryDirectory = await mkdtemp6(join14(tmpdir6(), "ade-diff-image-"));
|
|
16746
|
+
uploadPath = join14(temporaryDirectory, basename5(input.path));
|
|
16040
16747
|
await writeGitObject(
|
|
16041
16748
|
folder,
|
|
16042
16749
|
selected.specification,
|
|
@@ -16058,7 +16765,7 @@ var downloadWorktreeDiffAsset = async (payload, timeoutMs, signal, _onLog, conte
|
|
|
16058
16765
|
return successfulProcess8;
|
|
16059
16766
|
} finally {
|
|
16060
16767
|
if (temporaryDirectory) {
|
|
16061
|
-
await
|
|
16768
|
+
await rm10(temporaryDirectory, { recursive: true, force: true });
|
|
16062
16769
|
}
|
|
16063
16770
|
}
|
|
16064
16771
|
};
|
|
@@ -16154,7 +16861,7 @@ var inspectWorktreeGit = async (payload, timeoutMs, signal) => {
|
|
|
16154
16861
|
var commitWorktree = async (payload, timeoutMs, signal) => {
|
|
16155
16862
|
const input = worktreeCommitJobPayload(payload);
|
|
16156
16863
|
const folder = await validateWorktree2(input, timeoutMs, signal);
|
|
16157
|
-
const runGit = async (args, fallback) =>
|
|
16864
|
+
const runGit = async (args, fallback) => requireSuccess4(await git4(folder, args, timeoutMs, signal), fallback);
|
|
16158
16865
|
if (input.stageAll) {
|
|
16159
16866
|
await runGit(["add", "--all"], "Could not stage worktree changes");
|
|
16160
16867
|
} else {
|
|
@@ -16167,7 +16874,7 @@ var commitWorktree = async (payload, timeoutMs, signal) => {
|
|
|
16167
16874
|
if (!change) throw new Error(`Worktree change no longer exists: ${path}`);
|
|
16168
16875
|
return change;
|
|
16169
16876
|
});
|
|
16170
|
-
const head = await
|
|
16877
|
+
const head = await git4(
|
|
16171
16878
|
folder,
|
|
16172
16879
|
["rev-parse", "--verify", "HEAD"],
|
|
16173
16880
|
timeoutMs,
|
|
@@ -16196,7 +16903,7 @@ var commitWorktree = async (payload, timeoutMs, signal) => {
|
|
|
16196
16903
|
"Could not stage selected worktree changes"
|
|
16197
16904
|
);
|
|
16198
16905
|
}
|
|
16199
|
-
const staged = await
|
|
16906
|
+
const staged = await git4(
|
|
16200
16907
|
folder,
|
|
16201
16908
|
["diff", "--cached", "--quiet", "--exit-code"],
|
|
16202
16909
|
timeoutMs,
|
|
@@ -16204,10 +16911,10 @@ var commitWorktree = async (payload, timeoutMs, signal) => {
|
|
|
16204
16911
|
);
|
|
16205
16912
|
if (staged.exitCode === 0) throw new Error("No staged changes to commit");
|
|
16206
16913
|
if (staged.exitCode !== 1)
|
|
16207
|
-
|
|
16914
|
+
requireSuccess4(staged, "Could not inspect staged changes");
|
|
16208
16915
|
let signed = input.signed;
|
|
16209
16916
|
if (signed === null) {
|
|
16210
|
-
const configured = await
|
|
16917
|
+
const configured = await git4(
|
|
16211
16918
|
folder,
|
|
16212
16919
|
["config", "--bool", "--get", "commit.gpgsign"],
|
|
16213
16920
|
timeoutMs,
|
|
@@ -16264,7 +16971,7 @@ var operateWorktreeGit = async (payload, timeoutMs, signal) => {
|
|
|
16264
16971
|
};
|
|
16265
16972
|
};
|
|
16266
16973
|
async function refExists(folder, ref, timeoutMs, signal) {
|
|
16267
|
-
const result = await
|
|
16974
|
+
const result = await git4(
|
|
16268
16975
|
folder,
|
|
16269
16976
|
["show-ref", "--verify", "--quiet", ref],
|
|
16270
16977
|
timeoutMs,
|
|
@@ -16273,13 +16980,13 @@ async function refExists(folder, ref, timeoutMs, signal) {
|
|
|
16273
16980
|
return result.exitCode === 0;
|
|
16274
16981
|
}
|
|
16275
16982
|
async function resolveHead(folder, ref, timeoutMs, signal) {
|
|
16276
|
-
return
|
|
16277
|
-
await
|
|
16983
|
+
return requireSuccess4(
|
|
16984
|
+
await git4(folder, ["rev-parse", ref], timeoutMs, signal),
|
|
16278
16985
|
`Could not resolve ${ref}`
|
|
16279
16986
|
).stdout.trim();
|
|
16280
16987
|
}
|
|
16281
16988
|
async function isAncestor(folder, ancestor, descendant, timeoutMs, signal) {
|
|
16282
|
-
const result = await
|
|
16989
|
+
const result = await git4(
|
|
16283
16990
|
folder,
|
|
16284
16991
|
["merge-base", "--is-ancestor", ancestor, descendant],
|
|
16285
16992
|
timeoutMs,
|
|
@@ -16287,12 +16994,12 @@ async function isAncestor(folder, ancestor, descendant, timeoutMs, signal) {
|
|
|
16287
16994
|
);
|
|
16288
16995
|
if (result.exitCode === 0) return true;
|
|
16289
16996
|
if (result.exitCode === 1) return false;
|
|
16290
|
-
|
|
16997
|
+
requireSuccess4(result, "Could not compare Git history");
|
|
16291
16998
|
return false;
|
|
16292
16999
|
}
|
|
16293
17000
|
async function statusState(folder, timeoutMs, signal) {
|
|
16294
|
-
const result =
|
|
16295
|
-
await
|
|
17001
|
+
const result = requireSuccess4(
|
|
17002
|
+
await git4(
|
|
16296
17003
|
folder,
|
|
16297
17004
|
["status", "--porcelain=v1", "-z", "--untracked-files=all"],
|
|
16298
17005
|
timeoutMs,
|
|
@@ -16306,7 +17013,7 @@ function hasChanges(changes) {
|
|
|
16306
17013
|
return changes.hasStagedChanges || changes.hasUnstagedChanges;
|
|
16307
17014
|
}
|
|
16308
17015
|
async function currentBranch(folder, timeoutMs, signal) {
|
|
16309
|
-
const result = await
|
|
17016
|
+
const result = await git4(
|
|
16310
17017
|
folder,
|
|
16311
17018
|
["symbolic-ref", "--short", "-q", "HEAD"],
|
|
16312
17019
|
timeoutMs,
|
|
@@ -16326,7 +17033,7 @@ async function chooseNewBranch(folder, candidates, allowedCurrentBranch, timeout
|
|
|
16326
17033
|
throw new Error("Every generated ticket branch name is already taken");
|
|
16327
17034
|
}
|
|
16328
17035
|
async function validateBranchRoot(input, timeoutMs, signal) {
|
|
16329
|
-
const rootFolder = await
|
|
17036
|
+
const rootFolder = await realpath9(input.rootFolder);
|
|
16330
17037
|
if (!(await stat10(rootFolder)).isDirectory()) {
|
|
16331
17038
|
throw new Error("Base repository is missing");
|
|
16332
17039
|
}
|
|
@@ -16390,8 +17097,8 @@ var branchWorktree = async (payload, timeoutMs, signal) => {
|
|
|
16390
17097
|
timeoutMs,
|
|
16391
17098
|
signal
|
|
16392
17099
|
) : input.candidates[0];
|
|
16393
|
-
const targetFolder = input.action === "CREATE" ?
|
|
16394
|
-
|
|
17100
|
+
const targetFolder = input.action === "CREATE" ? join14(
|
|
17101
|
+
dirname8(rootFolder),
|
|
16395
17102
|
`${basename5(rootFolder)}-${branch.replaceAll("/", "-")}`
|
|
16396
17103
|
) : changeFolder;
|
|
16397
17104
|
if (input.action === "CREATE") {
|
|
@@ -16436,40 +17143,89 @@ var branchWorktree = async (payload, timeoutMs, signal) => {
|
|
|
16436
17143
|
];
|
|
16437
17144
|
}
|
|
16438
17145
|
let stashed = false;
|
|
16439
|
-
|
|
16440
|
-
|
|
16441
|
-
|
|
16442
|
-
|
|
17146
|
+
let preparationsSuspended = false;
|
|
17147
|
+
const reapplyPreparations = () => executeWorktreePreparations(
|
|
17148
|
+
targetFolder,
|
|
17149
|
+
input.preparations,
|
|
17150
|
+
"APPLY",
|
|
17151
|
+
timeoutMs,
|
|
17152
|
+
signal
|
|
17153
|
+
);
|
|
17154
|
+
if (args.length > 0 && input.action === "CHANGE" && input.preparations.length > 0) {
|
|
17155
|
+
const suspended = await suspendWorktreePreparations(
|
|
17156
|
+
targetFolder,
|
|
17157
|
+
input.preparations,
|
|
16443
17158
|
timeoutMs,
|
|
16444
|
-
signal
|
|
17159
|
+
signal,
|
|
17160
|
+
true
|
|
16445
17161
|
);
|
|
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"
|
|
17162
|
+
preparationsSuspended = true;
|
|
17163
|
+
const failed = suspended.filter((item) => item.state === "ERROR");
|
|
17164
|
+
if (failed.length > 0) {
|
|
17165
|
+
await reapplyPreparations();
|
|
17166
|
+
throw new Error(
|
|
17167
|
+
failed.map((item) => item.message ?? "Preparation failed").join("; ")
|
|
16461
17168
|
);
|
|
16462
|
-
|
|
16463
|
-
|
|
16464
|
-
|
|
16465
|
-
|
|
16466
|
-
|
|
17169
|
+
}
|
|
17170
|
+
}
|
|
17171
|
+
if (args.length > 0) {
|
|
17172
|
+
try {
|
|
17173
|
+
let switched = await git4(
|
|
17174
|
+
input.action === "CREATE" ? rootFolder : targetFolder,
|
|
17175
|
+
args,
|
|
17176
|
+
timeoutMs,
|
|
17177
|
+
signal
|
|
17178
|
+
);
|
|
17179
|
+
if (switched.exitCode !== 0 && input.action === "CHANGE" && input.stashOnFailure) {
|
|
17180
|
+
const stash = requireSuccess4(
|
|
17181
|
+
await git4(
|
|
17182
|
+
targetFolder,
|
|
17183
|
+
[
|
|
17184
|
+
"stash",
|
|
17185
|
+
"push",
|
|
17186
|
+
"--include-untracked",
|
|
17187
|
+
"-m",
|
|
17188
|
+
`Automatic stash before switching to ${branch}`
|
|
17189
|
+
],
|
|
17190
|
+
timeoutMs,
|
|
17191
|
+
signal
|
|
17192
|
+
),
|
|
17193
|
+
"Could not stash worktree changes"
|
|
17194
|
+
);
|
|
17195
|
+
stashed = !stash.stdout.toLowerCase().includes("no local changes");
|
|
17196
|
+
switched = await git4(targetFolder, args, timeoutMs, signal);
|
|
17197
|
+
if (switched.exitCode !== 0) {
|
|
17198
|
+
throw new Error(
|
|
17199
|
+
`${cleanError4(switched.stderr || "Branch switch failed after stashing")}. The stash was preserved.`
|
|
17200
|
+
);
|
|
17201
|
+
}
|
|
17202
|
+
} else {
|
|
17203
|
+
requireSuccess4(
|
|
17204
|
+
switched,
|
|
17205
|
+
input.action === "CREATE" ? "Could not create the worktree" : "Could not change the worktree branch"
|
|
16467
17206
|
);
|
|
16468
17207
|
}
|
|
16469
|
-
}
|
|
16470
|
-
|
|
16471
|
-
|
|
16472
|
-
|
|
17208
|
+
} catch (error) {
|
|
17209
|
+
if (preparationsSuspended) await reapplyPreparations();
|
|
17210
|
+
throw error;
|
|
17211
|
+
}
|
|
17212
|
+
}
|
|
17213
|
+
let preparations = [];
|
|
17214
|
+
if (input.preparations.length > 0) {
|
|
17215
|
+
preparations = await reapplyPreparations();
|
|
17216
|
+
const failed = preparations.filter((item) => item.state === "ERROR");
|
|
17217
|
+
if (failed.length > 0 && input.action === "CREATE") {
|
|
17218
|
+
await git4(
|
|
17219
|
+
rootFolder,
|
|
17220
|
+
["worktree", "remove", "--force", targetFolder],
|
|
17221
|
+
timeoutMs,
|
|
17222
|
+
signal
|
|
17223
|
+
);
|
|
17224
|
+
if (input.mode === "NEW") {
|
|
17225
|
+
await git4(rootFolder, ["branch", "-D", branch], timeoutMs, signal);
|
|
17226
|
+
}
|
|
17227
|
+
throw new Error(
|
|
17228
|
+
failed.map((item) => item.message ?? "Preparation failed").join("; ")
|
|
16473
17229
|
);
|
|
16474
17230
|
}
|
|
16475
17231
|
}
|
|
@@ -16489,7 +17245,9 @@ var branchWorktree = async (payload, timeoutMs, signal) => {
|
|
|
16489
17245
|
worktree,
|
|
16490
17246
|
branch,
|
|
16491
17247
|
baseBranch: input.baseBranch,
|
|
16492
|
-
stashed
|
|
17248
|
+
stashed,
|
|
17249
|
+
checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
17250
|
+
preparations
|
|
16493
17251
|
};
|
|
16494
17252
|
};
|
|
16495
17253
|
var pushMovedWorktree = async (payload, timeoutMs, signal) => {
|
|
@@ -16516,8 +17274,8 @@ var pushMovedWorktree = async (payload, timeoutMs, signal) => {
|
|
|
16516
17274
|
if (hasChanges(changes)) {
|
|
16517
17275
|
throw new Error("Commit or discard source changes before moving");
|
|
16518
17276
|
}
|
|
16519
|
-
|
|
16520
|
-
await
|
|
17277
|
+
requireSuccess4(
|
|
17278
|
+
await git4(folder, ["fetch", "origin"], timeoutMs, signal),
|
|
16521
17279
|
"Could not fetch origin before moving"
|
|
16522
17280
|
);
|
|
16523
17281
|
const remoteRef = `refs/remotes/origin/${branch}`;
|
|
@@ -16526,8 +17284,8 @@ var pushMovedWorktree = async (payload, timeoutMs, signal) => {
|
|
|
16526
17284
|
"The origin branch contains commits that must be pulled before moving"
|
|
16527
17285
|
);
|
|
16528
17286
|
}
|
|
16529
|
-
|
|
16530
|
-
await
|
|
17287
|
+
requireSuccess4(
|
|
17288
|
+
await git4(
|
|
16531
17289
|
folder,
|
|
16532
17290
|
["push", "--set-upstream", "origin", `HEAD:refs/heads/${branch}`],
|
|
16533
17291
|
timeoutMs,
|
|
@@ -16562,8 +17320,8 @@ async function updateLocalBranchForMove(rootFolder, branch, expectedHeadSha, tim
|
|
|
16562
17320
|
`Local branch ${branch} has commits that are not on origin; move them before retrying`
|
|
16563
17321
|
);
|
|
16564
17322
|
}
|
|
16565
|
-
|
|
16566
|
-
await
|
|
17323
|
+
requireSuccess4(
|
|
17324
|
+
await git4(
|
|
16567
17325
|
rootFolder,
|
|
16568
17326
|
["branch", "-f", branch, expectedHeadSha],
|
|
16569
17327
|
timeoutMs,
|
|
@@ -16574,8 +17332,8 @@ async function updateLocalBranchForMove(rootFolder, branch, expectedHeadSha, tim
|
|
|
16574
17332
|
return true;
|
|
16575
17333
|
}
|
|
16576
17334
|
async function checkedOutBranchFolder(rootFolder, branch, timeoutMs, signal) {
|
|
16577
|
-
const result =
|
|
16578
|
-
await
|
|
17335
|
+
const result = requireSuccess4(
|
|
17336
|
+
await git4(
|
|
16579
17337
|
rootFolder,
|
|
16580
17338
|
["worktree", "list", "--porcelain"],
|
|
16581
17339
|
timeoutMs,
|
|
@@ -16591,8 +17349,8 @@ var checkoutMovedWorktree = async (payload, timeoutMs, signal) => {
|
|
|
16591
17349
|
const input = worktreeMoveCheckoutJobPayload(payload);
|
|
16592
17350
|
const rootFolder = await validateBranchRoot(input, timeoutMs, signal);
|
|
16593
17351
|
const remoteRef = `refs/remotes/origin/${input.branch}`;
|
|
16594
|
-
|
|
16595
|
-
await
|
|
17352
|
+
requireSuccess4(
|
|
17353
|
+
await git4(
|
|
16596
17354
|
rootFolder,
|
|
16597
17355
|
[
|
|
16598
17356
|
"fetch",
|
|
@@ -16617,6 +17375,7 @@ var checkoutMovedWorktree = async (payload, timeoutMs, signal) => {
|
|
|
16617
17375
|
);
|
|
16618
17376
|
}
|
|
16619
17377
|
let targetFolder;
|
|
17378
|
+
let createdLocalBranch = false;
|
|
16620
17379
|
let stashed = false;
|
|
16621
17380
|
const occupiedFolder = await checkedOutBranchFolder(
|
|
16622
17381
|
rootFolder,
|
|
@@ -16630,8 +17389,8 @@ var checkoutMovedWorktree = async (payload, timeoutMs, signal) => {
|
|
|
16630
17389
|
`Branch ${input.branch} is already checked out in ${occupiedFolder}`
|
|
16631
17390
|
);
|
|
16632
17391
|
}
|
|
16633
|
-
targetFolder =
|
|
16634
|
-
|
|
17392
|
+
targetFolder = join14(
|
|
17393
|
+
dirname8(rootFolder),
|
|
16635
17394
|
`${basename5(rootFolder)}-${input.branch.replaceAll("/", "-")}`
|
|
16636
17395
|
);
|
|
16637
17396
|
try {
|
|
@@ -16649,8 +17408,9 @@ var checkoutMovedWorktree = async (payload, timeoutMs, signal) => {
|
|
|
16649
17408
|
timeoutMs,
|
|
16650
17409
|
signal
|
|
16651
17410
|
);
|
|
16652
|
-
|
|
16653
|
-
|
|
17411
|
+
createdLocalBranch = !local;
|
|
17412
|
+
requireSuccess4(
|
|
17413
|
+
await git4(
|
|
16654
17414
|
rootFolder,
|
|
16655
17415
|
local ? ["worktree", "add", targetFolder, input.branch] : [
|
|
16656
17416
|
"worktree",
|
|
@@ -16681,7 +17441,7 @@ var checkoutMovedWorktree = async (payload, timeoutMs, signal) => {
|
|
|
16681
17441
|
const targetBranch = await currentBranch(targetFolder, timeoutMs, signal);
|
|
16682
17442
|
const targetChanges = await statusState(targetFolder, timeoutMs, signal);
|
|
16683
17443
|
if (occupiedFolder) {
|
|
16684
|
-
const occupied = await
|
|
17444
|
+
const occupied = await realpath9(occupiedFolder);
|
|
16685
17445
|
if (occupied !== targetFolder) {
|
|
16686
17446
|
throw new Error(
|
|
16687
17447
|
`Branch ${input.branch} is checked out in another destination worktree`
|
|
@@ -16719,8 +17479,8 @@ var checkoutMovedWorktree = async (payload, timeoutMs, signal) => {
|
|
|
16719
17479
|
switchArgs = local ? ["switch", input.branch] : ["switch", "--track", "-c", input.branch, remoteRef];
|
|
16720
17480
|
}
|
|
16721
17481
|
if (input.stashOnFailure && hasChanges(targetChanges)) {
|
|
16722
|
-
const stash =
|
|
16723
|
-
await
|
|
17482
|
+
const stash = requireSuccess4(
|
|
17483
|
+
await git4(
|
|
16724
17484
|
targetFolder,
|
|
16725
17485
|
[
|
|
16726
17486
|
"stash",
|
|
@@ -16736,25 +17496,25 @@ var checkoutMovedWorktree = async (payload, timeoutMs, signal) => {
|
|
|
16736
17496
|
);
|
|
16737
17497
|
stashed = !stash.stdout.toLowerCase().includes("no local changes");
|
|
16738
17498
|
}
|
|
16739
|
-
const switched = await
|
|
17499
|
+
const switched = await git4(targetFolder, switchArgs, timeoutMs, signal);
|
|
16740
17500
|
if (switched.exitCode !== 0) {
|
|
16741
17501
|
if (!input.stashOnFailure && hasChanges(targetChanges)) {
|
|
16742
17502
|
return {
|
|
16743
17503
|
...successfulProcess8,
|
|
16744
17504
|
moveId: input.moveId,
|
|
16745
17505
|
outcome: "NEEDS_STASH",
|
|
16746
|
-
message:
|
|
17506
|
+
message: cleanError4(
|
|
16747
17507
|
switched.stderr || "Destination changes block the branch switch"
|
|
16748
17508
|
)
|
|
16749
17509
|
};
|
|
16750
17510
|
}
|
|
16751
17511
|
throw new Error(
|
|
16752
|
-
`${
|
|
17512
|
+
`${cleanError4(switched.stderr || "Could not check out the moved branch")}${stashed ? ". The destination stash was preserved." : ""}`
|
|
16753
17513
|
);
|
|
16754
17514
|
}
|
|
16755
17515
|
}
|
|
16756
|
-
|
|
16757
|
-
await
|
|
17516
|
+
requireSuccess4(
|
|
17517
|
+
await git4(
|
|
16758
17518
|
targetFolder,
|
|
16759
17519
|
["branch", "--set-upstream-to", `origin/${input.branch}`, input.branch],
|
|
16760
17520
|
timeoutMs,
|
|
@@ -16771,6 +17531,30 @@ var checkoutMovedWorktree = async (payload, timeoutMs, signal) => {
|
|
|
16771
17531
|
if (checkedOutHead !== input.expectedHeadSha) {
|
|
16772
17532
|
throw new Error("The destination did not check out the pushed commit");
|
|
16773
17533
|
}
|
|
17534
|
+
const preparations = await executeWorktreePreparations(
|
|
17535
|
+
targetFolder,
|
|
17536
|
+
input.preparations,
|
|
17537
|
+
"APPLY",
|
|
17538
|
+
timeoutMs,
|
|
17539
|
+
signal
|
|
17540
|
+
);
|
|
17541
|
+
const preparationErrors = preparations.filter(
|
|
17542
|
+
(item) => item.state === "ERROR"
|
|
17543
|
+
);
|
|
17544
|
+
if (preparationErrors.length > 0 && input.mode === "NEW") {
|
|
17545
|
+
await git4(
|
|
17546
|
+
rootFolder,
|
|
17547
|
+
["worktree", "remove", "--force", targetFolder],
|
|
17548
|
+
timeoutMs,
|
|
17549
|
+
signal
|
|
17550
|
+
);
|
|
17551
|
+
if (createdLocalBranch) {
|
|
17552
|
+
await git4(rootFolder, ["branch", "-D", input.branch], timeoutMs, signal);
|
|
17553
|
+
}
|
|
17554
|
+
throw new Error(
|
|
17555
|
+
preparationErrors.map((item) => item.message ?? "Preparation failed").join("; ")
|
|
17556
|
+
);
|
|
17557
|
+
}
|
|
16774
17558
|
const worktree = await inspectWorktreeItem(
|
|
16775
17559
|
targetFolder,
|
|
16776
17560
|
rootFolder,
|
|
@@ -16790,12 +17574,72 @@ var checkoutMovedWorktree = async (payload, timeoutMs, signal) => {
|
|
|
16790
17574
|
outcome: "CHECKED_OUT",
|
|
16791
17575
|
worktree,
|
|
16792
17576
|
baseBranch: input.baseBranch,
|
|
16793
|
-
stashed
|
|
17577
|
+
stashed,
|
|
17578
|
+
checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
17579
|
+
preparations
|
|
17580
|
+
};
|
|
17581
|
+
};
|
|
17582
|
+
var prepareWorktree = async (payload, timeoutMs, signal) => {
|
|
17583
|
+
const input = worktreePreparationJobPayload(payload);
|
|
17584
|
+
if ("worktrees" in input) {
|
|
17585
|
+
const worktrees = [];
|
|
17586
|
+
for (const target2 of input.worktrees) {
|
|
17587
|
+
try {
|
|
17588
|
+
const folder2 = await validateWorktree2(
|
|
17589
|
+
{
|
|
17590
|
+
codebaseId: input.codebaseId,
|
|
17591
|
+
folder: target2.folder,
|
|
17592
|
+
gitDirectory: target2.gitDirectory,
|
|
17593
|
+
expectedOrigin: input.expectedOrigin,
|
|
17594
|
+
baseBranch: null
|
|
17595
|
+
},
|
|
17596
|
+
timeoutMs,
|
|
17597
|
+
signal
|
|
17598
|
+
);
|
|
17599
|
+
const preparations2 = await executeWorktreePreparations(
|
|
17600
|
+
folder2,
|
|
17601
|
+
input.preparations,
|
|
17602
|
+
input.action,
|
|
17603
|
+
timeoutMs,
|
|
17604
|
+
signal
|
|
17605
|
+
);
|
|
17606
|
+
worktrees.push({
|
|
17607
|
+
worktreeId: target2.worktreeId,
|
|
17608
|
+
checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
17609
|
+
preparations: preparations2
|
|
17610
|
+
});
|
|
17611
|
+
} catch (error) {
|
|
17612
|
+
worktrees.push({
|
|
17613
|
+
worktreeId: target2.worktreeId,
|
|
17614
|
+
checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
17615
|
+
preparations: input.preparations.map((definition) => ({
|
|
17616
|
+
id: definition.id,
|
|
17617
|
+
definitionHash: definition.definitionHash,
|
|
17618
|
+
state: "ERROR",
|
|
17619
|
+
message: cleanError4(error)
|
|
17620
|
+
}))
|
|
17621
|
+
});
|
|
17622
|
+
}
|
|
17623
|
+
}
|
|
17624
|
+
return { ...successfulProcess8, worktrees };
|
|
17625
|
+
}
|
|
17626
|
+
const folder = await validateWorktree2(input, timeoutMs, signal);
|
|
17627
|
+
const preparations = await executeWorktreePreparations(
|
|
17628
|
+
folder,
|
|
17629
|
+
input.preparations,
|
|
17630
|
+
input.action,
|
|
17631
|
+
timeoutMs,
|
|
17632
|
+
signal
|
|
17633
|
+
);
|
|
17634
|
+
return {
|
|
17635
|
+
...successfulProcess8,
|
|
17636
|
+
checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
17637
|
+
preparations
|
|
16794
17638
|
};
|
|
16795
17639
|
};
|
|
16796
17640
|
var deleteWorktree = async (payload, timeoutMs, signal) => {
|
|
16797
17641
|
const input = worktreeDeleteJobPayload(payload);
|
|
16798
|
-
const rootFolder = await
|
|
17642
|
+
const rootFolder = await realpath9(input.rootFolder);
|
|
16799
17643
|
if (!(await stat10(rootFolder)).isDirectory()) {
|
|
16800
17644
|
throw new Error("Base repository is missing");
|
|
16801
17645
|
}
|
|
@@ -16816,8 +17660,8 @@ var deleteWorktree = async (payload, timeoutMs, signal) => {
|
|
|
16816
17660
|
if (folder === rootFolder)
|
|
16817
17661
|
throw new Error("The primary worktree cannot be deleted");
|
|
16818
17662
|
const listed = parseWorktreeList(
|
|
16819
|
-
|
|
16820
|
-
await
|
|
17663
|
+
requireSuccess4(
|
|
17664
|
+
await git4(
|
|
16821
17665
|
rootFolder,
|
|
16822
17666
|
["worktree", "list", "--porcelain"],
|
|
16823
17667
|
timeoutMs,
|
|
@@ -16847,15 +17691,15 @@ var deleteWorktree = async (payload, timeoutMs, signal) => {
|
|
|
16847
17691
|
if (branch === input.defaultBranch) {
|
|
16848
17692
|
throw new Error("The default remote branch cannot be deleted");
|
|
16849
17693
|
}
|
|
16850
|
-
const remote = await
|
|
17694
|
+
const remote = await git4(
|
|
16851
17695
|
rootFolder,
|
|
16852
17696
|
["ls-remote", "--exit-code", "--heads", "origin", `refs/heads/${branch}`],
|
|
16853
17697
|
timeoutMs,
|
|
16854
17698
|
signal
|
|
16855
17699
|
);
|
|
16856
17700
|
if (remote.exitCode === 0) {
|
|
16857
|
-
|
|
16858
|
-
await
|
|
17701
|
+
requireSuccess4(
|
|
17702
|
+
await git4(
|
|
16859
17703
|
rootFolder,
|
|
16860
17704
|
["push", "origin", "--delete", branch],
|
|
16861
17705
|
timeoutMs,
|
|
@@ -16864,11 +17708,11 @@ var deleteWorktree = async (payload, timeoutMs, signal) => {
|
|
|
16864
17708
|
`Could not delete origin/${branch}`
|
|
16865
17709
|
);
|
|
16866
17710
|
} else if (remote.exitCode !== 2) {
|
|
16867
|
-
|
|
17711
|
+
requireSuccess4(remote, `Could not inspect origin/${branch}`);
|
|
16868
17712
|
}
|
|
16869
17713
|
}
|
|
16870
|
-
|
|
16871
|
-
await
|
|
17714
|
+
requireSuccess4(
|
|
17715
|
+
await git4(
|
|
16872
17716
|
rootFolder,
|
|
16873
17717
|
["worktree", "remove", "--force", folder],
|
|
16874
17718
|
timeoutMs,
|
|
@@ -16877,8 +17721,8 @@ var deleteWorktree = async (payload, timeoutMs, signal) => {
|
|
|
16877
17721
|
"Could not remove the worktree"
|
|
16878
17722
|
);
|
|
16879
17723
|
if (branch && await refExists(rootFolder, `refs/heads/${branch}`, timeoutMs, signal)) {
|
|
16880
|
-
|
|
16881
|
-
await
|
|
17724
|
+
requireSuccess4(
|
|
17725
|
+
await git4(rootFolder, ["branch", "-D", branch], timeoutMs, signal),
|
|
16882
17726
|
`Worktree removed, but local branch ${branch} could not be deleted`
|
|
16883
17727
|
);
|
|
16884
17728
|
}
|
|
@@ -16894,28 +17738,53 @@ var operateWorktree = async (payload, timeoutMs, signal) => {
|
|
|
16894
17738
|
const input = worktreeJobPayload(payload);
|
|
16895
17739
|
const folder = await validateWorktree2(input, timeoutMs, signal);
|
|
16896
17740
|
if (!input.operation) throw new Error("A worktree operation is required");
|
|
16897
|
-
const branchResult = await
|
|
17741
|
+
const branchResult = await git4(
|
|
16898
17742
|
folder,
|
|
16899
17743
|
["symbolic-ref", "--short", "-q", "HEAD"],
|
|
16900
17744
|
timeoutMs,
|
|
16901
17745
|
signal
|
|
16902
17746
|
);
|
|
16903
17747
|
const branch = branchResult.exitCode === 0 ? branchResult.stdout.trim() : null;
|
|
16904
|
-
const upstreamResult = branch ? await
|
|
17748
|
+
const upstreamResult = branch ? await git4(
|
|
16905
17749
|
folder,
|
|
16906
17750
|
["rev-parse", "--abbrev-ref", "@{upstream}"],
|
|
16907
17751
|
timeoutMs,
|
|
16908
17752
|
signal
|
|
16909
17753
|
) : null;
|
|
16910
17754
|
const upstream = upstreamResult?.exitCode === 0 ? upstreamResult.stdout.trim() : null;
|
|
16911
|
-
const runGit = async (args, fallback) =>
|
|
17755
|
+
const runGit = async (args, fallback) => requireSuccess4(await git4(folder, args, timeoutMs, signal), fallback);
|
|
17756
|
+
let operationOutcome = "COMPLETED";
|
|
17757
|
+
let preparationConflictPathList = [];
|
|
17758
|
+
let preparationResults = [];
|
|
17759
|
+
const inspectPreparations = () => executeWorktreePreparations(
|
|
17760
|
+
folder,
|
|
17761
|
+
input.preparations,
|
|
17762
|
+
"INSPECT",
|
|
17763
|
+
timeoutMs,
|
|
17764
|
+
signal
|
|
17765
|
+
);
|
|
17766
|
+
const reapplyPreparations = () => executeWorktreePreparations(
|
|
17767
|
+
folder,
|
|
17768
|
+
input.preparations,
|
|
17769
|
+
"APPLY",
|
|
17770
|
+
timeoutMs,
|
|
17771
|
+
signal
|
|
17772
|
+
);
|
|
17773
|
+
const worktreeResult = async () => inspectWorktreeItem(
|
|
17774
|
+
folder,
|
|
17775
|
+
folder,
|
|
17776
|
+
input.baseBranch,
|
|
17777
|
+
false,
|
|
17778
|
+
Math.min(timeoutMs, 3e4),
|
|
17779
|
+
signal
|
|
17780
|
+
);
|
|
16912
17781
|
switch (input.operation) {
|
|
16913
17782
|
case "OPEN_EDITOR": {
|
|
16914
17783
|
if (input.editorVariant === "NONE" || !input.editorVariant) {
|
|
16915
17784
|
throw new Error("VS Code is disabled in Settings");
|
|
16916
17785
|
}
|
|
16917
17786
|
const app = input.editorVariant === "CODE_INSIDERS" ? "Visual Studio Code - Insiders" : "Visual Studio Code";
|
|
16918
|
-
|
|
17787
|
+
requireSuccess4(
|
|
16919
17788
|
await command2("open", ["-a", app, folder], timeoutMs, signal),
|
|
16920
17789
|
`${app} could not be opened`
|
|
16921
17790
|
);
|
|
@@ -16937,26 +17806,105 @@ var operateWorktree = async (payload, timeoutMs, signal) => {
|
|
|
16937
17806
|
if (statusResult.stdout.trim())
|
|
16938
17807
|
throw new Error("Stash or commit changes before syncing");
|
|
16939
17808
|
await runGit(["fetch", "origin"], "Could not fetch origin");
|
|
16940
|
-
const
|
|
17809
|
+
const remoteBase = `refs/remotes/origin/${input.baseBranch}`;
|
|
17810
|
+
const isCurrent = await git4(
|
|
16941
17811
|
folder,
|
|
16942
|
-
["
|
|
17812
|
+
["merge-base", "--is-ancestor", remoteBase, "HEAD"],
|
|
16943
17813
|
timeoutMs,
|
|
16944
17814
|
signal
|
|
16945
17815
|
);
|
|
16946
|
-
if (
|
|
16947
|
-
|
|
17816
|
+
if (isCurrent.exitCode !== 0 && isCurrent.exitCode !== 1) {
|
|
17817
|
+
requireSuccess4(isCurrent, "Could not compare the base branch");
|
|
17818
|
+
}
|
|
17819
|
+
if (isCurrent.exitCode === 1) {
|
|
17820
|
+
preparationConflictPathList = await preparationConflictPaths(
|
|
17821
|
+
folder,
|
|
17822
|
+
input.preparations,
|
|
17823
|
+
remoteBase,
|
|
17824
|
+
timeoutMs,
|
|
17825
|
+
signal
|
|
17826
|
+
);
|
|
17827
|
+
if (preparationConflictPathList.length > 0 && !input.forcePreparations) {
|
|
17828
|
+
operationOutcome = "PREPARATION_CONFLICT";
|
|
17829
|
+
preparationResults = await inspectPreparations();
|
|
17830
|
+
return {
|
|
17831
|
+
...successfulProcess8,
|
|
17832
|
+
outcome: operationOutcome,
|
|
17833
|
+
preparationConflictPaths: preparationConflictPathList,
|
|
17834
|
+
checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
17835
|
+
preparations: preparationResults,
|
|
17836
|
+
worktree: await worktreeResult()
|
|
17837
|
+
};
|
|
17838
|
+
}
|
|
17839
|
+
if (input.forcePreparations) {
|
|
17840
|
+
preparationResults = await suspendWorktreePreparations(
|
|
17841
|
+
folder,
|
|
17842
|
+
input.preparations,
|
|
17843
|
+
timeoutMs,
|
|
17844
|
+
signal
|
|
17845
|
+
);
|
|
17846
|
+
if (preparationResults.some((item) => item.state === "ERROR")) {
|
|
17847
|
+
return {
|
|
17848
|
+
...successfulProcess8,
|
|
17849
|
+
exitCode: 1,
|
|
17850
|
+
checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
17851
|
+
preparations: preparationResults
|
|
17852
|
+
};
|
|
17853
|
+
}
|
|
17854
|
+
}
|
|
17855
|
+
}
|
|
17856
|
+
const rebase = isCurrent.exitCode === 0 ? null : await git4(folder, ["rebase", remoteBase], timeoutMs, signal);
|
|
17857
|
+
if (rebase && rebase.exitCode !== 0) {
|
|
17858
|
+
const status2 = await git4(
|
|
16948
17859
|
folder,
|
|
16949
17860
|
["status", "--porcelain=v1", "-z"],
|
|
16950
17861
|
timeoutMs,
|
|
16951
17862
|
signal
|
|
16952
17863
|
);
|
|
16953
17864
|
const conflicts = status2.exitCode === 0 && statusChangeState(status2.stdout).hasConflicts;
|
|
16954
|
-
if (
|
|
16955
|
-
|
|
17865
|
+
if (conflicts && await rebaseInProgress(folder, timeoutMs, signal)) {
|
|
17866
|
+
operationOutcome = "REBASE_CONFLICT";
|
|
17867
|
+
const conflictsResult = await git4(
|
|
17868
|
+
folder,
|
|
17869
|
+
["diff", "--name-only", "--diff-filter=U"],
|
|
17870
|
+
timeoutMs,
|
|
17871
|
+
signal
|
|
17872
|
+
);
|
|
17873
|
+
preparationConflictPathList = conflictsResult.exitCode === 0 ? conflictsResult.stdout.split("\n").filter(Boolean) : [];
|
|
17874
|
+
preparationResults = input.preparations.map((definition) => ({
|
|
17875
|
+
id: definition.id,
|
|
17876
|
+
definitionHash: definition.definitionHash,
|
|
17877
|
+
state: "SUSPENDED"
|
|
17878
|
+
}));
|
|
17879
|
+
return {
|
|
17880
|
+
...successfulProcess8,
|
|
17881
|
+
outcome: operationOutcome,
|
|
17882
|
+
preparationConflictPaths: preparationConflictPathList,
|
|
17883
|
+
checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
17884
|
+
preparations: preparationResults,
|
|
17885
|
+
worktree: await worktreeResult()
|
|
17886
|
+
};
|
|
17887
|
+
} else {
|
|
17888
|
+
await git4(folder, ["rebase", "--abort"], timeoutMs, signal);
|
|
17889
|
+
}
|
|
17890
|
+
if (input.forcePreparations) {
|
|
17891
|
+
preparationResults = await reapplyPreparations();
|
|
16956
17892
|
}
|
|
16957
|
-
throw new Error(
|
|
17893
|
+
throw new Error(cleanError4(rebase.stderr || "Rebase failed"));
|
|
16958
17894
|
}
|
|
16959
|
-
|
|
17895
|
+
const push = await git4(
|
|
17896
|
+
folder,
|
|
17897
|
+
["push", "--force-with-lease"],
|
|
17898
|
+
timeoutMs,
|
|
17899
|
+
signal
|
|
17900
|
+
);
|
|
17901
|
+
if (push.exitCode !== 0) {
|
|
17902
|
+
if (input.forcePreparations) {
|
|
17903
|
+
preparationResults = await reapplyPreparations();
|
|
17904
|
+
}
|
|
17905
|
+
requireSuccess4(push, "Sync push failed");
|
|
17906
|
+
}
|
|
17907
|
+
preparationResults = input.forcePreparations ? await reapplyPreparations() : await inspectPreparations();
|
|
16960
17908
|
break;
|
|
16961
17909
|
}
|
|
16962
17910
|
case "REBASE": {
|
|
@@ -16969,25 +17917,93 @@ var operateWorktree = async (payload, timeoutMs, signal) => {
|
|
|
16969
17917
|
if (statusResult.stdout.trim())
|
|
16970
17918
|
throw new Error("Stash or commit changes before rebasing");
|
|
16971
17919
|
await runGit(["fetch", "origin"], "Could not fetch origin");
|
|
16972
|
-
const
|
|
17920
|
+
const remoteBase = `refs/remotes/origin/${input.baseBranch}`;
|
|
17921
|
+
const isCurrent = await git4(
|
|
16973
17922
|
folder,
|
|
16974
|
-
["
|
|
17923
|
+
["merge-base", "--is-ancestor", remoteBase, "HEAD"],
|
|
16975
17924
|
timeoutMs,
|
|
16976
17925
|
signal
|
|
16977
17926
|
);
|
|
16978
|
-
if (
|
|
16979
|
-
|
|
17927
|
+
if (isCurrent.exitCode !== 0 && isCurrent.exitCode !== 1) {
|
|
17928
|
+
requireSuccess4(isCurrent, "Could not compare the base branch");
|
|
17929
|
+
}
|
|
17930
|
+
if (isCurrent.exitCode === 1) {
|
|
17931
|
+
preparationConflictPathList = await preparationConflictPaths(
|
|
17932
|
+
folder,
|
|
17933
|
+
input.preparations,
|
|
17934
|
+
remoteBase,
|
|
17935
|
+
timeoutMs,
|
|
17936
|
+
signal
|
|
17937
|
+
);
|
|
17938
|
+
if (preparationConflictPathList.length > 0 && !input.forcePreparations) {
|
|
17939
|
+
operationOutcome = "PREPARATION_CONFLICT";
|
|
17940
|
+
preparationResults = await inspectPreparations();
|
|
17941
|
+
return {
|
|
17942
|
+
...successfulProcess8,
|
|
17943
|
+
outcome: operationOutcome,
|
|
17944
|
+
preparationConflictPaths: preparationConflictPathList,
|
|
17945
|
+
checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
17946
|
+
preparations: preparationResults,
|
|
17947
|
+
worktree: await worktreeResult()
|
|
17948
|
+
};
|
|
17949
|
+
}
|
|
17950
|
+
if (input.forcePreparations) {
|
|
17951
|
+
preparationResults = await suspendWorktreePreparations(
|
|
17952
|
+
folder,
|
|
17953
|
+
input.preparations,
|
|
17954
|
+
timeoutMs,
|
|
17955
|
+
signal
|
|
17956
|
+
);
|
|
17957
|
+
if (preparationResults.some((item) => item.state === "ERROR")) {
|
|
17958
|
+
return {
|
|
17959
|
+
...successfulProcess8,
|
|
17960
|
+
exitCode: 1,
|
|
17961
|
+
checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
17962
|
+
preparations: preparationResults
|
|
17963
|
+
};
|
|
17964
|
+
}
|
|
17965
|
+
}
|
|
17966
|
+
}
|
|
17967
|
+
const rebase = isCurrent.exitCode === 0 ? null : await git4(folder, ["rebase", remoteBase], timeoutMs, signal);
|
|
17968
|
+
if (rebase && rebase.exitCode !== 0) {
|
|
17969
|
+
const status2 = await git4(
|
|
16980
17970
|
folder,
|
|
16981
17971
|
["status", "--porcelain=v1", "-z"],
|
|
16982
17972
|
timeoutMs,
|
|
16983
17973
|
signal
|
|
16984
17974
|
);
|
|
16985
17975
|
const conflicts = status2.exitCode === 0 && statusChangeState(status2.stdout).hasConflicts;
|
|
16986
|
-
if (
|
|
16987
|
-
|
|
17976
|
+
if (conflicts && await rebaseInProgress(folder, timeoutMs, signal)) {
|
|
17977
|
+
operationOutcome = "REBASE_CONFLICT";
|
|
17978
|
+
const conflictsResult = await git4(
|
|
17979
|
+
folder,
|
|
17980
|
+
["diff", "--name-only", "--diff-filter=U"],
|
|
17981
|
+
timeoutMs,
|
|
17982
|
+
signal
|
|
17983
|
+
);
|
|
17984
|
+
preparationConflictPathList = conflictsResult.exitCode === 0 ? conflictsResult.stdout.split("\n").filter(Boolean) : [];
|
|
17985
|
+
preparationResults = input.preparations.map((definition) => ({
|
|
17986
|
+
id: definition.id,
|
|
17987
|
+
definitionHash: definition.definitionHash,
|
|
17988
|
+
state: "SUSPENDED"
|
|
17989
|
+
}));
|
|
17990
|
+
return {
|
|
17991
|
+
...successfulProcess8,
|
|
17992
|
+
outcome: operationOutcome,
|
|
17993
|
+
preparationConflictPaths: preparationConflictPathList,
|
|
17994
|
+
checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
17995
|
+
preparations: preparationResults,
|
|
17996
|
+
worktree: await worktreeResult()
|
|
17997
|
+
};
|
|
17998
|
+
} else {
|
|
17999
|
+
await git4(folder, ["rebase", "--abort"], timeoutMs, signal);
|
|
16988
18000
|
}
|
|
16989
|
-
|
|
18001
|
+
if (input.forcePreparations) {
|
|
18002
|
+
preparationResults = await reapplyPreparations();
|
|
18003
|
+
}
|
|
18004
|
+
throw new Error(cleanError4(rebase.stderr || "Rebase failed"));
|
|
16990
18005
|
}
|
|
18006
|
+
preparationResults = input.forcePreparations ? await reapplyPreparations() : await inspectPreparations();
|
|
16991
18007
|
break;
|
|
16992
18008
|
}
|
|
16993
18009
|
case "CANCEL_REBASE": {
|
|
@@ -16995,6 +18011,7 @@ var operateWorktree = async (payload, timeoutMs, signal) => {
|
|
|
16995
18011
|
throw new Error("No rebase is in progress");
|
|
16996
18012
|
}
|
|
16997
18013
|
await runGit(["rebase", "--abort"], "Could not cancel rebase");
|
|
18014
|
+
preparationResults = await reapplyPreparations();
|
|
16998
18015
|
break;
|
|
16999
18016
|
}
|
|
17000
18017
|
case "PULL": {
|
|
@@ -17021,6 +18038,9 @@ var operateWorktree = async (payload, timeoutMs, signal) => {
|
|
|
17021
18038
|
await runGit(["clean", "-fd"], "Could not remove untracked files");
|
|
17022
18039
|
break;
|
|
17023
18040
|
}
|
|
18041
|
+
case "CLEAR_LOCK":
|
|
18042
|
+
await rm10(join14(input.gitDirectory, "index.lock"), { force: true });
|
|
18043
|
+
break;
|
|
17024
18044
|
case "STASH_ALL":
|
|
17025
18045
|
await runGit(["stash", "push", "--include-untracked"], "Stash failed");
|
|
17026
18046
|
break;
|
|
@@ -17033,21 +18053,37 @@ var operateWorktree = async (payload, timeoutMs, signal) => {
|
|
|
17033
18053
|
}
|
|
17034
18054
|
return {
|
|
17035
18055
|
...successfulProcess8,
|
|
17036
|
-
|
|
17037
|
-
|
|
17038
|
-
|
|
17039
|
-
|
|
17040
|
-
|
|
17041
|
-
Math.min(timeoutMs, 3e4),
|
|
17042
|
-
signal
|
|
17043
|
-
)
|
|
18056
|
+
outcome: operationOutcome,
|
|
18057
|
+
preparationConflictPaths: preparationConflictPathList,
|
|
18058
|
+
checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
18059
|
+
preparations: preparationResults,
|
|
18060
|
+
worktree: await worktreeResult()
|
|
17044
18061
|
};
|
|
17045
18062
|
};
|
|
17046
18063
|
var autoSyncWorktree = async (payload, timeoutMs, signal) => {
|
|
17047
18064
|
const input = worktreeAutoSyncJobPayload(payload);
|
|
17048
18065
|
const folder = await validateWorktree2(input, timeoutMs, signal);
|
|
17049
|
-
const runGit = async (args, fallback) =>
|
|
17050
|
-
const
|
|
18066
|
+
const runGit = async (args, fallback) => requireSuccess4(await git4(folder, args, timeoutMs, signal), fallback);
|
|
18067
|
+
const inspectPreparations = () => executeWorktreePreparations(
|
|
18068
|
+
folder,
|
|
18069
|
+
input.preparations,
|
|
18070
|
+
"INSPECT",
|
|
18071
|
+
timeoutMs,
|
|
18072
|
+
signal
|
|
18073
|
+
);
|
|
18074
|
+
const reapplyPreparations = () => executeWorktreePreparations(
|
|
18075
|
+
folder,
|
|
18076
|
+
input.preparations,
|
|
18077
|
+
"APPLY",
|
|
18078
|
+
timeoutMs,
|
|
18079
|
+
signal
|
|
18080
|
+
);
|
|
18081
|
+
const suspendedPreparations = () => input.preparations.map((definition) => ({
|
|
18082
|
+
id: definition.id,
|
|
18083
|
+
definitionHash: definition.definitionHash,
|
|
18084
|
+
state: "SUSPENDED"
|
|
18085
|
+
}));
|
|
18086
|
+
const branchResult = await git4(
|
|
17051
18087
|
folder,
|
|
17052
18088
|
["symbolic-ref", "--short", "-q", "HEAD"],
|
|
17053
18089
|
timeoutMs,
|
|
@@ -17060,7 +18096,7 @@ var autoSyncWorktree = async (payload, timeoutMs, signal) => {
|
|
|
17060
18096
|
`Auto Sync expected branch ${input.expectedBranch}, but found ${branch ?? "detached HEAD"}`
|
|
17061
18097
|
);
|
|
17062
18098
|
}
|
|
17063
|
-
const upstreamResult = branch ? await
|
|
18099
|
+
const upstreamResult = branch ? await git4(
|
|
17064
18100
|
folder,
|
|
17065
18101
|
["rev-parse", "--abbrev-ref", "@{upstream}"],
|
|
17066
18102
|
timeoutMs,
|
|
@@ -17081,6 +18117,8 @@ var autoSyncWorktree = async (payload, timeoutMs, signal) => {
|
|
|
17081
18117
|
return {
|
|
17082
18118
|
...successfulProcess8,
|
|
17083
18119
|
outcome: "UNRESOLVED",
|
|
18120
|
+
checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
18121
|
+
preparations: suspendedPreparations(),
|
|
17084
18122
|
worktree: await inspectWorktreeItem(
|
|
17085
18123
|
folder,
|
|
17086
18124
|
folder,
|
|
@@ -17109,6 +18147,8 @@ var autoSyncWorktree = async (payload, timeoutMs, signal) => {
|
|
|
17109
18147
|
return {
|
|
17110
18148
|
...successfulProcess8,
|
|
17111
18149
|
outcome: "UNRESOLVED",
|
|
18150
|
+
checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
18151
|
+
preparations: suspendedPreparations(),
|
|
17112
18152
|
worktree: await inspectWorktreeItem(
|
|
17113
18153
|
folder,
|
|
17114
18154
|
folder,
|
|
@@ -17129,6 +18169,8 @@ var autoSyncWorktree = async (payload, timeoutMs, signal) => {
|
|
|
17129
18169
|
return {
|
|
17130
18170
|
...successfulProcess8,
|
|
17131
18171
|
outcome: "UNRESOLVED",
|
|
18172
|
+
checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
18173
|
+
preparations: suspendedPreparations(),
|
|
17132
18174
|
worktree: await inspectWorktreeItem(
|
|
17133
18175
|
folder,
|
|
17134
18176
|
folder,
|
|
@@ -17139,13 +18181,13 @@ var autoSyncWorktree = async (payload, timeoutMs, signal) => {
|
|
|
17139
18181
|
)
|
|
17140
18182
|
};
|
|
17141
18183
|
}
|
|
17142
|
-
const finalBranch = await
|
|
18184
|
+
const finalBranch = await git4(
|
|
17143
18185
|
folder,
|
|
17144
18186
|
["symbolic-ref", "--short", "-q", "HEAD"],
|
|
17145
18187
|
timeoutMs,
|
|
17146
18188
|
signal
|
|
17147
18189
|
);
|
|
17148
|
-
const finalUpstream = finalBranch.exitCode === 0 ? await
|
|
18190
|
+
const finalUpstream = finalBranch.exitCode === 0 ? await git4(
|
|
17149
18191
|
folder,
|
|
17150
18192
|
["rev-parse", "--abbrev-ref", "@{upstream}"],
|
|
17151
18193
|
timeoutMs,
|
|
@@ -17156,10 +18198,22 @@ var autoSyncWorktree = async (payload, timeoutMs, signal) => {
|
|
|
17156
18198
|
`Auto Sync expected branch ${input.expectedBranch} with an upstream`
|
|
17157
18199
|
);
|
|
17158
18200
|
}
|
|
17159
|
-
|
|
18201
|
+
const push2 = await git4(
|
|
18202
|
+
folder,
|
|
18203
|
+
["push", "--force-with-lease"],
|
|
18204
|
+
timeoutMs,
|
|
18205
|
+
signal
|
|
18206
|
+
);
|
|
18207
|
+
if (push2.exitCode !== 0) {
|
|
18208
|
+
await reapplyPreparations();
|
|
18209
|
+
requireSuccess4(push2, "Auto Sync push failed");
|
|
18210
|
+
}
|
|
18211
|
+
const preparations = await reapplyPreparations();
|
|
17160
18212
|
return {
|
|
17161
18213
|
...successfulProcess8,
|
|
17162
18214
|
outcome: "SYNCED",
|
|
18215
|
+
checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
18216
|
+
preparations,
|
|
17163
18217
|
worktree: await inspectWorktreeItem(
|
|
17164
18218
|
folder,
|
|
17165
18219
|
folder,
|
|
@@ -17179,14 +18233,14 @@ var autoSyncWorktree = async (payload, timeoutMs, signal) => {
|
|
|
17179
18233
|
}
|
|
17180
18234
|
await runGit(["fetch", "origin"], "Could not fetch origin");
|
|
17181
18235
|
const remoteBase = `refs/remotes/origin/${input.baseBranch}`;
|
|
17182
|
-
const isCurrent = await
|
|
18236
|
+
const isCurrent = await git4(
|
|
17183
18237
|
folder,
|
|
17184
18238
|
["merge-base", "--is-ancestor", remoteBase, "HEAD"],
|
|
17185
18239
|
timeoutMs,
|
|
17186
18240
|
signal
|
|
17187
18241
|
);
|
|
17188
18242
|
if (isCurrent.exitCode === 0) {
|
|
17189
|
-
const upstreamContainsHead = await
|
|
18243
|
+
const upstreamContainsHead = await git4(
|
|
17190
18244
|
folder,
|
|
17191
18245
|
["merge-base", "--is-ancestor", "HEAD", "@{upstream}"],
|
|
17192
18246
|
timeoutMs,
|
|
@@ -17194,7 +18248,7 @@ var autoSyncWorktree = async (payload, timeoutMs, signal) => {
|
|
|
17194
18248
|
);
|
|
17195
18249
|
if (upstreamContainsHead.exitCode !== 0 && upstreamContainsHead.exitCode !== 1) {
|
|
17196
18250
|
throw new Error(
|
|
17197
|
-
|
|
18251
|
+
cleanError4(
|
|
17198
18252
|
upstreamContainsHead.stderr || "Could not compare the upstream branch"
|
|
17199
18253
|
)
|
|
17200
18254
|
);
|
|
@@ -17204,6 +18258,8 @@ var autoSyncWorktree = async (payload, timeoutMs, signal) => {
|
|
|
17204
18258
|
return {
|
|
17205
18259
|
...successfulProcess8,
|
|
17206
18260
|
outcome: "SYNCED",
|
|
18261
|
+
checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
18262
|
+
preparations: await inspectPreparations(),
|
|
17207
18263
|
worktree: await inspectWorktreeItem(
|
|
17208
18264
|
folder,
|
|
17209
18265
|
folder,
|
|
@@ -17217,6 +18273,32 @@ var autoSyncWorktree = async (payload, timeoutMs, signal) => {
|
|
|
17217
18273
|
return {
|
|
17218
18274
|
...successfulProcess8,
|
|
17219
18275
|
outcome: "NO_CHANGE",
|
|
18276
|
+
checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
18277
|
+
preparations: await inspectPreparations(),
|
|
18278
|
+
worktree: await inspectWorktreeItem(
|
|
18279
|
+
folder,
|
|
18280
|
+
folder,
|
|
18281
|
+
input.baseBranch,
|
|
18282
|
+
false,
|
|
18283
|
+
Math.min(timeoutMs, 3e4),
|
|
18284
|
+
signal
|
|
18285
|
+
)
|
|
18286
|
+
};
|
|
18287
|
+
}
|
|
18288
|
+
const preparationConflictPathList = await preparationConflictPaths(
|
|
18289
|
+
folder,
|
|
18290
|
+
input.preparations,
|
|
18291
|
+
remoteBase,
|
|
18292
|
+
timeoutMs,
|
|
18293
|
+
signal
|
|
18294
|
+
);
|
|
18295
|
+
if (preparationConflictPathList.length > 0 && !input.forcePreparations) {
|
|
18296
|
+
return {
|
|
18297
|
+
...successfulProcess8,
|
|
18298
|
+
outcome: "PREPARATION_CONFLICT",
|
|
18299
|
+
preparationConflictPaths: preparationConflictPathList,
|
|
18300
|
+
checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
18301
|
+
preparations: await inspectPreparations(),
|
|
17220
18302
|
worktree: await inspectWorktreeItem(
|
|
17221
18303
|
folder,
|
|
17222
18304
|
folder,
|
|
@@ -17227,9 +18309,26 @@ var autoSyncWorktree = async (payload, timeoutMs, signal) => {
|
|
|
17227
18309
|
)
|
|
17228
18310
|
};
|
|
17229
18311
|
}
|
|
17230
|
-
|
|
18312
|
+
let preparationResults = [];
|
|
18313
|
+
if (input.forcePreparations) {
|
|
18314
|
+
preparationResults = await suspendWorktreePreparations(
|
|
18315
|
+
folder,
|
|
18316
|
+
input.preparations,
|
|
18317
|
+
timeoutMs,
|
|
18318
|
+
signal
|
|
18319
|
+
);
|
|
18320
|
+
if (preparationResults.some((item) => item.state === "ERROR")) {
|
|
18321
|
+
return {
|
|
18322
|
+
...successfulProcess8,
|
|
18323
|
+
exitCode: 1,
|
|
18324
|
+
checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
18325
|
+
preparations: preparationResults
|
|
18326
|
+
};
|
|
18327
|
+
}
|
|
18328
|
+
}
|
|
18329
|
+
const rebase = await git4(folder, ["rebase", remoteBase], timeoutMs, signal);
|
|
17231
18330
|
if (rebase.exitCode !== 0) {
|
|
17232
|
-
const conflictStatus = await
|
|
18331
|
+
const conflictStatus = await git4(
|
|
17233
18332
|
folder,
|
|
17234
18333
|
["status", "--porcelain=v1", "-z"],
|
|
17235
18334
|
timeoutMs,
|
|
@@ -17240,6 +18339,8 @@ var autoSyncWorktree = async (payload, timeoutMs, signal) => {
|
|
|
17240
18339
|
return {
|
|
17241
18340
|
...successfulProcess8,
|
|
17242
18341
|
outcome: "CONFLICT",
|
|
18342
|
+
checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
18343
|
+
preparations: suspendedPreparations(),
|
|
17243
18344
|
worktree: await inspectWorktreeItem(
|
|
17244
18345
|
folder,
|
|
17245
18346
|
folder,
|
|
@@ -17250,13 +18351,26 @@ var autoSyncWorktree = async (payload, timeoutMs, signal) => {
|
|
|
17250
18351
|
)
|
|
17251
18352
|
};
|
|
17252
18353
|
}
|
|
17253
|
-
await
|
|
17254
|
-
|
|
18354
|
+
await git4(folder, ["rebase", "--abort"], timeoutMs, signal);
|
|
18355
|
+
if (input.forcePreparations) await reapplyPreparations();
|
|
18356
|
+
throw new Error(cleanError4(rebase.stderr || "Auto Sync rebase failed"));
|
|
17255
18357
|
}
|
|
17256
|
-
|
|
18358
|
+
const push = await git4(
|
|
18359
|
+
folder,
|
|
18360
|
+
["push", "--force-with-lease"],
|
|
18361
|
+
timeoutMs,
|
|
18362
|
+
signal
|
|
18363
|
+
);
|
|
18364
|
+
if (push.exitCode !== 0) {
|
|
18365
|
+
if (input.forcePreparations) await reapplyPreparations();
|
|
18366
|
+
requireSuccess4(push, "Auto Sync push failed");
|
|
18367
|
+
}
|
|
18368
|
+
preparationResults = input.forcePreparations ? await reapplyPreparations() : await inspectPreparations();
|
|
17257
18369
|
return {
|
|
17258
18370
|
...successfulProcess8,
|
|
17259
18371
|
outcome: "SYNCED",
|
|
18372
|
+
checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
18373
|
+
preparations: preparationResults,
|
|
17260
18374
|
worktree: await inspectWorktreeItem(
|
|
17261
18375
|
folder,
|
|
17262
18376
|
folder,
|
|
@@ -17290,6 +18404,7 @@ var handlers = {
|
|
|
17290
18404
|
[WORKTREE_MOVE_CHECKOUT_JOB_KIND]: checkoutMovedWorktree,
|
|
17291
18405
|
[WORKTREE_DELETE_JOB_KIND]: deleteWorktree,
|
|
17292
18406
|
[WORKTREE_OPERATION_JOB_KIND]: operateWorktree,
|
|
18407
|
+
[WORKTREE_PREPARATION_JOB_KIND]: prepareWorktree,
|
|
17293
18408
|
[WORKTREE_GIT_INSPECT_JOB_KIND]: inspectWorktreeGit,
|
|
17294
18409
|
[WORKTREE_GIT_OPERATION_JOB_KIND]: operateWorktreeGit,
|
|
17295
18410
|
[WORKTREE_WATCH_JOB_KIND]: watchWorktree,
|
|
@@ -17328,8 +18443,8 @@ var RepositoryCoordinator = class {
|
|
|
17328
18443
|
async run(key, task) {
|
|
17329
18444
|
const previous = this.tails.get(key) ?? Promise.resolve();
|
|
17330
18445
|
let release2;
|
|
17331
|
-
const current = new Promise((
|
|
17332
|
-
release2 =
|
|
18446
|
+
const current = new Promise((resolve9) => {
|
|
18447
|
+
release2 = resolve9;
|
|
17333
18448
|
});
|
|
17334
18449
|
const tail = previous.then(() => current);
|
|
17335
18450
|
this.tails.set(key, tail);
|
|
@@ -17433,7 +18548,7 @@ var JobExecutor = class {
|
|
|
17433
18548
|
);
|
|
17434
18549
|
if (this.stopping) return;
|
|
17435
18550
|
const delay = Math.min(3e4, 1e3 * 2 ** Math.min(retry++, 5));
|
|
17436
|
-
await new Promise((
|
|
18551
|
+
await new Promise((resolve9) => setTimeout(resolve9, delay));
|
|
17437
18552
|
}
|
|
17438
18553
|
}
|
|
17439
18554
|
}
|
|
@@ -17580,21 +18695,21 @@ var CodebaseMonitor = class {
|
|
|
17580
18695
|
|
|
17581
18696
|
// src/runs/run-manager.ts
|
|
17582
18697
|
import { execFile as execFile4 } from "node:child_process";
|
|
17583
|
-
import { mkdir as
|
|
17584
|
-
import { dirname as
|
|
18698
|
+
import { mkdir as mkdir7, rm as rm14 } from "node:fs/promises";
|
|
18699
|
+
import { dirname as dirname11, join as join18 } from "node:path";
|
|
17585
18700
|
import { promisify as promisify4 } from "node:util";
|
|
17586
18701
|
|
|
17587
18702
|
// src/runs/journal.ts
|
|
17588
18703
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
17589
18704
|
import {
|
|
17590
18705
|
appendFile,
|
|
17591
|
-
mkdir as
|
|
17592
|
-
readFile as
|
|
18706
|
+
mkdir as mkdir6,
|
|
18707
|
+
readFile as readFile10,
|
|
17593
18708
|
rename as rename4,
|
|
17594
|
-
rm as
|
|
17595
|
-
writeFile as
|
|
18709
|
+
rm as rm11,
|
|
18710
|
+
writeFile as writeFile8
|
|
17596
18711
|
} from "node:fs/promises";
|
|
17597
|
-
import { dirname as
|
|
18712
|
+
import { dirname as dirname9, join as join15 } from "node:path";
|
|
17598
18713
|
var RunJournal = class {
|
|
17599
18714
|
constructor(runId, attemptId) {
|
|
17600
18715
|
this.runId = runId;
|
|
@@ -17613,13 +18728,13 @@ var RunJournal = class {
|
|
|
17613
18728
|
this.attemptId = attemptId;
|
|
17614
18729
|
}
|
|
17615
18730
|
get directory() {
|
|
17616
|
-
return
|
|
18731
|
+
return join15(dirname9(configPath()), "runs", this.runId);
|
|
17617
18732
|
}
|
|
17618
18733
|
get eventsPath() {
|
|
17619
|
-
return
|
|
18734
|
+
return join15(this.directory, "events.jsonl");
|
|
17620
18735
|
}
|
|
17621
18736
|
get statePath() {
|
|
17622
|
-
return
|
|
18737
|
+
return join15(this.directory, "state.json");
|
|
17623
18738
|
}
|
|
17624
18739
|
async load() {
|
|
17625
18740
|
if (this.loaded) return;
|
|
@@ -17631,9 +18746,9 @@ var RunJournal = class {
|
|
|
17631
18746
|
await this.loading;
|
|
17632
18747
|
}
|
|
17633
18748
|
async loadState() {
|
|
17634
|
-
await
|
|
18749
|
+
await mkdir6(this.directory, { recursive: true, mode: 448 });
|
|
17635
18750
|
try {
|
|
17636
|
-
const state = JSON.parse(await
|
|
18751
|
+
const state = JSON.parse(await readFile10(this.statePath, "utf8"));
|
|
17637
18752
|
this.acknowledged = state.acknowledged ?? -1;
|
|
17638
18753
|
this.nextSequence = state.nextSequence ?? 0;
|
|
17639
18754
|
} catch {
|
|
@@ -17708,7 +18823,7 @@ var RunJournal = class {
|
|
|
17708
18823
|
}
|
|
17709
18824
|
async readEvents() {
|
|
17710
18825
|
try {
|
|
17711
|
-
return (await
|
|
18826
|
+
return (await readFile10(this.eventsPath, "utf8")).split("\n").filter(Boolean).map((line) => JSON.parse(line));
|
|
17712
18827
|
} catch (error) {
|
|
17713
18828
|
if (error.code === "ENOENT") return [];
|
|
17714
18829
|
throw error;
|
|
@@ -17720,10 +18835,10 @@ var RunJournal = class {
|
|
|
17720
18835
|
const operation = this.saving.then(async () => {
|
|
17721
18836
|
const temporary = `${this.statePath}.${process.pid}.${randomUUID4()}.tmp`;
|
|
17722
18837
|
try {
|
|
17723
|
-
await
|
|
18838
|
+
await writeFile8(temporary, contents, { mode: 384 });
|
|
17724
18839
|
await rename4(temporary, this.statePath);
|
|
17725
18840
|
} catch (error) {
|
|
17726
|
-
await
|
|
18841
|
+
await rm11(temporary, { force: true }).catch(() => void 0);
|
|
17727
18842
|
throw error;
|
|
17728
18843
|
}
|
|
17729
18844
|
});
|
|
@@ -26897,7 +28012,7 @@ function Yy(e) {
|
|
|
26897
28012
|
var l = {};
|
|
26898
28013
|
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
28014
|
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: () =>
|
|
28015
|
+
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
28016
|
var Kd = Object.freeze({ status: "aborted" });
|
|
26902
28017
|
function S(e, t, r) {
|
|
26903
28018
|
function n(a, c) {
|
|
@@ -28445,7 +29560,7 @@ var tm = S("$ZodReadonly", (e, t) => {
|
|
|
28445
29560
|
function DC(e) {
|
|
28446
29561
|
return e.value = Object.freeze(e.value), e;
|
|
28447
29562
|
}
|
|
28448
|
-
var
|
|
29563
|
+
var rm12 = S("$ZodTemplateLiteral", (e, t) => {
|
|
28449
29564
|
ie.init(e, t);
|
|
28450
29565
|
let r = [];
|
|
28451
29566
|
for (let n of t.parts) if (n instanceof ie) {
|
|
@@ -32252,7 +33367,7 @@ function hR(e) {
|
|
|
32252
33367
|
return new gR({ type: "readonly", innerType: e });
|
|
32253
33368
|
}
|
|
32254
33369
|
var _R = S("ZodTemplateLiteral", (e, t) => {
|
|
32255
|
-
|
|
33370
|
+
rm12.init(e, t), de.init(e, t);
|
|
32256
33371
|
});
|
|
32257
33372
|
function q9(e, t) {
|
|
32258
33373
|
return new _R({ type: "template_literal", parts: e, ...M.normalizeParams(t) });
|
|
@@ -43579,7 +44694,7 @@ var MessageQueue = class {
|
|
|
43579
44694
|
if (value) return Promise.resolve({ value, done: false });
|
|
43580
44695
|
if (this.closed)
|
|
43581
44696
|
return Promise.resolve({ value: void 0, done: true });
|
|
43582
|
-
return new Promise((
|
|
44697
|
+
return new Promise((resolve9) => this.waiters.push(resolve9));
|
|
43583
44698
|
}
|
|
43584
44699
|
};
|
|
43585
44700
|
}
|
|
@@ -43749,8 +44864,8 @@ var ClaudeAdapter = class {
|
|
|
43749
44864
|
const requestId = options.toolUseID || randomUUID5();
|
|
43750
44865
|
const questions = questionsFromInput(toolInput);
|
|
43751
44866
|
await callbacks.onQuestion(requestId, questions);
|
|
43752
|
-
const answers = await new Promise((
|
|
43753
|
-
pendingQuestions.set(requestId, { input: toolInput, resolve:
|
|
44867
|
+
const answers = await new Promise((resolve9) => {
|
|
44868
|
+
pendingQuestions.set(requestId, { input: toolInput, resolve: resolve9 });
|
|
43754
44869
|
});
|
|
43755
44870
|
return {
|
|
43756
44871
|
behavior: "allow",
|
|
@@ -43893,9 +45008,9 @@ import {
|
|
|
43893
45008
|
execFile as execFile3,
|
|
43894
45009
|
spawn as spawn8
|
|
43895
45010
|
} from "node:child_process";
|
|
43896
|
-
import { mkdtemp as mkdtemp7, rm as
|
|
45011
|
+
import { mkdtemp as mkdtemp7, rm as rm13, writeFile as writeFile9 } from "node:fs/promises";
|
|
43897
45012
|
import { tmpdir as tmpdir7 } from "node:os";
|
|
43898
|
-
import { join as
|
|
45013
|
+
import { join as join17 } from "node:path";
|
|
43899
45014
|
import { createInterface } from "node:readline";
|
|
43900
45015
|
import { promisify as promisify3 } from "node:util";
|
|
43901
45016
|
var SUPPORTED_CODEX_APP_SERVER_MINORS = ["0.144", "0.145"];
|
|
@@ -44006,8 +45121,8 @@ var CodexAppServer = class {
|
|
|
44006
45121
|
});
|
|
44007
45122
|
const lines = createInterface({ input: child.stdout });
|
|
44008
45123
|
lines.on("line", (line) => this.receive(line));
|
|
44009
|
-
await new Promise((
|
|
44010
|
-
child.once("spawn",
|
|
45124
|
+
await new Promise((resolve9, reject) => {
|
|
45125
|
+
child.once("spawn", resolve9);
|
|
44011
45126
|
child.once("error", reject);
|
|
44012
45127
|
});
|
|
44013
45128
|
const initialized = asRecord(
|
|
@@ -44049,7 +45164,7 @@ var CodexAppServer = class {
|
|
|
44049
45164
|
}
|
|
44050
45165
|
}
|
|
44051
45166
|
async createBundledModelCatalog(executable) {
|
|
44052
|
-
const directory = await mkdtemp7(
|
|
45167
|
+
const directory = await mkdtemp7(join17(tmpdir7(), "aide-codex-models-"));
|
|
44053
45168
|
try {
|
|
44054
45169
|
const { stdout } = await execFileAsync2(
|
|
44055
45170
|
executable,
|
|
@@ -44059,12 +45174,12 @@ var CodexAppServer = class {
|
|
|
44059
45174
|
maxBuffer: 16 * 1024 * 1024
|
|
44060
45175
|
}
|
|
44061
45176
|
);
|
|
44062
|
-
const catalogPath =
|
|
44063
|
-
await
|
|
45177
|
+
const catalogPath = join17(directory, "models.json");
|
|
45178
|
+
await writeFile9(catalogPath, stdout, "utf8");
|
|
44064
45179
|
this.modelCatalogDirectory = directory;
|
|
44065
45180
|
return catalogPath;
|
|
44066
45181
|
} catch (error) {
|
|
44067
|
-
await
|
|
45182
|
+
await rm13(directory, { recursive: true, force: true }).catch(
|
|
44068
45183
|
() => void 0
|
|
44069
45184
|
);
|
|
44070
45185
|
throw error;
|
|
@@ -44075,7 +45190,7 @@ var CodexAppServer = class {
|
|
|
44075
45190
|
if (this.modelCatalogDirectory === directory) {
|
|
44076
45191
|
this.modelCatalogDirectory = void 0;
|
|
44077
45192
|
}
|
|
44078
|
-
await
|
|
45193
|
+
await rm13(directory, { recursive: true, force: true }).catch(
|
|
44079
45194
|
() => void 0
|
|
44080
45195
|
);
|
|
44081
45196
|
}
|
|
@@ -44115,8 +45230,8 @@ var CodexAppServer = class {
|
|
|
44115
45230
|
}
|
|
44116
45231
|
requestDirect(method, params) {
|
|
44117
45232
|
const id2 = this.nextId++;
|
|
44118
|
-
return new Promise((
|
|
44119
|
-
this.pending.set(id2, { resolve:
|
|
45233
|
+
return new Promise((resolve9, reject) => {
|
|
45234
|
+
this.pending.set(id2, { resolve: resolve9, reject });
|
|
44120
45235
|
this.write({ id: id2, method, params });
|
|
44121
45236
|
});
|
|
44122
45237
|
}
|
|
@@ -44279,8 +45394,8 @@ var CodexAdapter = class {
|
|
|
44279
45394
|
let lastUsageSignature = "";
|
|
44280
45395
|
const pendingQuestions = /* @__PURE__ */ new Map();
|
|
44281
45396
|
let resolveCompletion;
|
|
44282
|
-
const completion = new Promise((
|
|
44283
|
-
resolveCompletion =
|
|
45397
|
+
const completion = new Promise((resolve9) => {
|
|
45398
|
+
resolveCompletion = resolve9;
|
|
44284
45399
|
});
|
|
44285
45400
|
const unsubscribe = this.server.listen(nativeId, (message) => {
|
|
44286
45401
|
void (async () => {
|
|
@@ -44490,13 +45605,13 @@ var CodexAdapter = class {
|
|
|
44490
45605
|
};
|
|
44491
45606
|
|
|
44492
45607
|
// src/runs/opencode-adapter.ts
|
|
44493
|
-
import { dirname as
|
|
45608
|
+
import { dirname as dirname10 } from "node:path";
|
|
44494
45609
|
import { pathToFileURL } from "node:url";
|
|
44495
45610
|
|
|
44496
45611
|
// ../../node_modules/@opencode-ai/sdk/dist/v2/gen/core/serverSentEvents.gen.js
|
|
44497
45612
|
var createSseClient = ({ onRequest, onSseError, onSseEvent, responseTransformer, responseValidator, sseDefaultRetryDelay, sseMaxRetryAttempts, sseMaxRetryDelay, sseSleepFn, url, ...options }) => {
|
|
44498
45613
|
let lastEventId;
|
|
44499
|
-
const sleep = sseSleepFn ?? ((ms) => new Promise((
|
|
45614
|
+
const sleep = sseSleepFn ?? ((ms) => new Promise((resolve9) => setTimeout(resolve9, ms)));
|
|
44500
45615
|
const createStream = async function* () {
|
|
44501
45616
|
let retryDelay = sseDefaultRetryDelay ?? 3e3;
|
|
44502
45617
|
let attempt = 0;
|
|
@@ -49948,7 +51063,7 @@ async function createOpencodeServer(options) {
|
|
|
49948
51063
|
});
|
|
49949
51064
|
let clear = () => {
|
|
49950
51065
|
};
|
|
49951
|
-
const url = await new Promise((
|
|
51066
|
+
const url = await new Promise((resolve9, reject) => {
|
|
49952
51067
|
const id2 = setTimeout(() => {
|
|
49953
51068
|
clear();
|
|
49954
51069
|
stop(proc);
|
|
@@ -49973,7 +51088,7 @@ async function createOpencodeServer(options) {
|
|
|
49973
51088
|
}
|
|
49974
51089
|
clearTimeout(id2);
|
|
49975
51090
|
resolved = true;
|
|
49976
|
-
|
|
51091
|
+
resolve9(match[1]);
|
|
49977
51092
|
return;
|
|
49978
51093
|
}
|
|
49979
51094
|
}
|
|
@@ -50138,11 +51253,11 @@ function responseItems(value) {
|
|
|
50138
51253
|
}
|
|
50139
51254
|
function waitForPoll(signal) {
|
|
50140
51255
|
if (signal.aborted) return Promise.resolve();
|
|
50141
|
-
return new Promise((
|
|
51256
|
+
return new Promise((resolve9) => {
|
|
50142
51257
|
const finish = () => {
|
|
50143
51258
|
clearTimeout(timer);
|
|
50144
51259
|
signal.removeEventListener("abort", finish);
|
|
50145
|
-
|
|
51260
|
+
resolve9();
|
|
50146
51261
|
};
|
|
50147
51262
|
const timer = setTimeout(finish, QUESTION_RECONCILIATION_INTERVAL_MS);
|
|
50148
51263
|
timer.unref();
|
|
@@ -50171,7 +51286,7 @@ var OpenCodeAdapter = class {
|
|
|
50171
51286
|
"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
51287
|
);
|
|
50173
51288
|
}
|
|
50174
|
-
prependPathDirectory(
|
|
51289
|
+
prependPathDirectory(dirname10(executable));
|
|
50175
51290
|
this.runtime = await createOpencode({ port: 0 });
|
|
50176
51291
|
}
|
|
50177
51292
|
return this.runtime.client;
|
|
@@ -50795,7 +51910,7 @@ var RunManager = class {
|
|
|
50795
51910
|
5
|
|
50796
51911
|
);
|
|
50797
51912
|
await this.completeCommand(command3.id, "SUCCEEDED");
|
|
50798
|
-
await
|
|
51913
|
+
await rm14(join18(dirname11(configPath()), "runs", run.id, "attachments"), {
|
|
50799
51914
|
recursive: true,
|
|
50800
51915
|
force: true
|
|
50801
51916
|
}).catch(() => void 0);
|
|
@@ -50977,7 +52092,7 @@ var RunManager = class {
|
|
|
50977
52092
|
this.active.delete(run.id);
|
|
50978
52093
|
this.interruptionRequests.delete(run.id);
|
|
50979
52094
|
this.executingCommands.delete(command3.id);
|
|
50980
|
-
await
|
|
52095
|
+
await rm14(join18(dirname11(configPath()), "runs", run.id, "attachments"), {
|
|
50981
52096
|
recursive: true,
|
|
50982
52097
|
force: true
|
|
50983
52098
|
}).catch(() => void 0);
|
|
@@ -51205,11 +52320,11 @@ var RunManager = class {
|
|
|
51205
52320
|
}
|
|
51206
52321
|
async stageAttachments(runId, attachments) {
|
|
51207
52322
|
if (!attachments.length) return [];
|
|
51208
|
-
const directory =
|
|
51209
|
-
await
|
|
52323
|
+
const directory = join18(dirname11(configPath()), "runs", runId, "attachments");
|
|
52324
|
+
await mkdir7(directory, { recursive: true, mode: 448 });
|
|
51210
52325
|
return Promise.all(
|
|
51211
52326
|
attachments.map(async (attachment) => {
|
|
51212
|
-
const path =
|
|
52327
|
+
const path = join18(
|
|
51213
52328
|
directory,
|
|
51214
52329
|
`${attachment.id}-${safeFilename(attachment.filename)}`
|
|
51215
52330
|
);
|
|
@@ -51301,7 +52416,7 @@ var RunManager = class {
|
|
|
51301
52416
|
return await operation();
|
|
51302
52417
|
} catch (error) {
|
|
51303
52418
|
if (this.stopped || attempt >= attempts) throw error;
|
|
51304
|
-
await new Promise((
|
|
52419
|
+
await new Promise((resolve9) => setTimeout(resolve9, delay));
|
|
51305
52420
|
delay = Math.min(delay * 2, 3e4);
|
|
51306
52421
|
}
|
|
51307
52422
|
}
|
|
@@ -51581,9 +52696,9 @@ async function runAgentSession(config, signal, onUnhealthy) {
|
|
|
51581
52696
|
}
|
|
51582
52697
|
}
|
|
51583
52698
|
);
|
|
51584
|
-
await new Promise((
|
|
51585
|
-
if (signal.aborted)
|
|
51586
|
-
else signal.addEventListener("abort", () =>
|
|
52699
|
+
await new Promise((resolve9) => {
|
|
52700
|
+
if (signal.aborted) resolve9();
|
|
52701
|
+
else signal.addEventListener("abort", () => resolve9(), { once: true });
|
|
51587
52702
|
});
|
|
51588
52703
|
if (heartbeatTimer) clearTimeout(heartbeatTimer);
|
|
51589
52704
|
if (jobReconciliationTimer) clearTimeout(jobReconciliationTimer);
|
|
@@ -51650,7 +52765,7 @@ var defaultDependencies = {
|
|
|
51650
52765
|
inventory: collectInventory,
|
|
51651
52766
|
load: loadConfig,
|
|
51652
52767
|
save: saveConfig,
|
|
51653
|
-
wait: (milliseconds, signal) => new Promise((
|
|
52768
|
+
wait: (milliseconds, signal) => new Promise((resolve9, reject) => {
|
|
51654
52769
|
if (signal.aborted) {
|
|
51655
52770
|
reject(new Error("Development agent startup was cancelled"));
|
|
51656
52771
|
return;
|
|
@@ -51661,7 +52776,7 @@ var defaultDependencies = {
|
|
|
51661
52776
|
};
|
|
51662
52777
|
const timer = setTimeout(() => {
|
|
51663
52778
|
signal.removeEventListener("abort", onAbort);
|
|
51664
|
-
|
|
52779
|
+
resolve9();
|
|
51665
52780
|
}, milliseconds);
|
|
51666
52781
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
51667
52782
|
})
|
|
@@ -51905,7 +53020,7 @@ async function unenroll() {
|
|
|
51905
53020
|
config = await loadConfig(path);
|
|
51906
53021
|
} catch {
|
|
51907
53022
|
}
|
|
51908
|
-
await
|
|
53023
|
+
await rm15(path, { force: true });
|
|
51909
53024
|
console.log(
|
|
51910
53025
|
config ? `Removed the enrollment for ${config.name} (${config.agentId}) from ${path}` : `Removed ${path}`
|
|
51911
53026
|
);
|