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