@buildautomaton/cli 0.1.13 → 0.1.14
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/cli.js +824 -228
- package/dist/cli.js.map +4 -4
- package/dist/index.js +803 -207
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4065,8 +4065,8 @@ var init_parseUtil = __esm({
|
|
|
4065
4065
|
init_errors();
|
|
4066
4066
|
init_en();
|
|
4067
4067
|
makeIssue = (params) => {
|
|
4068
|
-
const { data, path:
|
|
4069
|
-
const fullPath = [...
|
|
4068
|
+
const { data, path: path31, errorMaps, issueData } = params;
|
|
4069
|
+
const fullPath = [...path31, ...issueData.path || []];
|
|
4070
4070
|
const fullIssue = {
|
|
4071
4071
|
...issueData,
|
|
4072
4072
|
path: fullPath
|
|
@@ -4374,11 +4374,11 @@ var init_types = __esm({
|
|
|
4374
4374
|
init_parseUtil();
|
|
4375
4375
|
init_util();
|
|
4376
4376
|
ParseInputLazyPath = class {
|
|
4377
|
-
constructor(parent, value,
|
|
4377
|
+
constructor(parent, value, path31, key) {
|
|
4378
4378
|
this._cachedPath = [];
|
|
4379
4379
|
this.parent = parent;
|
|
4380
4380
|
this.data = value;
|
|
4381
|
-
this._path =
|
|
4381
|
+
this._path = path31;
|
|
4382
4382
|
this._key = key;
|
|
4383
4383
|
}
|
|
4384
4384
|
get path() {
|
|
@@ -7993,15 +7993,15 @@ function assignProp(target, prop, value) {
|
|
|
7993
7993
|
configurable: true
|
|
7994
7994
|
});
|
|
7995
7995
|
}
|
|
7996
|
-
function getElementAtPath(obj,
|
|
7997
|
-
if (!
|
|
7996
|
+
function getElementAtPath(obj, path31) {
|
|
7997
|
+
if (!path31)
|
|
7998
7998
|
return obj;
|
|
7999
|
-
return
|
|
7999
|
+
return path31.reduce((acc, key) => acc?.[key], obj);
|
|
8000
8000
|
}
|
|
8001
8001
|
function promiseAllObject(promisesObj) {
|
|
8002
8002
|
const keys = Object.keys(promisesObj);
|
|
8003
|
-
const
|
|
8004
|
-
return Promise.all(
|
|
8003
|
+
const promises3 = keys.map((key) => promisesObj[key]);
|
|
8004
|
+
return Promise.all(promises3).then((results) => {
|
|
8005
8005
|
const resolvedObj = {};
|
|
8006
8006
|
for (let i = 0; i < keys.length; i++) {
|
|
8007
8007
|
resolvedObj[keys[i]] = results[i];
|
|
@@ -8245,11 +8245,11 @@ function aborted(x, startIndex = 0) {
|
|
|
8245
8245
|
}
|
|
8246
8246
|
return false;
|
|
8247
8247
|
}
|
|
8248
|
-
function prefixIssues(
|
|
8248
|
+
function prefixIssues(path31, issues) {
|
|
8249
8249
|
return issues.map((iss) => {
|
|
8250
8250
|
var _a2;
|
|
8251
8251
|
(_a2 = iss).path ?? (_a2.path = []);
|
|
8252
|
-
iss.path.unshift(
|
|
8252
|
+
iss.path.unshift(path31);
|
|
8253
8253
|
return iss;
|
|
8254
8254
|
});
|
|
8255
8255
|
}
|
|
@@ -8438,7 +8438,7 @@ function treeifyError(error40, _mapper) {
|
|
|
8438
8438
|
return issue2.message;
|
|
8439
8439
|
};
|
|
8440
8440
|
const result = { errors: [] };
|
|
8441
|
-
const processError = (error41,
|
|
8441
|
+
const processError = (error41, path31 = []) => {
|
|
8442
8442
|
var _a2, _b;
|
|
8443
8443
|
for (const issue2 of error41.issues) {
|
|
8444
8444
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
@@ -8448,7 +8448,7 @@ function treeifyError(error40, _mapper) {
|
|
|
8448
8448
|
} else if (issue2.code === "invalid_element") {
|
|
8449
8449
|
processError({ issues: issue2.issues }, issue2.path);
|
|
8450
8450
|
} else {
|
|
8451
|
-
const fullpath = [...
|
|
8451
|
+
const fullpath = [...path31, ...issue2.path];
|
|
8452
8452
|
if (fullpath.length === 0) {
|
|
8453
8453
|
result.errors.push(mapper(issue2));
|
|
8454
8454
|
continue;
|
|
@@ -8478,9 +8478,9 @@ function treeifyError(error40, _mapper) {
|
|
|
8478
8478
|
processError(error40);
|
|
8479
8479
|
return result;
|
|
8480
8480
|
}
|
|
8481
|
-
function toDotPath(
|
|
8481
|
+
function toDotPath(path31) {
|
|
8482
8482
|
const segs = [];
|
|
8483
|
-
for (const seg of
|
|
8483
|
+
for (const seg of path31) {
|
|
8484
8484
|
if (typeof seg === "number")
|
|
8485
8485
|
segs.push(`[${seg}]`);
|
|
8486
8486
|
else if (typeof seg === "symbol")
|
|
@@ -20943,8 +20943,8 @@ var init_acp = __esm({
|
|
|
20943
20943
|
this.#requestHandler = requestHandler;
|
|
20944
20944
|
this.#notificationHandler = notificationHandler;
|
|
20945
20945
|
this.#stream = stream;
|
|
20946
|
-
this.#closedPromise = new Promise((
|
|
20947
|
-
this.#abortController.signal.addEventListener("abort", () =>
|
|
20946
|
+
this.#closedPromise = new Promise((resolve15) => {
|
|
20947
|
+
this.#abortController.signal.addEventListener("abort", () => resolve15());
|
|
20948
20948
|
});
|
|
20949
20949
|
this.#receive();
|
|
20950
20950
|
}
|
|
@@ -21093,8 +21093,8 @@ var init_acp = __esm({
|
|
|
21093
21093
|
}
|
|
21094
21094
|
async sendRequest(method, params) {
|
|
21095
21095
|
const id = this.#nextRequestId++;
|
|
21096
|
-
const responsePromise = new Promise((
|
|
21097
|
-
this.#pendingResponses.set(id, { resolve:
|
|
21096
|
+
const responsePromise = new Promise((resolve15, reject) => {
|
|
21097
|
+
this.#pendingResponses.set(id, { resolve: resolve15, reject });
|
|
21098
21098
|
});
|
|
21099
21099
|
await this.#sendMessage({ jsonrpc: "2.0", id, method, params });
|
|
21100
21100
|
return responsePromise;
|
|
@@ -21963,10 +21963,10 @@ var require_src2 = __commonJS({
|
|
|
21963
21963
|
var fs_1 = __require("fs");
|
|
21964
21964
|
var debug_1 = __importDefault(require_src());
|
|
21965
21965
|
var log2 = debug_1.default("@kwsites/file-exists");
|
|
21966
|
-
function check2(
|
|
21967
|
-
log2(`checking %s`,
|
|
21966
|
+
function check2(path31, isFile, isDirectory) {
|
|
21967
|
+
log2(`checking %s`, path31);
|
|
21968
21968
|
try {
|
|
21969
|
-
const stat2 = fs_1.statSync(
|
|
21969
|
+
const stat2 = fs_1.statSync(path31);
|
|
21970
21970
|
if (stat2.isFile() && isFile) {
|
|
21971
21971
|
log2(`[OK] path represents a file`);
|
|
21972
21972
|
return true;
|
|
@@ -21986,8 +21986,8 @@ var require_src2 = __commonJS({
|
|
|
21986
21986
|
throw e;
|
|
21987
21987
|
}
|
|
21988
21988
|
}
|
|
21989
|
-
function exists2(
|
|
21990
|
-
return check2(
|
|
21989
|
+
function exists2(path31, type = exports.READABLE) {
|
|
21990
|
+
return check2(path31, (type & exports.FILE) > 0, (type & exports.FOLDER) > 0);
|
|
21991
21991
|
}
|
|
21992
21992
|
exports.exists = exists2;
|
|
21993
21993
|
exports.FILE = 1;
|
|
@@ -22413,7 +22413,7 @@ async function createSdkStdioAcpClient(options) {
|
|
|
22413
22413
|
child.once("close", (code, signal) => {
|
|
22414
22414
|
onAgentSubprocessExit?.({ code, signal });
|
|
22415
22415
|
});
|
|
22416
|
-
return new Promise((
|
|
22416
|
+
return new Promise((resolve15, reject) => {
|
|
22417
22417
|
let initSettled = false;
|
|
22418
22418
|
const settleReject = (err) => {
|
|
22419
22419
|
if (initSettled) return;
|
|
@@ -22427,7 +22427,7 @@ async function createSdkStdioAcpClient(options) {
|
|
|
22427
22427
|
const settleResolve = (handle) => {
|
|
22428
22428
|
if (initSettled) return;
|
|
22429
22429
|
initSettled = true;
|
|
22430
|
-
|
|
22430
|
+
resolve15(handle);
|
|
22431
22431
|
};
|
|
22432
22432
|
child.on("error", (err) => {
|
|
22433
22433
|
settleReject(new Error(formatSpawnError(err, command[0])));
|
|
@@ -22463,8 +22463,8 @@ async function createSdkStdioAcpClient(options) {
|
|
|
22463
22463
|
});
|
|
22464
22464
|
} catch {
|
|
22465
22465
|
}
|
|
22466
|
-
return await new Promise((
|
|
22467
|
-
pendingPermissionResolvers.set(requestId,
|
|
22466
|
+
return await new Promise((resolve16) => {
|
|
22467
|
+
pendingPermissionResolvers.set(requestId, resolve16);
|
|
22468
22468
|
});
|
|
22469
22469
|
},
|
|
22470
22470
|
async readTextFile(params) {
|
|
@@ -22572,9 +22572,9 @@ async function createSdkStdioAcpClient(options) {
|
|
|
22572
22572
|
}
|
|
22573
22573
|
},
|
|
22574
22574
|
async cancel() {
|
|
22575
|
-
for (const [id,
|
|
22575
|
+
for (const [id, resolve16] of [...pendingPermissionResolvers.entries()]) {
|
|
22576
22576
|
pendingPermissionResolvers.delete(id);
|
|
22577
|
-
|
|
22577
|
+
resolve16({ outcome: { outcome: "cancelled" } });
|
|
22578
22578
|
}
|
|
22579
22579
|
try {
|
|
22580
22580
|
await connection.cancel({ sessionId });
|
|
@@ -22590,10 +22590,10 @@ async function createSdkStdioAcpClient(options) {
|
|
|
22590
22590
|
}
|
|
22591
22591
|
},
|
|
22592
22592
|
resolveRequest(requestId, result) {
|
|
22593
|
-
const
|
|
22594
|
-
if (!
|
|
22593
|
+
const resolve16 = pendingPermissionResolvers.get(requestId);
|
|
22594
|
+
if (!resolve16) return;
|
|
22595
22595
|
pendingPermissionResolvers.delete(requestId);
|
|
22596
|
-
|
|
22596
|
+
resolve16(result);
|
|
22597
22597
|
},
|
|
22598
22598
|
disconnect() {
|
|
22599
22599
|
child.kill();
|
|
@@ -22700,7 +22700,7 @@ async function proxyToLocal(request) {
|
|
|
22700
22700
|
};
|
|
22701
22701
|
const maxAttempts = isIdempotentProxyMethod(request.method) ? LOCAL_PREVIEW_FETCH_RETRY_DELAYS_MS.length + 1 : 1;
|
|
22702
22702
|
for (let attempt = 0; attempt < maxAttempts; attempt += 1) {
|
|
22703
|
-
const once = await new Promise((
|
|
22703
|
+
const once = await new Promise((resolve15) => {
|
|
22704
22704
|
const req = mod.request(opts, (res) => {
|
|
22705
22705
|
const chunks = [];
|
|
22706
22706
|
res.on("data", (c) => chunks.push(c));
|
|
@@ -22711,7 +22711,7 @@ async function proxyToLocal(request) {
|
|
|
22711
22711
|
if (typeof v === "string") headers[k] = v;
|
|
22712
22712
|
else if (Array.isArray(v) && v[0]) headers[k] = v[0];
|
|
22713
22713
|
}
|
|
22714
|
-
|
|
22714
|
+
resolve15({
|
|
22715
22715
|
id: request.id,
|
|
22716
22716
|
statusCode: res.statusCode ?? 0,
|
|
22717
22717
|
headers,
|
|
@@ -22720,7 +22720,7 @@ async function proxyToLocal(request) {
|
|
|
22720
22720
|
});
|
|
22721
22721
|
});
|
|
22722
22722
|
req.on("error", (err) => {
|
|
22723
|
-
|
|
22723
|
+
resolve15({
|
|
22724
22724
|
id: request.id,
|
|
22725
22725
|
statusCode: 0,
|
|
22726
22726
|
headers: {},
|
|
@@ -22802,8 +22802,8 @@ function randomSecret() {
|
|
|
22802
22802
|
}
|
|
22803
22803
|
return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
22804
22804
|
}
|
|
22805
|
-
async function requestPreviewApi(port, secret, method,
|
|
22806
|
-
const url2 = `http://127.0.0.1:${port}${
|
|
22805
|
+
async function requestPreviewApi(port, secret, method, path31, body) {
|
|
22806
|
+
const url2 = `http://127.0.0.1:${port}${path31}`;
|
|
22807
22807
|
const headers = {
|
|
22808
22808
|
[PREVIEW_SECRET_HEADER]: secret,
|
|
22809
22809
|
"Content-Type": "application/json"
|
|
@@ -22815,7 +22815,7 @@ async function requestPreviewApi(port, secret, method, path29, body) {
|
|
|
22815
22815
|
});
|
|
22816
22816
|
const data = await res.json().catch(() => ({}));
|
|
22817
22817
|
if (!res.ok) {
|
|
22818
|
-
throw new Error(data?.error ?? `Preview API ${method} ${
|
|
22818
|
+
throw new Error(data?.error ?? `Preview API ${method} ${path31}: ${res.status}`);
|
|
22819
22819
|
}
|
|
22820
22820
|
return data;
|
|
22821
22821
|
}
|
|
@@ -23027,6 +23027,19 @@ function clearConfigForApi(apiUrl) {
|
|
|
23027
23027
|
}
|
|
23028
23028
|
}
|
|
23029
23029
|
|
|
23030
|
+
// src/process-bridge-resilience.ts
|
|
23031
|
+
var installed = false;
|
|
23032
|
+
function installBridgeProcessResilience() {
|
|
23033
|
+
if (installed) return;
|
|
23034
|
+
installed = true;
|
|
23035
|
+
process.on("uncaughtException", (err) => {
|
|
23036
|
+
logImmediate(`[bridge] uncaughtException \u2014 continuing: ${err.stack ?? String(err)}`);
|
|
23037
|
+
});
|
|
23038
|
+
process.on("unhandledRejection", (reason) => {
|
|
23039
|
+
logImmediate(`[bridge] unhandledRejection \u2014 continuing: ${reason instanceof Error ? reason.stack : String(reason)}`);
|
|
23040
|
+
});
|
|
23041
|
+
}
|
|
23042
|
+
|
|
23030
23043
|
// src/auth/open-browser.ts
|
|
23031
23044
|
import { execSync } from "node:child_process";
|
|
23032
23045
|
function isLocalApiUrl(apiUrl) {
|
|
@@ -23246,8 +23259,8 @@ function runPendingAuth(options) {
|
|
|
23246
23259
|
let hasOpenedBrowser = false;
|
|
23247
23260
|
let resolved = false;
|
|
23248
23261
|
let resolveAuth;
|
|
23249
|
-
const authPromise = new Promise((
|
|
23250
|
-
resolveAuth =
|
|
23262
|
+
const authPromise = new Promise((resolve15) => {
|
|
23263
|
+
resolveAuth = resolve15;
|
|
23251
23264
|
});
|
|
23252
23265
|
let reconnectAttempt = 0;
|
|
23253
23266
|
const signInQuiet = createEmptyReconnectQuietSlot();
|
|
@@ -23369,7 +23382,7 @@ function runPendingAuth(options) {
|
|
|
23369
23382
|
async function closeBridgeConnection(state, acpManager, devServerManager, log2) {
|
|
23370
23383
|
const say = log2 ?? logImmediate;
|
|
23371
23384
|
say("Cleaning up connections\u2026");
|
|
23372
|
-
await new Promise((
|
|
23385
|
+
await new Promise((resolve15) => setImmediate(resolve15));
|
|
23373
23386
|
state.closedByUser = true;
|
|
23374
23387
|
clearReconnectQuietTimer(state.mainQuiet);
|
|
23375
23388
|
clearReconnectQuietTimer(state.firehoseQuiet);
|
|
@@ -23464,8 +23477,8 @@ function pathspec(...paths) {
|
|
|
23464
23477
|
cache.set(key, paths);
|
|
23465
23478
|
return key;
|
|
23466
23479
|
}
|
|
23467
|
-
function isPathSpec(
|
|
23468
|
-
return
|
|
23480
|
+
function isPathSpec(path31) {
|
|
23481
|
+
return path31 instanceof String && cache.has(path31);
|
|
23469
23482
|
}
|
|
23470
23483
|
function toPaths(pathSpec) {
|
|
23471
23484
|
return cache.get(pathSpec) || [];
|
|
@@ -23554,8 +23567,8 @@ function toLinesWithContent(input = "", trimmed2 = true, separator = "\n") {
|
|
|
23554
23567
|
function forEachLineWithContent(input, callback) {
|
|
23555
23568
|
return toLinesWithContent(input, true).map((line) => callback(line));
|
|
23556
23569
|
}
|
|
23557
|
-
function folderExists(
|
|
23558
|
-
return (0, import_file_exists.exists)(
|
|
23570
|
+
function folderExists(path31) {
|
|
23571
|
+
return (0, import_file_exists.exists)(path31, import_file_exists.FOLDER);
|
|
23559
23572
|
}
|
|
23560
23573
|
function append(target, item) {
|
|
23561
23574
|
if (Array.isArray(target)) {
|
|
@@ -23959,8 +23972,8 @@ function checkIsRepoRootTask() {
|
|
|
23959
23972
|
commands,
|
|
23960
23973
|
format: "utf-8",
|
|
23961
23974
|
onError,
|
|
23962
|
-
parser(
|
|
23963
|
-
return /^\.(git)?$/.test(
|
|
23975
|
+
parser(path31) {
|
|
23976
|
+
return /^\.(git)?$/.test(path31.trim());
|
|
23964
23977
|
}
|
|
23965
23978
|
};
|
|
23966
23979
|
}
|
|
@@ -24394,11 +24407,11 @@ function parseGrep(grep) {
|
|
|
24394
24407
|
const paths = /* @__PURE__ */ new Set();
|
|
24395
24408
|
const results = {};
|
|
24396
24409
|
forEachLineWithContent(grep, (input) => {
|
|
24397
|
-
const [
|
|
24398
|
-
paths.add(
|
|
24399
|
-
(results[
|
|
24410
|
+
const [path31, line, preview] = input.split(NULL);
|
|
24411
|
+
paths.add(path31);
|
|
24412
|
+
(results[path31] = results[path31] || []).push({
|
|
24400
24413
|
line: asNumber(line),
|
|
24401
|
-
path:
|
|
24414
|
+
path: path31,
|
|
24402
24415
|
preview
|
|
24403
24416
|
});
|
|
24404
24417
|
});
|
|
@@ -25163,14 +25176,14 @@ var init_hash_object = __esm2({
|
|
|
25163
25176
|
init_task();
|
|
25164
25177
|
}
|
|
25165
25178
|
});
|
|
25166
|
-
function parseInit(bare,
|
|
25179
|
+
function parseInit(bare, path31, text) {
|
|
25167
25180
|
const response = String(text).trim();
|
|
25168
25181
|
let result;
|
|
25169
25182
|
if (result = initResponseRegex.exec(response)) {
|
|
25170
|
-
return new InitSummary(bare,
|
|
25183
|
+
return new InitSummary(bare, path31, false, result[1]);
|
|
25171
25184
|
}
|
|
25172
25185
|
if (result = reInitResponseRegex.exec(response)) {
|
|
25173
|
-
return new InitSummary(bare,
|
|
25186
|
+
return new InitSummary(bare, path31, true, result[1]);
|
|
25174
25187
|
}
|
|
25175
25188
|
let gitDir = "";
|
|
25176
25189
|
const tokens = response.split(" ");
|
|
@@ -25181,7 +25194,7 @@ function parseInit(bare, path29, text) {
|
|
|
25181
25194
|
break;
|
|
25182
25195
|
}
|
|
25183
25196
|
}
|
|
25184
|
-
return new InitSummary(bare,
|
|
25197
|
+
return new InitSummary(bare, path31, /^re/i.test(response), gitDir);
|
|
25185
25198
|
}
|
|
25186
25199
|
var InitSummary;
|
|
25187
25200
|
var initResponseRegex;
|
|
@@ -25190,9 +25203,9 @@ var init_InitSummary = __esm2({
|
|
|
25190
25203
|
"src/lib/responses/InitSummary.ts"() {
|
|
25191
25204
|
"use strict";
|
|
25192
25205
|
InitSummary = class {
|
|
25193
|
-
constructor(bare,
|
|
25206
|
+
constructor(bare, path31, existing, gitDir) {
|
|
25194
25207
|
this.bare = bare;
|
|
25195
|
-
this.path =
|
|
25208
|
+
this.path = path31;
|
|
25196
25209
|
this.existing = existing;
|
|
25197
25210
|
this.gitDir = gitDir;
|
|
25198
25211
|
}
|
|
@@ -25204,7 +25217,7 @@ var init_InitSummary = __esm2({
|
|
|
25204
25217
|
function hasBareCommand(command) {
|
|
25205
25218
|
return command.includes(bareCommand);
|
|
25206
25219
|
}
|
|
25207
|
-
function initTask(bare = false,
|
|
25220
|
+
function initTask(bare = false, path31, customArgs) {
|
|
25208
25221
|
const commands = ["init", ...customArgs];
|
|
25209
25222
|
if (bare && !hasBareCommand(commands)) {
|
|
25210
25223
|
commands.splice(1, 0, bareCommand);
|
|
@@ -25213,7 +25226,7 @@ function initTask(bare = false, path29, customArgs) {
|
|
|
25213
25226
|
commands,
|
|
25214
25227
|
format: "utf-8",
|
|
25215
25228
|
parser(text) {
|
|
25216
|
-
return parseInit(commands.includes("--bare"),
|
|
25229
|
+
return parseInit(commands.includes("--bare"), path31, text);
|
|
25217
25230
|
}
|
|
25218
25231
|
};
|
|
25219
25232
|
}
|
|
@@ -26029,12 +26042,12 @@ var init_FileStatusSummary = __esm2({
|
|
|
26029
26042
|
"use strict";
|
|
26030
26043
|
fromPathRegex = /^(.+)\0(.+)$/;
|
|
26031
26044
|
FileStatusSummary = class {
|
|
26032
|
-
constructor(
|
|
26033
|
-
this.path =
|
|
26045
|
+
constructor(path31, index, working_dir) {
|
|
26046
|
+
this.path = path31;
|
|
26034
26047
|
this.index = index;
|
|
26035
26048
|
this.working_dir = working_dir;
|
|
26036
26049
|
if (index === "R" || working_dir === "R") {
|
|
26037
|
-
const detail = fromPathRegex.exec(
|
|
26050
|
+
const detail = fromPathRegex.exec(path31) || [null, path31, path31];
|
|
26038
26051
|
this.from = detail[2] || "";
|
|
26039
26052
|
this.path = detail[1] || "";
|
|
26040
26053
|
}
|
|
@@ -26065,14 +26078,14 @@ function splitLine(result, lineStr) {
|
|
|
26065
26078
|
default:
|
|
26066
26079
|
return;
|
|
26067
26080
|
}
|
|
26068
|
-
function data(index, workingDir,
|
|
26081
|
+
function data(index, workingDir, path31) {
|
|
26069
26082
|
const raw = `${index}${workingDir}`;
|
|
26070
26083
|
const handler = parsers6.get(raw);
|
|
26071
26084
|
if (handler) {
|
|
26072
|
-
handler(result,
|
|
26085
|
+
handler(result, path31);
|
|
26073
26086
|
}
|
|
26074
26087
|
if (raw !== "##" && raw !== "!!") {
|
|
26075
|
-
result.files.push(new FileStatusSummary(
|
|
26088
|
+
result.files.push(new FileStatusSummary(path31, index, workingDir));
|
|
26076
26089
|
}
|
|
26077
26090
|
}
|
|
26078
26091
|
}
|
|
@@ -26243,14 +26256,14 @@ var init_status = __esm2({
|
|
|
26243
26256
|
ignoredOptions = ["--null", "-z"];
|
|
26244
26257
|
}
|
|
26245
26258
|
});
|
|
26246
|
-
function versionResponse(major = 0, minor = 0, patch = 0, agent = "",
|
|
26259
|
+
function versionResponse(major = 0, minor = 0, patch = 0, agent = "", installed2 = true) {
|
|
26247
26260
|
return Object.defineProperty(
|
|
26248
26261
|
{
|
|
26249
26262
|
major,
|
|
26250
26263
|
minor,
|
|
26251
26264
|
patch,
|
|
26252
26265
|
agent,
|
|
26253
|
-
installed
|
|
26266
|
+
installed: installed2
|
|
26254
26267
|
},
|
|
26255
26268
|
"toString",
|
|
26256
26269
|
{
|
|
@@ -26381,9 +26394,9 @@ var init_simple_git_api = __esm2({
|
|
|
26381
26394
|
next
|
|
26382
26395
|
);
|
|
26383
26396
|
}
|
|
26384
|
-
hashObject(
|
|
26397
|
+
hashObject(path31, write) {
|
|
26385
26398
|
return this._runTask(
|
|
26386
|
-
hashObjectTask(
|
|
26399
|
+
hashObjectTask(path31, write === true),
|
|
26387
26400
|
trailingFunctionArgument(arguments)
|
|
26388
26401
|
);
|
|
26389
26402
|
}
|
|
@@ -26736,8 +26749,8 @@ var init_branch = __esm2({
|
|
|
26736
26749
|
}
|
|
26737
26750
|
});
|
|
26738
26751
|
function toPath(input) {
|
|
26739
|
-
const
|
|
26740
|
-
return
|
|
26752
|
+
const path31 = input.trim().replace(/^["']|["']$/g, "");
|
|
26753
|
+
return path31 && normalize2(path31);
|
|
26741
26754
|
}
|
|
26742
26755
|
var parseCheckIgnore;
|
|
26743
26756
|
var init_CheckIgnore = __esm2({
|
|
@@ -27051,8 +27064,8 @@ __export2(sub_module_exports, {
|
|
|
27051
27064
|
subModuleTask: () => subModuleTask,
|
|
27052
27065
|
updateSubModuleTask: () => updateSubModuleTask
|
|
27053
27066
|
});
|
|
27054
|
-
function addSubModuleTask(repo,
|
|
27055
|
-
return subModuleTask(["add", repo,
|
|
27067
|
+
function addSubModuleTask(repo, path31) {
|
|
27068
|
+
return subModuleTask(["add", repo, path31]);
|
|
27056
27069
|
}
|
|
27057
27070
|
function initSubModuleTask(customArgs) {
|
|
27058
27071
|
return subModuleTask(["init", ...customArgs]);
|
|
@@ -27385,8 +27398,8 @@ var require_git = __commonJS2({
|
|
|
27385
27398
|
}
|
|
27386
27399
|
return this._runTask(straightThroughStringTask2(command, this._trimmed), next);
|
|
27387
27400
|
};
|
|
27388
|
-
Git2.prototype.submoduleAdd = function(repo,
|
|
27389
|
-
return this._runTask(addSubModuleTask2(repo,
|
|
27401
|
+
Git2.prototype.submoduleAdd = function(repo, path31, then) {
|
|
27402
|
+
return this._runTask(addSubModuleTask2(repo, path31), trailingFunctionArgument2(arguments));
|
|
27390
27403
|
};
|
|
27391
27404
|
Git2.prototype.submoduleUpdate = function(args, then) {
|
|
27392
27405
|
return this._runTask(
|
|
@@ -28475,7 +28488,7 @@ async function createCursorAcpClient(options) {
|
|
|
28475
28488
|
});
|
|
28476
28489
|
const stderrCapture = createStderrCapture(child);
|
|
28477
28490
|
child.stderr?.on("data", (chunk) => stderrCapture.append(chunk));
|
|
28478
|
-
return new Promise((
|
|
28491
|
+
return new Promise((resolve15, reject) => {
|
|
28479
28492
|
child.on("error", (err) => {
|
|
28480
28493
|
child.kill();
|
|
28481
28494
|
reject(new Error(formatSpawnError2(err, command[0])));
|
|
@@ -28662,7 +28675,7 @@ async function createCursorAcpClient(options) {
|
|
|
28662
28675
|
const newResult = await send("session/new", { cwd, mcpServers: [] });
|
|
28663
28676
|
const sessionId = newResult?.sessionId ?? "";
|
|
28664
28677
|
if (!sessionId) throw new Error("Cursor ACP session/new did not return sessionId");
|
|
28665
|
-
|
|
28678
|
+
resolve15({
|
|
28666
28679
|
sessionId,
|
|
28667
28680
|
async sendPrompt(prompt, _options) {
|
|
28668
28681
|
promptOutputBuffer = "";
|
|
@@ -29720,7 +29733,7 @@ async function createAcpManager(options) {
|
|
|
29720
29733
|
}
|
|
29721
29734
|
|
|
29722
29735
|
// src/worktrees/session-worktree-manager.ts
|
|
29723
|
-
import * as
|
|
29736
|
+
import * as path15 from "node:path";
|
|
29724
29737
|
import os3 from "node:os";
|
|
29725
29738
|
|
|
29726
29739
|
// src/worktrees/prepare-new-session-worktrees.ts
|
|
@@ -29887,7 +29900,7 @@ async function removeSessionWorktrees(paths, log2) {
|
|
|
29887
29900
|
}
|
|
29888
29901
|
}
|
|
29889
29902
|
|
|
29890
|
-
// src/git/working-tree-status.ts
|
|
29903
|
+
// src/git/working-directory/status/working-tree-status.ts
|
|
29891
29904
|
async function tryConfigGet(g, key) {
|
|
29892
29905
|
try {
|
|
29893
29906
|
const out = await g.raw(["config", "--get", key]);
|
|
@@ -29897,11 +29910,24 @@ async function tryConfigGet(g, key) {
|
|
|
29897
29910
|
return null;
|
|
29898
29911
|
}
|
|
29899
29912
|
}
|
|
29913
|
+
async function revParseSafe(g, ref) {
|
|
29914
|
+
try {
|
|
29915
|
+
const v = (await g.raw(["rev-parse", ref])).trim();
|
|
29916
|
+
return v || null;
|
|
29917
|
+
} catch {
|
|
29918
|
+
return null;
|
|
29919
|
+
}
|
|
29920
|
+
}
|
|
29900
29921
|
async function resolveRemoteTrackingRefForAhead(g) {
|
|
29901
29922
|
try {
|
|
29902
|
-
await g.raw(["rev-parse", "--verify", "@{
|
|
29903
|
-
return "@{
|
|
29923
|
+
await g.raw(["rev-parse", "--verify", "HEAD@{upstream}"]);
|
|
29924
|
+
return "HEAD@{upstream}";
|
|
29904
29925
|
} catch {
|
|
29926
|
+
try {
|
|
29927
|
+
await g.raw(["rev-parse", "--verify", "@{u}"]);
|
|
29928
|
+
return "@{u}";
|
|
29929
|
+
} catch {
|
|
29930
|
+
}
|
|
29905
29931
|
}
|
|
29906
29932
|
const branch = (await g.raw(["rev-parse", "--abbrev-ref", "HEAD"])).trim();
|
|
29907
29933
|
if (!branch || branch === "HEAD") return null;
|
|
@@ -29924,16 +29950,76 @@ async function resolveRemoteTrackingRefForAhead(g) {
|
|
|
29924
29950
|
return null;
|
|
29925
29951
|
}
|
|
29926
29952
|
}
|
|
29953
|
+
async function remoteForCurrentBranch(g) {
|
|
29954
|
+
const branch = (await g.raw(["rev-parse", "--abbrev-ref", "HEAD"])).trim();
|
|
29955
|
+
if (!branch || branch === "HEAD") return "origin";
|
|
29956
|
+
return await tryConfigGet(g, `branch.${branch}.remote`) ?? "origin";
|
|
29957
|
+
}
|
|
29958
|
+
async function resolveDefaultRemoteBranchRef(g, remote) {
|
|
29959
|
+
const headSym = `refs/remotes/${remote}/HEAD`;
|
|
29960
|
+
try {
|
|
29961
|
+
const resolved = (await g.raw(["symbolic-ref", "-q", "--verify", headSym])).trim();
|
|
29962
|
+
if (resolved.startsWith("refs/remotes/")) return resolved;
|
|
29963
|
+
} catch {
|
|
29964
|
+
}
|
|
29965
|
+
for (const name of ["main", "master", "trunk", "develop"]) {
|
|
29966
|
+
const r = `refs/remotes/${remote}/${name}`;
|
|
29967
|
+
try {
|
|
29968
|
+
await g.raw(["rev-parse", "--verify", r]);
|
|
29969
|
+
return r;
|
|
29970
|
+
} catch {
|
|
29971
|
+
}
|
|
29972
|
+
}
|
|
29973
|
+
return null;
|
|
29974
|
+
}
|
|
29975
|
+
async function resolveBaseShaForUnpushedCommits(g) {
|
|
29976
|
+
const trackingRef = await resolveRemoteTrackingRefForAhead(g);
|
|
29977
|
+
if (trackingRef) {
|
|
29978
|
+
const sha = await revParseSafe(g, trackingRef);
|
|
29979
|
+
if (sha) return sha;
|
|
29980
|
+
}
|
|
29981
|
+
const remote = await remoteForCurrentBranch(g);
|
|
29982
|
+
const defaultRef = await resolveDefaultRemoteBranchRef(g, remote);
|
|
29983
|
+
if (!defaultRef) return null;
|
|
29984
|
+
return revParseSafe(g, defaultRef);
|
|
29985
|
+
}
|
|
29986
|
+
function parseLogShaDateSubjectLines(raw) {
|
|
29987
|
+
const out = [];
|
|
29988
|
+
for (const line of String(raw).split("\n")) {
|
|
29989
|
+
const l = line.trimEnd();
|
|
29990
|
+
if (!l.trim()) continue;
|
|
29991
|
+
const parts = l.split(" ");
|
|
29992
|
+
if (parts.length < 3) continue;
|
|
29993
|
+
const sha = parts[0].trim();
|
|
29994
|
+
const committedAt = parts[1].trim();
|
|
29995
|
+
const subject = parts.slice(2).join(" ").trim();
|
|
29996
|
+
if (!/^[0-9a-f]{7,40}$/i.test(sha)) continue;
|
|
29997
|
+
out.push({ sha, shortSha: sha.slice(0, 7), subject, committedAt });
|
|
29998
|
+
}
|
|
29999
|
+
return out;
|
|
30000
|
+
}
|
|
30001
|
+
async function gitLogNotReachableFromBase(g, baseSha, headSha) {
|
|
30002
|
+
if (baseSha === headSha) return [];
|
|
30003
|
+
try {
|
|
30004
|
+
const logOut = await g.raw(["log", "--format=%H %cI %s", `${baseSha}..${headSha}`]);
|
|
30005
|
+
return parseLogShaDateSubjectLines(logOut);
|
|
30006
|
+
} catch {
|
|
30007
|
+
return [];
|
|
30008
|
+
}
|
|
30009
|
+
}
|
|
29927
30010
|
async function commitsAheadOfRemoteTracking(repoDir) {
|
|
29928
30011
|
const g = simpleGit(repoDir);
|
|
29929
|
-
const
|
|
29930
|
-
if (!
|
|
29931
|
-
const
|
|
29932
|
-
|
|
29933
|
-
|
|
29934
|
-
|
|
29935
|
-
|
|
29936
|
-
|
|
30012
|
+
const headSha = await revParseSafe(g, "HEAD");
|
|
30013
|
+
if (!headSha) return 0;
|
|
30014
|
+
const baseSha = await resolveBaseShaForUnpushedCommits(g);
|
|
30015
|
+
if (!baseSha || baseSha === headSha) return 0;
|
|
30016
|
+
try {
|
|
30017
|
+
const out = await g.raw(["rev-list", "--count", `${baseSha}..${headSha}`]);
|
|
30018
|
+
const n = parseInt(String(out).trim(), 10);
|
|
30019
|
+
return Number.isNaN(n) ? 0 : n;
|
|
30020
|
+
} catch {
|
|
30021
|
+
return 0;
|
|
30022
|
+
}
|
|
29937
30023
|
}
|
|
29938
30024
|
async function getRepoWorkingTreeStatus(repoDir) {
|
|
29939
30025
|
const g = simpleGit(repoDir);
|
|
@@ -29942,6 +30028,14 @@ async function getRepoWorkingTreeStatus(repoDir) {
|
|
|
29942
30028
|
const ahead = await commitsAheadOfRemoteTracking(repoDir);
|
|
29943
30029
|
return { hasUncommittedChanges, hasUnpushedCommits: ahead > 0 };
|
|
29944
30030
|
}
|
|
30031
|
+
async function listUnpushedCommits(repoDir) {
|
|
30032
|
+
const g = simpleGit(repoDir);
|
|
30033
|
+
const headSha = await revParseSafe(g, "HEAD");
|
|
30034
|
+
if (!headSha) return [];
|
|
30035
|
+
const baseSha = await resolveBaseShaForUnpushedCommits(g);
|
|
30036
|
+
if (!baseSha) return [];
|
|
30037
|
+
return gitLogNotReachableFromBase(g, baseSha, headSha);
|
|
30038
|
+
}
|
|
29945
30039
|
async function aggregateSessionPathsWorkingTreeStatus(paths) {
|
|
29946
30040
|
let hasUncommittedChanges = false;
|
|
29947
30041
|
let hasUnpushedCommits = false;
|
|
@@ -29961,6 +30055,477 @@ async function pushAheadOfUpstreamForPaths(paths) {
|
|
|
29961
30055
|
}
|
|
29962
30056
|
}
|
|
29963
30057
|
|
|
30058
|
+
// src/git/working-directory/changes/types.ts
|
|
30059
|
+
var MAX_PATCH_CHARS = 35e4;
|
|
30060
|
+
|
|
30061
|
+
// src/git/working-directory/changes/repo-format.ts
|
|
30062
|
+
function posixJoinDirFile(dir, file2) {
|
|
30063
|
+
const d = dir === "." || dir === "" ? "" : dir.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
30064
|
+
const f = file2.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
30065
|
+
return d ? `${d}/${f}` : f;
|
|
30066
|
+
}
|
|
30067
|
+
function formatRepoShortTitle(remoteUrl, repoRelPath) {
|
|
30068
|
+
const u = remoteUrl.trim();
|
|
30069
|
+
if (u) {
|
|
30070
|
+
try {
|
|
30071
|
+
if (u.startsWith("git@")) {
|
|
30072
|
+
const colon = u.indexOf(":");
|
|
30073
|
+
if (colon > 0) {
|
|
30074
|
+
const pathPart = u.slice(colon + 1).replace(/\.git$/i, "").replace(/\/+$/, "");
|
|
30075
|
+
if (pathPart.includes("/")) return pathPart;
|
|
30076
|
+
}
|
|
30077
|
+
} else {
|
|
30078
|
+
const parsed = new URL(u);
|
|
30079
|
+
const p = parsed.pathname.replace(/^\//, "").replace(/\.git$/i, "");
|
|
30080
|
+
const parts = p.split("/").filter(Boolean);
|
|
30081
|
+
if (parts.length >= 2) {
|
|
30082
|
+
return `${parts[parts.length - 2]}/${parts[parts.length - 1]}`;
|
|
30083
|
+
}
|
|
30084
|
+
if (parts.length === 1) return parts[0];
|
|
30085
|
+
}
|
|
30086
|
+
} catch {
|
|
30087
|
+
}
|
|
30088
|
+
}
|
|
30089
|
+
if (repoRelPath && repoRelPath !== ".") {
|
|
30090
|
+
const segments = repoRelPath.split("/").filter(Boolean);
|
|
30091
|
+
const last2 = segments[segments.length - 1];
|
|
30092
|
+
if (last2) return last2;
|
|
30093
|
+
}
|
|
30094
|
+
return "Repository";
|
|
30095
|
+
}
|
|
30096
|
+
function formatRemoteDisplayLabel(remoteUrl) {
|
|
30097
|
+
const u = remoteUrl.trim();
|
|
30098
|
+
if (!u) return "";
|
|
30099
|
+
let hostPath = u;
|
|
30100
|
+
try {
|
|
30101
|
+
if (u.startsWith("git@")) {
|
|
30102
|
+
const rest = u.slice("git@".length);
|
|
30103
|
+
const slash = rest.indexOf(":");
|
|
30104
|
+
if (slash > 0) hostPath = `${rest.slice(0, slash)}/${rest.slice(slash + 1)}`;
|
|
30105
|
+
} else {
|
|
30106
|
+
const parsed = new URL(u);
|
|
30107
|
+
hostPath = `${parsed.hostname}${parsed.pathname}`.replace(/\/\.git$/i, "").replace(/\.git$/i, "");
|
|
30108
|
+
}
|
|
30109
|
+
} catch {
|
|
30110
|
+
hostPath = u.replace(/^https?:\/\//i, "").replace(/\.git$/i, "");
|
|
30111
|
+
}
|
|
30112
|
+
return `origin \xB7 ${hostPath}`;
|
|
30113
|
+
}
|
|
30114
|
+
|
|
30115
|
+
// src/git/working-directory/changes/get-working-tree-change-repo-details.ts
|
|
30116
|
+
import * as path14 from "node:path";
|
|
30117
|
+
|
|
30118
|
+
// src/git/working-directory/changes/parse-git-status.ts
|
|
30119
|
+
function parseNameStatusLines(lines) {
|
|
30120
|
+
const m = /* @__PURE__ */ new Map();
|
|
30121
|
+
for (const line of lines) {
|
|
30122
|
+
if (!line.trim()) continue;
|
|
30123
|
+
const tabParts = line.split(" ");
|
|
30124
|
+
if (tabParts.length < 2) continue;
|
|
30125
|
+
const status = tabParts[0].trim();
|
|
30126
|
+
const code = status[0];
|
|
30127
|
+
if (code === "A") {
|
|
30128
|
+
m.set(tabParts[tabParts.length - 1], "added");
|
|
30129
|
+
} else if (code === "D") {
|
|
30130
|
+
m.set(tabParts[tabParts.length - 1], "removed");
|
|
30131
|
+
} else if (code === "R" || code === "C") {
|
|
30132
|
+
if (tabParts.length >= 3) m.set(tabParts[tabParts.length - 1], "modified");
|
|
30133
|
+
} else if (code === "M" || code === "U" || code === "T") {
|
|
30134
|
+
m.set(tabParts[tabParts.length - 1], "modified");
|
|
30135
|
+
}
|
|
30136
|
+
}
|
|
30137
|
+
return m;
|
|
30138
|
+
}
|
|
30139
|
+
function parseNumstatFirstLine(line) {
|
|
30140
|
+
const parts = line.split(" ");
|
|
30141
|
+
if (parts.length < 3) return null;
|
|
30142
|
+
const [a, d] = parts;
|
|
30143
|
+
const additions = a === "-" ? 0 : parseInt(String(a), 10) || 0;
|
|
30144
|
+
const deletions = d === "-" ? 0 : parseInt(String(d), 10) || 0;
|
|
30145
|
+
return { additions, deletions };
|
|
30146
|
+
}
|
|
30147
|
+
function parseNumstat(lines) {
|
|
30148
|
+
const m = /* @__PURE__ */ new Map();
|
|
30149
|
+
for (const line of lines) {
|
|
30150
|
+
if (!line.trim()) continue;
|
|
30151
|
+
const parts = line.split(" ");
|
|
30152
|
+
if (parts.length < 3) continue;
|
|
30153
|
+
const [a, d, p] = parts;
|
|
30154
|
+
const additions = a === "-" ? 0 : parseInt(String(a), 10) || 0;
|
|
30155
|
+
const deletions = d === "-" ? 0 : parseInt(String(d), 10) || 0;
|
|
30156
|
+
m.set(p, { additions, deletions });
|
|
30157
|
+
}
|
|
30158
|
+
return m;
|
|
30159
|
+
}
|
|
30160
|
+
async function numstatFromGitNoIndex(g, pathInRepo) {
|
|
30161
|
+
const devNull = process.platform === "win32" ? "NUL" : "/dev/null";
|
|
30162
|
+
try {
|
|
30163
|
+
const out = await g.raw(["diff", "--numstat", "--no-index", "--", devNull, pathInRepo]);
|
|
30164
|
+
const first2 = String(out).split("\n").find((l) => l.trim()) ?? "";
|
|
30165
|
+
return parseNumstatFirstLine(first2);
|
|
30166
|
+
} catch {
|
|
30167
|
+
return null;
|
|
30168
|
+
}
|
|
30169
|
+
}
|
|
30170
|
+
|
|
30171
|
+
// src/git/working-directory/changes/patch-truncate.ts
|
|
30172
|
+
function truncatePatch(s) {
|
|
30173
|
+
if (s.length <= MAX_PATCH_CHARS) return s;
|
|
30174
|
+
return `${s.slice(0, MAX_PATCH_CHARS)}
|
|
30175
|
+
|
|
30176
|
+
\u2026 (diff truncated)`;
|
|
30177
|
+
}
|
|
30178
|
+
|
|
30179
|
+
// src/git/working-directory/changes/list-changed-files-for-commit.ts
|
|
30180
|
+
var EMPTY_TREE = "4b825dc642cb6eb9a060e54bf8d69288fbee4904";
|
|
30181
|
+
async function parentForCommitDiff(g, sha) {
|
|
30182
|
+
try {
|
|
30183
|
+
return (await g.raw(["rev-parse", `${sha}^1`])).trim();
|
|
30184
|
+
} catch {
|
|
30185
|
+
try {
|
|
30186
|
+
return (await g.raw(["rev-parse", `${sha}^`])).trim();
|
|
30187
|
+
} catch {
|
|
30188
|
+
return EMPTY_TREE;
|
|
30189
|
+
}
|
|
30190
|
+
}
|
|
30191
|
+
}
|
|
30192
|
+
async function listChangedFilesForCommit(repoGitCwd, repoRelPath, commitSha) {
|
|
30193
|
+
const g = simpleGit(repoGitCwd);
|
|
30194
|
+
const parent = await parentForCommitDiff(g, commitSha);
|
|
30195
|
+
const range = `${parent}..${commitSha}`;
|
|
30196
|
+
const [nameStatusRaw, numstatRaw] = await Promise.all([
|
|
30197
|
+
g.raw(["diff", "--name-status", range]).catch(() => ""),
|
|
30198
|
+
g.raw(["diff", "--numstat", range]).catch(() => "")
|
|
30199
|
+
]);
|
|
30200
|
+
const kindByPath = parseNameStatusLines(String(nameStatusRaw).split("\n"));
|
|
30201
|
+
const numByPath = parseNumstat(String(numstatRaw).split("\n"));
|
|
30202
|
+
const paths = new Set([...kindByPath.keys(), ...numByPath.keys()].filter(Boolean));
|
|
30203
|
+
const rows = [];
|
|
30204
|
+
const normRel = repoRelPath === "." || repoRelPath === "" ? "." : repoRelPath;
|
|
30205
|
+
for (const pathInRepo of paths) {
|
|
30206
|
+
const relLauncher = posixJoinDirFile(normRel, pathInRepo.replace(/\\/g, "/"));
|
|
30207
|
+
const nums = numByPath.get(pathInRepo);
|
|
30208
|
+
let additions = nums?.additions ?? 0;
|
|
30209
|
+
let deletions = nums?.deletions ?? 0;
|
|
30210
|
+
let change = kindByPath.get(pathInRepo) ?? "modified";
|
|
30211
|
+
if (!kindByPath.has(pathInRepo) && nums) {
|
|
30212
|
+
if (additions > 0 && deletions === 0) change = "added";
|
|
30213
|
+
else if (deletions > 0 && additions === 0) change = "removed";
|
|
30214
|
+
else change = "modified";
|
|
30215
|
+
}
|
|
30216
|
+
rows.push({ pathRelLauncher: relLauncher, additions, deletions, change });
|
|
30217
|
+
}
|
|
30218
|
+
for (const row of rows) {
|
|
30219
|
+
let pathInRepo;
|
|
30220
|
+
if (normRel === ".") {
|
|
30221
|
+
pathInRepo = row.pathRelLauncher;
|
|
30222
|
+
} else if (row.pathRelLauncher.startsWith(`${normRel}/`)) {
|
|
30223
|
+
pathInRepo = row.pathRelLauncher.slice(normRel.length + 1);
|
|
30224
|
+
} else {
|
|
30225
|
+
pathInRepo = row.pathRelLauncher;
|
|
30226
|
+
}
|
|
30227
|
+
const raw = await g.raw(["diff", "-U20000", range, "--", pathInRepo]).catch(() => "");
|
|
30228
|
+
const t = String(raw).trim();
|
|
30229
|
+
row.patchContent = t ? truncatePatch(t) : void 0;
|
|
30230
|
+
}
|
|
30231
|
+
rows.sort((a, b) => a.pathRelLauncher.localeCompare(b.pathRelLauncher));
|
|
30232
|
+
return rows;
|
|
30233
|
+
}
|
|
30234
|
+
|
|
30235
|
+
// src/git/working-directory/changes/list-changed-files-for-repo.ts
|
|
30236
|
+
import * as fs11 from "node:fs";
|
|
30237
|
+
import * as path13 from "node:path";
|
|
30238
|
+
|
|
30239
|
+
// src/git/working-directory/changes/count-lines.ts
|
|
30240
|
+
import { createReadStream } from "node:fs";
|
|
30241
|
+
import * as readline2 from "node:readline";
|
|
30242
|
+
async function countTextFileLines(absFile) {
|
|
30243
|
+
let bytes = 0;
|
|
30244
|
+
const maxBytes = 512e3;
|
|
30245
|
+
let lines = 0;
|
|
30246
|
+
const stream = createReadStream(absFile, { encoding: "utf8" });
|
|
30247
|
+
const rl = readline2.createInterface({ input: stream, crlfDelay: Infinity });
|
|
30248
|
+
for await (const _line of rl) {
|
|
30249
|
+
lines += 1;
|
|
30250
|
+
bytes += Buffer.byteLength(String(_line), "utf8") + 1;
|
|
30251
|
+
if (bytes > maxBytes) {
|
|
30252
|
+
rl.close();
|
|
30253
|
+
stream.destroy();
|
|
30254
|
+
return lines;
|
|
30255
|
+
}
|
|
30256
|
+
}
|
|
30257
|
+
return lines;
|
|
30258
|
+
}
|
|
30259
|
+
|
|
30260
|
+
// src/git/working-directory/changes/hydrate-patch.ts
|
|
30261
|
+
import * as fs10 from "node:fs";
|
|
30262
|
+
var UNIFIED_HUNK_HEADER_RE = /^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/;
|
|
30263
|
+
var MAX_HYDRATE_LINES_PER_GAP = 8e3;
|
|
30264
|
+
var MAX_HYDRATE_LINES_PER_FILE = 8e4;
|
|
30265
|
+
async function readGitBlobLines(repoCwd, pathInRepo) {
|
|
30266
|
+
try {
|
|
30267
|
+
const rel = pathInRepo.replace(/\\/g, "/");
|
|
30268
|
+
const raw = await simpleGit(repoCwd).show([`HEAD:${rel}`]);
|
|
30269
|
+
return String(raw).split(/\r?\n/);
|
|
30270
|
+
} catch {
|
|
30271
|
+
return null;
|
|
30272
|
+
}
|
|
30273
|
+
}
|
|
30274
|
+
async function readWorktreeFileLines(abs) {
|
|
30275
|
+
try {
|
|
30276
|
+
const raw = await fs10.promises.readFile(abs, "utf8");
|
|
30277
|
+
return raw.split(/\r?\n/);
|
|
30278
|
+
} catch {
|
|
30279
|
+
return null;
|
|
30280
|
+
}
|
|
30281
|
+
}
|
|
30282
|
+
async function hydrateUnifiedPatchWithFileContext(patch, absFile, repoGitCwd, pathInRepo, change) {
|
|
30283
|
+
if (!patch.trim() || patch.includes("Binary files")) return patch;
|
|
30284
|
+
const all = patch.split("\n");
|
|
30285
|
+
const out = [];
|
|
30286
|
+
let prevOldEnd = 0;
|
|
30287
|
+
let prevNewEnd = 0;
|
|
30288
|
+
let injectedTotal = 0;
|
|
30289
|
+
let i = 0;
|
|
30290
|
+
let blobCache;
|
|
30291
|
+
let diskCache;
|
|
30292
|
+
const blobLines = async () => {
|
|
30293
|
+
if (blobCache !== void 0) return blobCache;
|
|
30294
|
+
blobCache = await readGitBlobLines(repoGitCwd, pathInRepo);
|
|
30295
|
+
return blobCache;
|
|
30296
|
+
};
|
|
30297
|
+
const diskLines = async () => {
|
|
30298
|
+
if (diskCache !== void 0) return diskCache;
|
|
30299
|
+
diskCache = await readWorktreeFileLines(absFile);
|
|
30300
|
+
return diskCache;
|
|
30301
|
+
};
|
|
30302
|
+
while (i < all.length) {
|
|
30303
|
+
const line = all[i];
|
|
30304
|
+
const hm = line.match(UNIFIED_HUNK_HEADER_RE);
|
|
30305
|
+
if (!hm) {
|
|
30306
|
+
out.push(line);
|
|
30307
|
+
i++;
|
|
30308
|
+
continue;
|
|
30309
|
+
}
|
|
30310
|
+
const oldStart = parseInt(hm[1], 10) || 0;
|
|
30311
|
+
const newStart = parseInt(hm[3], 10) || 0;
|
|
30312
|
+
const gapOldStart = prevOldEnd + 1;
|
|
30313
|
+
const gapOldEnd = oldStart - 1;
|
|
30314
|
+
const gapNewStart = prevNewEnd + 1;
|
|
30315
|
+
const gapNewEnd = newStart - 1;
|
|
30316
|
+
if (injectedTotal < MAX_HYDRATE_LINES_PER_FILE) {
|
|
30317
|
+
let inject = null;
|
|
30318
|
+
if (gapNewEnd >= gapNewStart && change !== "removed") {
|
|
30319
|
+
const nNew = gapNewEnd - gapNewStart + 1;
|
|
30320
|
+
if (gapOldEnd < gapOldStart || gapOldEnd - gapOldStart + 1 === nNew) {
|
|
30321
|
+
const cap = Math.min(nNew, MAX_HYDRATE_LINES_PER_GAP, MAX_HYDRATE_LINES_PER_FILE - injectedTotal);
|
|
30322
|
+
const dl = await diskLines();
|
|
30323
|
+
if (dl && cap > 0) {
|
|
30324
|
+
inject = dl.slice(gapNewStart - 1, gapNewStart - 1 + cap);
|
|
30325
|
+
}
|
|
30326
|
+
}
|
|
30327
|
+
} else if (gapOldEnd >= gapOldStart && change === "removed") {
|
|
30328
|
+
const nOld = gapOldEnd - gapOldStart + 1;
|
|
30329
|
+
const cap = Math.min(nOld, MAX_HYDRATE_LINES_PER_GAP, MAX_HYDRATE_LINES_PER_FILE - injectedTotal);
|
|
30330
|
+
const bl = await blobLines();
|
|
30331
|
+
if (bl && cap > 0) {
|
|
30332
|
+
inject = bl.slice(gapOldStart - 1, gapOldStart - 1 + cap);
|
|
30333
|
+
}
|
|
30334
|
+
}
|
|
30335
|
+
if (inject && inject.length > 0) {
|
|
30336
|
+
for (const t of inject) {
|
|
30337
|
+
out.push(` ${t}`);
|
|
30338
|
+
injectedTotal++;
|
|
30339
|
+
}
|
|
30340
|
+
}
|
|
30341
|
+
}
|
|
30342
|
+
out.push(line);
|
|
30343
|
+
i++;
|
|
30344
|
+
let oldConsumed = 0;
|
|
30345
|
+
let newConsumed = 0;
|
|
30346
|
+
while (i < all.length) {
|
|
30347
|
+
const bl = all[i];
|
|
30348
|
+
if (UNIFIED_HUNK_HEADER_RE.test(bl)) break;
|
|
30349
|
+
out.push(bl);
|
|
30350
|
+
i++;
|
|
30351
|
+
if (bl.startsWith("\\")) continue;
|
|
30352
|
+
const ch = bl[0];
|
|
30353
|
+
if (ch === " ") {
|
|
30354
|
+
oldConsumed++;
|
|
30355
|
+
newConsumed++;
|
|
30356
|
+
} else if (ch === "-") {
|
|
30357
|
+
oldConsumed++;
|
|
30358
|
+
} else if (ch === "+") {
|
|
30359
|
+
newConsumed++;
|
|
30360
|
+
}
|
|
30361
|
+
}
|
|
30362
|
+
if (oldStart > 0) {
|
|
30363
|
+
prevOldEnd = oldStart + oldConsumed - 1;
|
|
30364
|
+
} else {
|
|
30365
|
+
prevOldEnd = 0;
|
|
30366
|
+
}
|
|
30367
|
+
if (newStart > 0) {
|
|
30368
|
+
prevNewEnd = newStart + newConsumed - 1;
|
|
30369
|
+
} else {
|
|
30370
|
+
prevNewEnd = 0;
|
|
30371
|
+
}
|
|
30372
|
+
}
|
|
30373
|
+
return truncatePatch(out.join("\n"));
|
|
30374
|
+
}
|
|
30375
|
+
|
|
30376
|
+
// src/git/working-directory/changes/unified-diff-for-file.ts
|
|
30377
|
+
async function unifiedDiffForFile(repoCwd, pathInRepo, change) {
|
|
30378
|
+
const g = simpleGit(repoCwd);
|
|
30379
|
+
try {
|
|
30380
|
+
let raw;
|
|
30381
|
+
if (change === "added") {
|
|
30382
|
+
const devNull = process.platform === "win32" ? "NUL" : "/dev/null";
|
|
30383
|
+
raw = await g.raw(["diff", "--no-index", "--", devNull, pathInRepo]);
|
|
30384
|
+
} else {
|
|
30385
|
+
raw = await g.raw(["diff", "HEAD", "--", pathInRepo]);
|
|
30386
|
+
}
|
|
30387
|
+
const t = String(raw).trim();
|
|
30388
|
+
if (!t) return void 0;
|
|
30389
|
+
return truncatePatch(t);
|
|
30390
|
+
} catch {
|
|
30391
|
+
return void 0;
|
|
30392
|
+
}
|
|
30393
|
+
}
|
|
30394
|
+
|
|
30395
|
+
// src/git/working-directory/changes/list-changed-files-for-repo.ts
|
|
30396
|
+
async function listChangedFilesForRepo(repoGitCwd, repoRelPath) {
|
|
30397
|
+
const g = simpleGit(repoGitCwd);
|
|
30398
|
+
const [nameStatusRaw, numstatRaw, untrackedRaw] = await Promise.all([
|
|
30399
|
+
g.raw(["diff", "--name-status", "HEAD"]).catch(() => ""),
|
|
30400
|
+
g.raw(["diff", "HEAD", "--numstat"]).catch(() => ""),
|
|
30401
|
+
g.raw(["ls-files", "--others", "--exclude-standard"]).catch(() => "")
|
|
30402
|
+
]);
|
|
30403
|
+
const kindByPath = parseNameStatusLines(String(nameStatusRaw).split("\n"));
|
|
30404
|
+
const numByPath = parseNumstat(String(numstatRaw).split("\n"));
|
|
30405
|
+
const paths = /* @__PURE__ */ new Set([...kindByPath.keys(), ...numByPath.keys()]);
|
|
30406
|
+
const untracked = String(untrackedRaw).split("\n").map((s) => s.trim()).filter(Boolean);
|
|
30407
|
+
for (const p of untracked) paths.add(p);
|
|
30408
|
+
const rows = [];
|
|
30409
|
+
for (const pathInRepo of paths) {
|
|
30410
|
+
const relLauncher = posixJoinDirFile(repoRelPath, pathInRepo.replace(/\\/g, "/"));
|
|
30411
|
+
const abs = path13.join(repoGitCwd, pathInRepo);
|
|
30412
|
+
const nums = numByPath.get(pathInRepo);
|
|
30413
|
+
let additions = nums?.additions ?? 0;
|
|
30414
|
+
let deletions = nums?.deletions ?? 0;
|
|
30415
|
+
let change = kindByPath.get(pathInRepo) ?? "modified";
|
|
30416
|
+
if (untracked.includes(pathInRepo) && !kindByPath.has(pathInRepo)) {
|
|
30417
|
+
change = "added";
|
|
30418
|
+
const fromGit = await numstatFromGitNoIndex(g, pathInRepo);
|
|
30419
|
+
if (fromGit) {
|
|
30420
|
+
additions = fromGit.additions;
|
|
30421
|
+
deletions = fromGit.deletions;
|
|
30422
|
+
} else {
|
|
30423
|
+
try {
|
|
30424
|
+
const st = await fs11.promises.stat(abs);
|
|
30425
|
+
if (st.isFile()) additions = await countTextFileLines(abs);
|
|
30426
|
+
else additions = 0;
|
|
30427
|
+
} catch {
|
|
30428
|
+
additions = 0;
|
|
30429
|
+
}
|
|
30430
|
+
deletions = 0;
|
|
30431
|
+
}
|
|
30432
|
+
}
|
|
30433
|
+
if (!kindByPath.has(pathInRepo) && nums) {
|
|
30434
|
+
if (additions > 0 && deletions === 0) change = "added";
|
|
30435
|
+
else if (deletions > 0 && additions === 0) change = "removed";
|
|
30436
|
+
else change = "modified";
|
|
30437
|
+
}
|
|
30438
|
+
rows.push({ pathRelLauncher: relLauncher, additions, deletions, change });
|
|
30439
|
+
}
|
|
30440
|
+
const normRel = repoRelPath === "." || repoRelPath === "" ? "." : repoRelPath;
|
|
30441
|
+
for (const row of rows) {
|
|
30442
|
+
let pathInRepo;
|
|
30443
|
+
if (normRel === ".") {
|
|
30444
|
+
pathInRepo = row.pathRelLauncher;
|
|
30445
|
+
} else if (row.pathRelLauncher.startsWith(`${normRel}/`)) {
|
|
30446
|
+
pathInRepo = row.pathRelLauncher.slice(normRel.length + 1);
|
|
30447
|
+
} else {
|
|
30448
|
+
pathInRepo = row.pathRelLauncher;
|
|
30449
|
+
}
|
|
30450
|
+
const absFile = path13.join(repoGitCwd, pathInRepo);
|
|
30451
|
+
let patch = await unifiedDiffForFile(repoGitCwd, pathInRepo, row.change);
|
|
30452
|
+
if (patch) {
|
|
30453
|
+
patch = await hydrateUnifiedPatchWithFileContext(patch, absFile, repoGitCwd, pathInRepo, row.change);
|
|
30454
|
+
}
|
|
30455
|
+
row.patchContent = patch;
|
|
30456
|
+
}
|
|
30457
|
+
return rows;
|
|
30458
|
+
}
|
|
30459
|
+
|
|
30460
|
+
// src/git/working-directory/changes/get-working-tree-change-repo-details.ts
|
|
30461
|
+
function normRepoRel(p) {
|
|
30462
|
+
const x = p.replace(/\\/g, "/").trim();
|
|
30463
|
+
return x === "" ? "." : x;
|
|
30464
|
+
}
|
|
30465
|
+
async function getWorkingTreeChangeRepoDetails(options) {
|
|
30466
|
+
const launcher = path14.resolve(getBridgeWorkspaceDirectory());
|
|
30467
|
+
const mirror = options.agentMirrorRootAbs ? path14.resolve(options.agentMirrorRootAbs) : null;
|
|
30468
|
+
const out = [];
|
|
30469
|
+
const filter = options.repoFilterRelPath != null ? normRepoRel(options.repoFilterRelPath) : null;
|
|
30470
|
+
const basisInput = options.basis ?? { kind: "working" };
|
|
30471
|
+
if (basisInput.kind === "commit" && !filter) {
|
|
30472
|
+
throw new Error("repoFilterRelPath is required for commit changes");
|
|
30473
|
+
}
|
|
30474
|
+
if (basisInput.kind === "commit" && !basisInput.sha.trim()) {
|
|
30475
|
+
throw new Error("commit sha is required for commit changes");
|
|
30476
|
+
}
|
|
30477
|
+
const basis = filter == null && basisInput.kind === "commit" ? { kind: "working" } : basisInput;
|
|
30478
|
+
for (const target of options.commitTargetAbsDirs) {
|
|
30479
|
+
const t = path14.resolve(target);
|
|
30480
|
+
if (!await isGitRepoDirectory(t)) continue;
|
|
30481
|
+
const g = simpleGit(t);
|
|
30482
|
+
let branch = "HEAD";
|
|
30483
|
+
try {
|
|
30484
|
+
branch = (await g.raw(["rev-parse", "--abbrev-ref", "HEAD"])).trim() || "HEAD";
|
|
30485
|
+
} catch {
|
|
30486
|
+
branch = "HEAD";
|
|
30487
|
+
}
|
|
30488
|
+
const remoteUrl = await getRemoteOriginUrl(t);
|
|
30489
|
+
const remoteDisplay = formatRemoteDisplayLabel(remoteUrl);
|
|
30490
|
+
let repoRelPath;
|
|
30491
|
+
if (mirror) {
|
|
30492
|
+
const relNorm = path14.relative(mirror, path14.dirname(t));
|
|
30493
|
+
repoRelPath = relNorm === "" ? "." : relNorm.replace(/\\/g, "/");
|
|
30494
|
+
} else {
|
|
30495
|
+
let top = t;
|
|
30496
|
+
try {
|
|
30497
|
+
top = (await g.raw(["rev-parse", "--show-toplevel"])).trim();
|
|
30498
|
+
} catch {
|
|
30499
|
+
top = t;
|
|
30500
|
+
}
|
|
30501
|
+
const rel = path14.relative(launcher, path14.resolve(top)).replace(/\\/g, "/") || ".";
|
|
30502
|
+
repoRelPath = rel.startsWith("..") ? path14.basename(path14.resolve(top)) : rel;
|
|
30503
|
+
}
|
|
30504
|
+
const norm = normRepoRel(repoRelPath === "" ? "." : repoRelPath);
|
|
30505
|
+
if (filter && norm !== filter) continue;
|
|
30506
|
+
const repoDisplayName = formatRepoShortTitle(remoteUrl, norm === "." ? "." : norm);
|
|
30507
|
+
const relForList = norm === "." ? "." : norm;
|
|
30508
|
+
const files = basis.kind === "commit" ? await listChangedFilesForCommit(t, relForList, basis.sha.trim()) : await listChangedFilesForRepo(t, relForList);
|
|
30509
|
+
const st = await g.status();
|
|
30510
|
+
const hasUncommittedChanges = (st.files?.length ?? 0) > 0;
|
|
30511
|
+
const unpushedCommits = await listUnpushedCommits(t);
|
|
30512
|
+
out.push({
|
|
30513
|
+
repoRelPath: norm,
|
|
30514
|
+
repoDisplayName,
|
|
30515
|
+
branch,
|
|
30516
|
+
remoteUrl,
|
|
30517
|
+
remoteDisplay,
|
|
30518
|
+
files,
|
|
30519
|
+
hasUncommittedChanges,
|
|
30520
|
+
unpushedCommits,
|
|
30521
|
+
changesView: basis.kind === "commit" ? "commit" : "working",
|
|
30522
|
+
changesCommitSha: basis.kind === "commit" ? basis.sha.trim() : null
|
|
30523
|
+
});
|
|
30524
|
+
if (filter) return out;
|
|
30525
|
+
}
|
|
30526
|
+
return out;
|
|
30527
|
+
}
|
|
30528
|
+
|
|
29964
30529
|
// src/git/commit-and-push.ts
|
|
29965
30530
|
async function gitCommitAllIfDirty(repoDir, message, options) {
|
|
29966
30531
|
const g = simpleGit(repoDir);
|
|
@@ -30026,7 +30591,7 @@ var SessionWorktreeManager = class {
|
|
|
30026
30591
|
}
|
|
30027
30592
|
if (!opts.isNewSession) {
|
|
30028
30593
|
const agentCwd = this.sessionAgentCwd.get(sessionId);
|
|
30029
|
-
if (agentCwd) return
|
|
30594
|
+
if (agentCwd) return path15.resolve(agentCwd);
|
|
30030
30595
|
return void 0;
|
|
30031
30596
|
}
|
|
30032
30597
|
const prep = await prepareNewSessionWorktrees({
|
|
@@ -30039,7 +30604,7 @@ var SessionWorktreeManager = class {
|
|
|
30039
30604
|
if (!prep) return void 0;
|
|
30040
30605
|
this.sessionPaths.set(sessionId, prep.worktreePaths);
|
|
30041
30606
|
this.sessionAgentCwd.set(sessionId, prep.agentCwd);
|
|
30042
|
-
return
|
|
30607
|
+
return path15.resolve(prep.agentCwd);
|
|
30043
30608
|
}
|
|
30044
30609
|
async renameSessionBranch(sessionId, newBranch) {
|
|
30045
30610
|
const paths = this.sessionPaths.get(sessionId);
|
|
@@ -30060,7 +30625,7 @@ var SessionWorktreeManager = class {
|
|
|
30060
30625
|
getAgentCwdForSession(sessionId) {
|
|
30061
30626
|
if (!sessionId) return null;
|
|
30062
30627
|
const c = this.sessionAgentCwd.get(sessionId);
|
|
30063
|
-
return c ?
|
|
30628
|
+
return c ? path15.resolve(c) : null;
|
|
30064
30629
|
}
|
|
30065
30630
|
async removeSessionWorktrees(sessionId) {
|
|
30066
30631
|
const paths = this.sessionPaths.get(sessionId);
|
|
@@ -30086,6 +30651,17 @@ var SessionWorktreeManager = class {
|
|
|
30086
30651
|
async getSessionWorkingTreeStatus(sessionId) {
|
|
30087
30652
|
return aggregateSessionPathsWorkingTreeStatus(this.resolveCommitTargets(sessionId));
|
|
30088
30653
|
}
|
|
30654
|
+
/** Per-repo changed files vs HEAD (or a single commit vs parent) for the same git roots used for commit/push. */
|
|
30655
|
+
async getSessionWorkingTreeChangeDetails(sessionId, opts) {
|
|
30656
|
+
const targets = this.resolveCommitTargets(sessionId);
|
|
30657
|
+
const mirror = this.getAgentCwdForSession(sessionId);
|
|
30658
|
+
return getWorkingTreeChangeRepoDetails({
|
|
30659
|
+
commitTargetAbsDirs: targets,
|
|
30660
|
+
agentMirrorRootAbs: mirror,
|
|
30661
|
+
repoFilterRelPath: opts?.repoRelPath?.trim() ? opts.repoRelPath.trim() : null,
|
|
30662
|
+
basis: opts?.basis
|
|
30663
|
+
});
|
|
30664
|
+
}
|
|
30089
30665
|
async pushSessionUpstream(sessionId) {
|
|
30090
30666
|
try {
|
|
30091
30667
|
await pushAheadOfUpstreamForPaths(this.resolveCommitTargets(sessionId));
|
|
@@ -30097,30 +30673,30 @@ var SessionWorktreeManager = class {
|
|
|
30097
30673
|
}
|
|
30098
30674
|
};
|
|
30099
30675
|
function defaultWorktreesRootAbs() {
|
|
30100
|
-
return
|
|
30676
|
+
return path15.join(os3.homedir(), ".buildautomaton", "worktrees");
|
|
30101
30677
|
}
|
|
30102
30678
|
|
|
30103
30679
|
// src/files/watch-file-index.ts
|
|
30104
30680
|
import { watch } from "node:fs";
|
|
30105
|
-
import
|
|
30681
|
+
import path22 from "node:path";
|
|
30106
30682
|
|
|
30107
30683
|
// src/files/index/build-file-index.ts
|
|
30108
|
-
import
|
|
30684
|
+
import path19 from "node:path";
|
|
30109
30685
|
|
|
30110
30686
|
// src/runtime/yield-to-event-loop.ts
|
|
30111
30687
|
function yieldToEventLoop() {
|
|
30112
|
-
return new Promise((
|
|
30688
|
+
return new Promise((resolve15) => setImmediate(resolve15));
|
|
30113
30689
|
}
|
|
30114
30690
|
|
|
30115
30691
|
// src/files/index/walk-workspace-tree.ts
|
|
30116
|
-
import
|
|
30117
|
-
import
|
|
30692
|
+
import fs12 from "node:fs";
|
|
30693
|
+
import path17 from "node:path";
|
|
30118
30694
|
|
|
30119
30695
|
// src/files/index/constants.ts
|
|
30120
|
-
import
|
|
30696
|
+
import path16 from "node:path";
|
|
30121
30697
|
import os4 from "node:os";
|
|
30122
30698
|
var INDEX_WORK_YIELD_EVERY = 256;
|
|
30123
|
-
var INDEX_DIR =
|
|
30699
|
+
var INDEX_DIR = path16.join(os4.homedir(), ".buildautomaton");
|
|
30124
30700
|
var INDEX_HASH_LEN = 16;
|
|
30125
30701
|
var INDEX_VERSION = 2;
|
|
30126
30702
|
var INDEX_LOG_PREFIX = "[file-index]";
|
|
@@ -30129,31 +30705,31 @@ var INDEX_LOG_PREFIX = "[file-index]";
|
|
|
30129
30705
|
function walkWorkspaceTreeSync(dir, baseDir, out) {
|
|
30130
30706
|
let names;
|
|
30131
30707
|
try {
|
|
30132
|
-
names =
|
|
30708
|
+
names = fs12.readdirSync(dir);
|
|
30133
30709
|
} catch {
|
|
30134
30710
|
return;
|
|
30135
30711
|
}
|
|
30136
30712
|
for (const name of names) {
|
|
30137
30713
|
if (name.startsWith(".")) continue;
|
|
30138
|
-
const full =
|
|
30714
|
+
const full = path17.join(dir, name);
|
|
30139
30715
|
let stat2;
|
|
30140
30716
|
try {
|
|
30141
|
-
stat2 =
|
|
30717
|
+
stat2 = fs12.statSync(full);
|
|
30142
30718
|
} catch {
|
|
30143
30719
|
continue;
|
|
30144
30720
|
}
|
|
30145
|
-
const
|
|
30721
|
+
const relative5 = path17.relative(baseDir, full).replace(/\\/g, "/");
|
|
30146
30722
|
if (stat2.isDirectory()) {
|
|
30147
30723
|
walkWorkspaceTreeSync(full, baseDir, out);
|
|
30148
30724
|
} else if (stat2.isFile()) {
|
|
30149
|
-
out.push(
|
|
30725
|
+
out.push(relative5);
|
|
30150
30726
|
}
|
|
30151
30727
|
}
|
|
30152
30728
|
}
|
|
30153
30729
|
async function walkWorkspaceTreeAsync(dir, baseDir, out, state) {
|
|
30154
30730
|
let names;
|
|
30155
30731
|
try {
|
|
30156
|
-
names = await
|
|
30732
|
+
names = await fs12.promises.readdir(dir);
|
|
30157
30733
|
} catch {
|
|
30158
30734
|
return;
|
|
30159
30735
|
}
|
|
@@ -30163,18 +30739,18 @@ async function walkWorkspaceTreeAsync(dir, baseDir, out, state) {
|
|
|
30163
30739
|
await yieldToEventLoop();
|
|
30164
30740
|
}
|
|
30165
30741
|
state.n++;
|
|
30166
|
-
const full =
|
|
30742
|
+
const full = path17.join(dir, name);
|
|
30167
30743
|
let stat2;
|
|
30168
30744
|
try {
|
|
30169
|
-
stat2 = await
|
|
30745
|
+
stat2 = await fs12.promises.stat(full);
|
|
30170
30746
|
} catch {
|
|
30171
30747
|
continue;
|
|
30172
30748
|
}
|
|
30173
|
-
const
|
|
30749
|
+
const relative5 = path17.relative(baseDir, full).replace(/\\/g, "/");
|
|
30174
30750
|
if (stat2.isDirectory()) {
|
|
30175
30751
|
await walkWorkspaceTreeAsync(full, baseDir, out, state);
|
|
30176
30752
|
} else if (stat2.isFile()) {
|
|
30177
|
-
out.push(
|
|
30753
|
+
out.push(relative5);
|
|
30178
30754
|
}
|
|
30179
30755
|
}
|
|
30180
30756
|
}
|
|
@@ -30251,22 +30827,22 @@ async function buildTrigramMapForPathsAsync(paths) {
|
|
|
30251
30827
|
}
|
|
30252
30828
|
|
|
30253
30829
|
// src/files/index/write-index-file.ts
|
|
30254
|
-
import
|
|
30830
|
+
import fs13 from "node:fs";
|
|
30255
30831
|
|
|
30256
30832
|
// src/files/index/paths.ts
|
|
30257
|
-
import
|
|
30833
|
+
import path18 from "node:path";
|
|
30258
30834
|
import crypto2 from "node:crypto";
|
|
30259
30835
|
function getIndexPathForCwd(resolvedCwd) {
|
|
30260
30836
|
const hash = crypto2.createHash("sha256").update(resolvedCwd).digest("hex").slice(0, INDEX_HASH_LEN);
|
|
30261
|
-
return
|
|
30837
|
+
return path18.join(INDEX_DIR, `.file-index-${hash}.json`);
|
|
30262
30838
|
}
|
|
30263
30839
|
|
|
30264
30840
|
// src/files/index/write-index-file.ts
|
|
30265
30841
|
function writeIndexFileSync(resolvedCwd, data) {
|
|
30266
30842
|
const indexPath = getIndexPathForCwd(resolvedCwd);
|
|
30267
30843
|
try {
|
|
30268
|
-
if (!
|
|
30269
|
-
|
|
30844
|
+
if (!fs13.existsSync(INDEX_DIR)) fs13.mkdirSync(INDEX_DIR, { recursive: true });
|
|
30845
|
+
fs13.writeFileSync(indexPath, JSON.stringify(data), "utf8");
|
|
30270
30846
|
} catch (e) {
|
|
30271
30847
|
console.error(`${INDEX_LOG_PREFIX} Failed to write index:`, e);
|
|
30272
30848
|
}
|
|
@@ -30274,8 +30850,8 @@ function writeIndexFileSync(resolvedCwd, data) {
|
|
|
30274
30850
|
async function writeIndexFileAsync(resolvedCwd, data) {
|
|
30275
30851
|
const indexPath = getIndexPathForCwd(resolvedCwd);
|
|
30276
30852
|
try {
|
|
30277
|
-
await
|
|
30278
|
-
await
|
|
30853
|
+
await fs13.promises.mkdir(INDEX_DIR, { recursive: true });
|
|
30854
|
+
await fs13.promises.writeFile(indexPath, JSON.stringify(data), "utf8");
|
|
30279
30855
|
} catch (e) {
|
|
30280
30856
|
console.error(`${INDEX_LOG_PREFIX} Failed to write index:`, e);
|
|
30281
30857
|
}
|
|
@@ -30289,7 +30865,7 @@ function sortPaths(paths) {
|
|
|
30289
30865
|
paths.sort((a, b) => a.localeCompare(b, void 0, { sensitivity: "base" }));
|
|
30290
30866
|
}
|
|
30291
30867
|
function buildFileIndex(cwd) {
|
|
30292
|
-
const resolved =
|
|
30868
|
+
const resolved = path19.resolve(cwd);
|
|
30293
30869
|
const paths = [];
|
|
30294
30870
|
walkWorkspaceTreeSync(resolved, resolved, paths);
|
|
30295
30871
|
sortPaths(paths);
|
|
@@ -30299,7 +30875,7 @@ function buildFileIndex(cwd) {
|
|
|
30299
30875
|
return data;
|
|
30300
30876
|
}
|
|
30301
30877
|
async function buildFileIndexAsync(cwd) {
|
|
30302
|
-
const resolved =
|
|
30878
|
+
const resolved = path19.resolve(cwd);
|
|
30303
30879
|
const paths = [];
|
|
30304
30880
|
await walkWorkspaceTreeAsync(resolved, resolved, paths, createWalkYieldState());
|
|
30305
30881
|
await yieldToEventLoop();
|
|
@@ -30311,13 +30887,13 @@ async function buildFileIndexAsync(cwd) {
|
|
|
30311
30887
|
}
|
|
30312
30888
|
|
|
30313
30889
|
// src/files/index/load-file-index.ts
|
|
30314
|
-
import
|
|
30315
|
-
import
|
|
30890
|
+
import fs14 from "node:fs";
|
|
30891
|
+
import path20 from "node:path";
|
|
30316
30892
|
function loadFileIndex(cwd) {
|
|
30317
|
-
const resolved =
|
|
30893
|
+
const resolved = path20.resolve(cwd);
|
|
30318
30894
|
const indexPath = getIndexPathForCwd(resolved);
|
|
30319
30895
|
try {
|
|
30320
|
-
const raw =
|
|
30896
|
+
const raw = fs14.readFileSync(indexPath, "utf8");
|
|
30321
30897
|
const parsed = JSON.parse(raw);
|
|
30322
30898
|
if (parsed !== null && typeof parsed === "object" && Array.isArray(parsed.paths)) {
|
|
30323
30899
|
const obj = parsed;
|
|
@@ -30336,9 +30912,9 @@ function loadFileIndex(cwd) {
|
|
|
30336
30912
|
}
|
|
30337
30913
|
|
|
30338
30914
|
// src/files/index/ensure-file-index.ts
|
|
30339
|
-
import
|
|
30915
|
+
import path21 from "node:path";
|
|
30340
30916
|
async function ensureFileIndexAsync(cwd) {
|
|
30341
|
-
const resolved =
|
|
30917
|
+
const resolved = path21.resolve(cwd);
|
|
30342
30918
|
const cached2 = loadFileIndex(resolved);
|
|
30343
30919
|
if (cached2 !== null) return { data: cached2, fromCache: true };
|
|
30344
30920
|
const data = await buildFileIndexAsync(resolved);
|
|
@@ -30421,7 +30997,7 @@ function createFsWatcher(resolved, schedule) {
|
|
|
30421
30997
|
}
|
|
30422
30998
|
}
|
|
30423
30999
|
function startFileIndexWatcher(cwd = getBridgeWorkspaceDirectory()) {
|
|
30424
|
-
const resolved =
|
|
31000
|
+
const resolved = path22.resolve(cwd);
|
|
30425
31001
|
void buildFileIndexAsync(resolved).catch((e) => {
|
|
30426
31002
|
console.error("[file-index] Initial index build failed:", e);
|
|
30427
31003
|
});
|
|
@@ -30468,15 +31044,15 @@ function sendDevServerStatus(getWs, serverId, status, options) {
|
|
|
30468
31044
|
|
|
30469
31045
|
// src/dev-servers/process/terminate-child-process.ts
|
|
30470
31046
|
async function sigtermAndWaitForExit(proc, graceMs, log2, shortId) {
|
|
30471
|
-
const exited = new Promise((
|
|
30472
|
-
proc.once("exit", () =>
|
|
31047
|
+
const exited = new Promise((resolve15) => {
|
|
31048
|
+
proc.once("exit", () => resolve15());
|
|
30473
31049
|
});
|
|
30474
31050
|
log2(`[dev-server] Sending SIGTERM to ${shortId} (pid=${proc.pid ?? "?"}).`);
|
|
30475
31051
|
try {
|
|
30476
31052
|
proc.kill("SIGTERM");
|
|
30477
31053
|
} catch {
|
|
30478
31054
|
}
|
|
30479
|
-
await Promise.race([exited, new Promise((
|
|
31055
|
+
await Promise.race([exited, new Promise((resolve15) => setTimeout(resolve15, graceMs))]);
|
|
30480
31056
|
}
|
|
30481
31057
|
function forceKillChild(proc, log2, shortId, graceMs) {
|
|
30482
31058
|
log2(
|
|
@@ -30490,7 +31066,7 @@ function forceKillChild(proc, log2, shortId, graceMs) {
|
|
|
30490
31066
|
}
|
|
30491
31067
|
|
|
30492
31068
|
// src/dev-servers/process/wire-dev-server-child-process.ts
|
|
30493
|
-
import
|
|
31069
|
+
import fs15 from "node:fs";
|
|
30494
31070
|
|
|
30495
31071
|
// src/dev-servers/manager/forward-pipe.ts
|
|
30496
31072
|
function forwardChildPipe(childReadable, terminal, onData) {
|
|
@@ -30526,7 +31102,7 @@ function wireDevServerChildProcess(d) {
|
|
|
30526
31102
|
d.setPollInterval(void 0);
|
|
30527
31103
|
return;
|
|
30528
31104
|
}
|
|
30529
|
-
|
|
31105
|
+
fs15.readFile(d.mergedLogPath, (err, buf) => {
|
|
30530
31106
|
if (err || (d.getSpawnGeneration() ?? 0) !== d.scheduledGen) return;
|
|
30531
31107
|
if (buf.length <= d.mergedReadPos.value) return;
|
|
30532
31108
|
const chunk = Buffer.from(buf.subarray(d.mergedReadPos.value));
|
|
@@ -30564,7 +31140,7 @@ ${errTail}` : ""}`);
|
|
|
30564
31140
|
d.sendStatus(code === 0 || code == null ? "stopped" : "error", detail, tails);
|
|
30565
31141
|
};
|
|
30566
31142
|
if (mergedPath) {
|
|
30567
|
-
|
|
31143
|
+
fs15.readFile(mergedPath, (err, buf) => {
|
|
30568
31144
|
if (!err && buf.length > d.mergedReadPos.value) {
|
|
30569
31145
|
const chunk = Buffer.from(buf.subarray(d.mergedReadPos.value));
|
|
30570
31146
|
if (chunk.length > 0) {
|
|
@@ -30666,13 +31242,13 @@ function parseDevServerDefs(servers) {
|
|
|
30666
31242
|
}
|
|
30667
31243
|
|
|
30668
31244
|
// src/dev-servers/manager/shell-spawn/utils.ts
|
|
30669
|
-
import
|
|
31245
|
+
import fs16 from "node:fs";
|
|
30670
31246
|
function isSpawnEbadf(e) {
|
|
30671
31247
|
return typeof e === "object" && e !== null && "code" in e && e.code === "EBADF";
|
|
30672
31248
|
}
|
|
30673
31249
|
function rmDirQuiet(dir) {
|
|
30674
31250
|
try {
|
|
30675
|
-
|
|
31251
|
+
fs16.rmSync(dir, { recursive: true, force: true });
|
|
30676
31252
|
} catch {
|
|
30677
31253
|
}
|
|
30678
31254
|
}
|
|
@@ -30680,7 +31256,7 @@ var cachedDevNullReadFd;
|
|
|
30680
31256
|
function devNullReadFd() {
|
|
30681
31257
|
if (cachedDevNullReadFd === void 0) {
|
|
30682
31258
|
const devPath = process.platform === "win32" ? "nul" : "/dev/null";
|
|
30683
|
-
cachedDevNullReadFd =
|
|
31259
|
+
cachedDevNullReadFd = fs16.openSync(devPath, "r");
|
|
30684
31260
|
}
|
|
30685
31261
|
return cachedDevNullReadFd;
|
|
30686
31262
|
}
|
|
@@ -30754,15 +31330,15 @@ function trySpawnShellTruePiped(command, env, cwd, devNullFd, signal) {
|
|
|
30754
31330
|
|
|
30755
31331
|
// src/dev-servers/manager/shell-spawn/try-spawn-merged-log-file.ts
|
|
30756
31332
|
import { spawn as spawn7 } from "node:child_process";
|
|
30757
|
-
import
|
|
31333
|
+
import fs17 from "node:fs";
|
|
30758
31334
|
import { tmpdir } from "node:os";
|
|
30759
|
-
import
|
|
31335
|
+
import path23 from "node:path";
|
|
30760
31336
|
function trySpawnMergedLogFile(command, env, cwd, signal) {
|
|
30761
|
-
const tmpRoot =
|
|
30762
|
-
const logPath =
|
|
31337
|
+
const tmpRoot = fs17.mkdtempSync(path23.join(tmpdir(), "ba-devsrv-log-"));
|
|
31338
|
+
const logPath = path23.join(tmpRoot, "combined.log");
|
|
30763
31339
|
let logFd;
|
|
30764
31340
|
try {
|
|
30765
|
-
logFd =
|
|
31341
|
+
logFd = fs17.openSync(logPath, "a");
|
|
30766
31342
|
} catch {
|
|
30767
31343
|
rmDirQuiet(tmpRoot);
|
|
30768
31344
|
return null;
|
|
@@ -30781,7 +31357,7 @@ function trySpawnMergedLogFile(command, env, cwd, signal) {
|
|
|
30781
31357
|
} else {
|
|
30782
31358
|
proc = spawn7("/bin/sh", ["-c", command], { env, cwd, stdio, ...signal ? { signal } : {} });
|
|
30783
31359
|
}
|
|
30784
|
-
|
|
31360
|
+
fs17.closeSync(logFd);
|
|
30785
31361
|
return {
|
|
30786
31362
|
proc,
|
|
30787
31363
|
pipedStdoutStderr: true,
|
|
@@ -30790,7 +31366,7 @@ function trySpawnMergedLogFile(command, env, cwd, signal) {
|
|
|
30790
31366
|
};
|
|
30791
31367
|
} catch (e) {
|
|
30792
31368
|
try {
|
|
30793
|
-
|
|
31369
|
+
fs17.closeSync(logFd);
|
|
30794
31370
|
} catch {
|
|
30795
31371
|
}
|
|
30796
31372
|
rmDirQuiet(tmpRoot);
|
|
@@ -30801,22 +31377,22 @@ function trySpawnMergedLogFile(command, env, cwd, signal) {
|
|
|
30801
31377
|
|
|
30802
31378
|
// src/dev-servers/manager/shell-spawn/try-spawn-shell-script-log-redirect.ts
|
|
30803
31379
|
import { spawn as spawn8 } from "node:child_process";
|
|
30804
|
-
import
|
|
31380
|
+
import fs18 from "node:fs";
|
|
30805
31381
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
30806
|
-
import
|
|
31382
|
+
import path24 from "node:path";
|
|
30807
31383
|
function shSingleQuote(s) {
|
|
30808
31384
|
return `'${s.replace(/'/g, `'\\''`)}'`;
|
|
30809
31385
|
}
|
|
30810
31386
|
function trySpawnShellScriptLogRedirectUnix(command, env, cwd, signal) {
|
|
30811
|
-
const tmpRoot =
|
|
30812
|
-
const logPath =
|
|
30813
|
-
const innerPath =
|
|
30814
|
-
const runnerPath =
|
|
31387
|
+
const tmpRoot = fs18.mkdtempSync(path24.join(tmpdir2(), "ba-devsrv-sh-"));
|
|
31388
|
+
const logPath = path24.join(tmpRoot, "combined.log");
|
|
31389
|
+
const innerPath = path24.join(tmpRoot, "_cmd.sh");
|
|
31390
|
+
const runnerPath = path24.join(tmpRoot, "_run.sh");
|
|
30815
31391
|
try {
|
|
30816
|
-
|
|
31392
|
+
fs18.writeFileSync(innerPath, `#!/bin/sh
|
|
30817
31393
|
${command}
|
|
30818
31394
|
`);
|
|
30819
|
-
|
|
31395
|
+
fs18.writeFileSync(
|
|
30820
31396
|
runnerPath,
|
|
30821
31397
|
`#!/bin/sh
|
|
30822
31398
|
cd ${shSingleQuote(cwd)}
|
|
@@ -30842,13 +31418,13 @@ cd ${shSingleQuote(cwd)}
|
|
|
30842
31418
|
}
|
|
30843
31419
|
}
|
|
30844
31420
|
function trySpawnShellScriptLogRedirectWin(command, env, cwd, signal) {
|
|
30845
|
-
const tmpRoot =
|
|
30846
|
-
const logPath =
|
|
30847
|
-
const runnerPath =
|
|
31421
|
+
const tmpRoot = fs18.mkdtempSync(path24.join(tmpdir2(), "ba-devsrv-sh-"));
|
|
31422
|
+
const logPath = path24.join(tmpRoot, "combined.log");
|
|
31423
|
+
const runnerPath = path24.join(tmpRoot, "_run.bat");
|
|
30848
31424
|
const q = (p) => `"${p.replace(/"/g, '""')}"`;
|
|
30849
31425
|
const com = process.env.ComSpec || "cmd.exe";
|
|
30850
31426
|
try {
|
|
30851
|
-
|
|
31427
|
+
fs18.writeFileSync(
|
|
30852
31428
|
runnerPath,
|
|
30853
31429
|
`@ECHO OFF\r
|
|
30854
31430
|
CD /D ${q(cwd)}\r
|
|
@@ -31530,30 +32106,30 @@ function createOnBridgeIdentified(opts) {
|
|
|
31530
32106
|
}
|
|
31531
32107
|
|
|
31532
32108
|
// src/skills/discover-local-agent-skills.ts
|
|
31533
|
-
import
|
|
31534
|
-
import
|
|
32109
|
+
import fs19 from "node:fs";
|
|
32110
|
+
import path25 from "node:path";
|
|
31535
32111
|
var SKILL_DISCOVERY_ROOTS = [".agents/skills", ".claude/skills", ".cursor/skills", "skills"];
|
|
31536
32112
|
function discoverLocalSkills(cwd) {
|
|
31537
32113
|
const out = [];
|
|
31538
32114
|
const seenKeys = /* @__PURE__ */ new Set();
|
|
31539
32115
|
for (const rel of SKILL_DISCOVERY_ROOTS) {
|
|
31540
|
-
const base =
|
|
31541
|
-
if (!
|
|
32116
|
+
const base = path25.join(cwd, rel);
|
|
32117
|
+
if (!fs19.existsSync(base) || !fs19.statSync(base).isDirectory()) continue;
|
|
31542
32118
|
let entries = [];
|
|
31543
32119
|
try {
|
|
31544
|
-
entries =
|
|
32120
|
+
entries = fs19.readdirSync(base);
|
|
31545
32121
|
} catch {
|
|
31546
32122
|
continue;
|
|
31547
32123
|
}
|
|
31548
32124
|
for (const name of entries) {
|
|
31549
|
-
const dir =
|
|
32125
|
+
const dir = path25.join(base, name);
|
|
31550
32126
|
try {
|
|
31551
|
-
if (!
|
|
32127
|
+
if (!fs19.statSync(dir).isDirectory()) continue;
|
|
31552
32128
|
} catch {
|
|
31553
32129
|
continue;
|
|
31554
32130
|
}
|
|
31555
|
-
const skillMd =
|
|
31556
|
-
if (!
|
|
32131
|
+
const skillMd = path25.join(dir, "SKILL.md");
|
|
32132
|
+
if (!fs19.existsSync(skillMd)) continue;
|
|
31557
32133
|
const key = `${rel}/${name}`;
|
|
31558
32134
|
if (seenKeys.has(key)) continue;
|
|
31559
32135
|
seenKeys.add(key);
|
|
@@ -31565,23 +32141,23 @@ function discoverLocalSkills(cwd) {
|
|
|
31565
32141
|
function discoverSkillLayoutRoots(cwd) {
|
|
31566
32142
|
const roots = [];
|
|
31567
32143
|
for (const rel of SKILL_DISCOVERY_ROOTS) {
|
|
31568
|
-
const base =
|
|
31569
|
-
if (!
|
|
32144
|
+
const base = path25.join(cwd, rel);
|
|
32145
|
+
if (!fs19.existsSync(base) || !fs19.statSync(base).isDirectory()) continue;
|
|
31570
32146
|
let entries = [];
|
|
31571
32147
|
try {
|
|
31572
|
-
entries =
|
|
32148
|
+
entries = fs19.readdirSync(base);
|
|
31573
32149
|
} catch {
|
|
31574
32150
|
continue;
|
|
31575
32151
|
}
|
|
31576
32152
|
const skills2 = [];
|
|
31577
32153
|
for (const name of entries) {
|
|
31578
|
-
const dir =
|
|
32154
|
+
const dir = path25.join(base, name);
|
|
31579
32155
|
try {
|
|
31580
|
-
if (!
|
|
32156
|
+
if (!fs19.statSync(dir).isDirectory()) continue;
|
|
31581
32157
|
} catch {
|
|
31582
32158
|
continue;
|
|
31583
32159
|
}
|
|
31584
|
-
if (!
|
|
32160
|
+
if (!fs19.existsSync(path25.join(dir, "SKILL.md"))) continue;
|
|
31585
32161
|
const relPath = `${rel}/${name}`.replace(/\\/g, "/");
|
|
31586
32162
|
skills2.push({ name, relPath });
|
|
31587
32163
|
}
|
|
@@ -31726,12 +32302,12 @@ var handleAgentConfigMessage = (msg, deps) => {
|
|
|
31726
32302
|
};
|
|
31727
32303
|
|
|
31728
32304
|
// src/agents/acp/from-bridge/handle-bridge-prompt.ts
|
|
31729
|
-
import * as
|
|
32305
|
+
import * as path27 from "node:path";
|
|
31730
32306
|
import { execFile as execFile5 } from "node:child_process";
|
|
31731
32307
|
import { promisify as promisify5 } from "node:util";
|
|
31732
32308
|
|
|
31733
32309
|
// src/git/bridge-queue-key.ts
|
|
31734
|
-
import * as
|
|
32310
|
+
import * as path26 from "node:path";
|
|
31735
32311
|
import { createHash } from "node:crypto";
|
|
31736
32312
|
function normalizeCanonicalGitUrl(url2) {
|
|
31737
32313
|
let s = url2.trim();
|
|
@@ -31759,11 +32335,11 @@ function canonicalUrlToRepoIdSync(url2) {
|
|
|
31759
32335
|
return createHash("sha256").update(normalized).digest("hex").slice(0, 32);
|
|
31760
32336
|
}
|
|
31761
32337
|
function fallbackRepoIdFromPath(absPath) {
|
|
31762
|
-
return createHash("sha256").update(
|
|
32338
|
+
return createHash("sha256").update(path26.resolve(absPath)).digest("hex").slice(0, 32);
|
|
31763
32339
|
}
|
|
31764
32340
|
async function resolveBridgeQueueBindFields(options) {
|
|
31765
32341
|
const { effectiveCwd, worktreePaths, primaryRepoRoots, log: log2 } = options;
|
|
31766
|
-
const cwdAbs = worktreePaths.length > 0 ?
|
|
32342
|
+
const cwdAbs = worktreePaths.length > 0 ? path26.resolve(worktreePaths[0]) : path26.resolve(effectiveCwd);
|
|
31767
32343
|
if (!primaryRepoRoots.length) {
|
|
31768
32344
|
log2("[Bridge service] Prompt queue bind skipped: no Git repository roots under the working directory.");
|
|
31769
32345
|
return null;
|
|
@@ -31828,7 +32404,7 @@ function handleBridgePrompt(msg, deps) {
|
|
|
31828
32404
|
};
|
|
31829
32405
|
async function preambleAndPrompt(resolvedCwd) {
|
|
31830
32406
|
const s = getWs();
|
|
31831
|
-
const effectiveCwd =
|
|
32407
|
+
const effectiveCwd = path27.resolve(resolvedCwd ?? getBridgeWorkspaceDirectory());
|
|
31832
32408
|
const worktreePaths = sessionWorktreeManager.getWorktreePathsForSession(sessionId) ?? [];
|
|
31833
32409
|
const repoRoots = await resolveSnapshotRepoRoots({
|
|
31834
32410
|
worktreePaths,
|
|
@@ -31953,15 +32529,15 @@ var handleSkillCallMessage = (msg, { getWs, log: log2 }) => {
|
|
|
31953
32529
|
};
|
|
31954
32530
|
|
|
31955
32531
|
// src/files/list-dir.ts
|
|
31956
|
-
import
|
|
31957
|
-
import
|
|
32532
|
+
import fs20 from "node:fs";
|
|
32533
|
+
import path29 from "node:path";
|
|
31958
32534
|
|
|
31959
32535
|
// src/files/ensure-under-cwd.ts
|
|
31960
|
-
import
|
|
32536
|
+
import path28 from "node:path";
|
|
31961
32537
|
function ensureUnderCwd(relativePath, cwd = getBridgeWorkspaceDirectory()) {
|
|
31962
|
-
const normalized =
|
|
31963
|
-
const resolved =
|
|
31964
|
-
if (!resolved.startsWith(cwd +
|
|
32538
|
+
const normalized = path28.normalize(relativePath).replace(/^(\.\/)+/, "");
|
|
32539
|
+
const resolved = path28.resolve(cwd, normalized);
|
|
32540
|
+
if (!resolved.startsWith(cwd + path28.sep) && resolved !== cwd) {
|
|
31965
32541
|
return null;
|
|
31966
32542
|
}
|
|
31967
32543
|
return resolved;
|
|
@@ -31975,7 +32551,7 @@ async function listDirAsync(relativePath) {
|
|
|
31975
32551
|
return { error: "Path is outside working directory" };
|
|
31976
32552
|
}
|
|
31977
32553
|
try {
|
|
31978
|
-
const names = await
|
|
32554
|
+
const names = await fs20.promises.readdir(resolved, { withFileTypes: true });
|
|
31979
32555
|
const visible = names.filter((d) => !d.name.startsWith("."));
|
|
31980
32556
|
const entries = [];
|
|
31981
32557
|
for (let i = 0; i < visible.length; i++) {
|
|
@@ -31983,12 +32559,12 @@ async function listDirAsync(relativePath) {
|
|
|
31983
32559
|
await yieldToEventLoop();
|
|
31984
32560
|
}
|
|
31985
32561
|
const d = visible[i];
|
|
31986
|
-
const entryPath =
|
|
31987
|
-
const fullPath =
|
|
32562
|
+
const entryPath = path29.join(relativePath || ".", d.name).replace(/\\/g, "/");
|
|
32563
|
+
const fullPath = path29.join(resolved, d.name);
|
|
31988
32564
|
let isDir = d.isDirectory();
|
|
31989
32565
|
if (d.isSymbolicLink()) {
|
|
31990
32566
|
try {
|
|
31991
|
-
const targetStat = await
|
|
32567
|
+
const targetStat = await fs20.promises.stat(fullPath);
|
|
31992
32568
|
isDir = targetStat.isDirectory();
|
|
31993
32569
|
} catch {
|
|
31994
32570
|
isDir = false;
|
|
@@ -32013,25 +32589,25 @@ async function listDirAsync(relativePath) {
|
|
|
32013
32589
|
}
|
|
32014
32590
|
|
|
32015
32591
|
// src/files/read-file.ts
|
|
32016
|
-
import
|
|
32592
|
+
import fs21 from "node:fs";
|
|
32017
32593
|
import { StringDecoder } from "node:string_decoder";
|
|
32018
32594
|
function resolveFilePath(relativePath) {
|
|
32019
32595
|
const resolved = ensureUnderCwd(relativePath, getBridgeWorkspaceDirectory());
|
|
32020
32596
|
if (!resolved) return { error: "Path is outside working directory" };
|
|
32021
32597
|
let real;
|
|
32022
32598
|
try {
|
|
32023
|
-
real =
|
|
32599
|
+
real = fs21.realpathSync(resolved);
|
|
32024
32600
|
} catch {
|
|
32025
32601
|
real = resolved;
|
|
32026
32602
|
}
|
|
32027
|
-
const stat2 =
|
|
32603
|
+
const stat2 = fs21.statSync(real);
|
|
32028
32604
|
if (!stat2.isFile()) return { error: "Not a file" };
|
|
32029
32605
|
return real;
|
|
32030
32606
|
}
|
|
32031
32607
|
var LINE_CHUNK_SIZE = 64 * 1024;
|
|
32032
32608
|
function readFileRange(filePath, startLine, endLine, lineOffsetIn, lineChunkSize = LINE_CHUNK_SIZE) {
|
|
32033
|
-
const fileSize =
|
|
32034
|
-
const fd =
|
|
32609
|
+
const fileSize = fs21.statSync(filePath).size;
|
|
32610
|
+
const fd = fs21.openSync(filePath, "r");
|
|
32035
32611
|
const bufSize = 64 * 1024;
|
|
32036
32612
|
const buf = Buffer.alloc(bufSize);
|
|
32037
32613
|
const decoder = new StringDecoder("utf8");
|
|
@@ -32044,7 +32620,7 @@ function readFileRange(filePath, startLine, endLine, lineOffsetIn, lineChunkSize
|
|
|
32044
32620
|
let line0Accum = "";
|
|
32045
32621
|
try {
|
|
32046
32622
|
let bytesRead;
|
|
32047
|
-
while (!done && (bytesRead =
|
|
32623
|
+
while (!done && (bytesRead = fs21.readSync(fd, buf, 0, bufSize, null)) > 0) {
|
|
32048
32624
|
const text = partial2 + decoder.write(buf.subarray(0, bytesRead));
|
|
32049
32625
|
partial2 = "";
|
|
32050
32626
|
let lineStart = 0;
|
|
@@ -32179,7 +32755,7 @@ function readFileRange(filePath, startLine, endLine, lineOffsetIn, lineChunkSize
|
|
|
32179
32755
|
}
|
|
32180
32756
|
return { content: resultLines.join("\n"), size: fileSize };
|
|
32181
32757
|
} finally {
|
|
32182
|
-
|
|
32758
|
+
fs21.closeSync(fd);
|
|
32183
32759
|
}
|
|
32184
32760
|
}
|
|
32185
32761
|
function readFile2(relativePath, startLine, endLine, lineOffset, lineChunkSize = LINE_CHUNK_SIZE) {
|
|
@@ -32190,8 +32766,8 @@ function readFile2(relativePath, startLine, endLine, lineOffset, lineChunkSize =
|
|
|
32190
32766
|
if (hasRange) {
|
|
32191
32767
|
return readFileRange(result, startLine, endLine, lineOffset, lineChunkSize);
|
|
32192
32768
|
}
|
|
32193
|
-
const stat2 =
|
|
32194
|
-
const raw =
|
|
32769
|
+
const stat2 = fs21.statSync(result);
|
|
32770
|
+
const raw = fs21.readFileSync(result, "utf8");
|
|
32195
32771
|
const lines = raw.split(/\r?\n/);
|
|
32196
32772
|
return { content: raw, totalLines: lines.length, size: stat2.size };
|
|
32197
32773
|
} catch (err) {
|
|
@@ -32301,10 +32877,10 @@ function handleSkillLayoutRequest(msg, deps) {
|
|
|
32301
32877
|
}
|
|
32302
32878
|
|
|
32303
32879
|
// src/skills/install-remote-skills.ts
|
|
32304
|
-
import
|
|
32305
|
-
import
|
|
32880
|
+
import fs22 from "node:fs";
|
|
32881
|
+
import path30 from "node:path";
|
|
32306
32882
|
function installRemoteSkills(cwd, targetDir, items) {
|
|
32307
|
-
const
|
|
32883
|
+
const installed2 = [];
|
|
32308
32884
|
if (!Array.isArray(items)) {
|
|
32309
32885
|
return { success: false, error: "Invalid items" };
|
|
32310
32886
|
}
|
|
@@ -32313,24 +32889,24 @@ function installRemoteSkills(cwd, targetDir, items) {
|
|
|
32313
32889
|
if (typeof item.sourceId !== "string" || typeof item.skillName !== "string" || typeof item.versionHash !== "string" || !Array.isArray(item.files)) {
|
|
32314
32890
|
continue;
|
|
32315
32891
|
}
|
|
32316
|
-
const skillDir =
|
|
32892
|
+
const skillDir = path30.join(cwd, targetDir, item.skillName);
|
|
32317
32893
|
for (const f of item.files) {
|
|
32318
32894
|
if (typeof f.path !== "string" || !f.text && !f.base64) continue;
|
|
32319
|
-
const dest =
|
|
32320
|
-
|
|
32895
|
+
const dest = path30.join(skillDir, f.path);
|
|
32896
|
+
fs22.mkdirSync(path30.dirname(dest), { recursive: true });
|
|
32321
32897
|
if (f.text !== void 0) {
|
|
32322
|
-
|
|
32898
|
+
fs22.writeFileSync(dest, f.text, "utf8");
|
|
32323
32899
|
} else if (f.base64) {
|
|
32324
|
-
|
|
32900
|
+
fs22.writeFileSync(dest, Buffer.from(f.base64, "base64"));
|
|
32325
32901
|
}
|
|
32326
32902
|
}
|
|
32327
|
-
|
|
32903
|
+
installed2.push({
|
|
32328
32904
|
sourceId: item.sourceId,
|
|
32329
32905
|
skillName: item.skillName,
|
|
32330
32906
|
versionHash: item.versionHash
|
|
32331
32907
|
});
|
|
32332
32908
|
}
|
|
32333
|
-
return { success: true, installed };
|
|
32909
|
+
return { success: true, installed: installed2 };
|
|
32334
32910
|
} catch (e) {
|
|
32335
32911
|
return { success: false, error: e instanceof Error ? e.message : String(e) };
|
|
32336
32912
|
}
|
|
@@ -32367,7 +32943,8 @@ var handleSessionGitRequestMessage = (msg, deps) => {
|
|
|
32367
32943
|
if (typeof msg.id !== "string") return;
|
|
32368
32944
|
const sessionId = typeof msg.sessionId === "string" ? msg.sessionId : "";
|
|
32369
32945
|
const action = msg.action;
|
|
32370
|
-
if (!sessionId || action !== "status" && action !== "push" && action !== "commit")
|
|
32946
|
+
if (!sessionId || action !== "status" && action !== "push" && action !== "commit" && action !== "list_changes")
|
|
32947
|
+
return;
|
|
32371
32948
|
void (async () => {
|
|
32372
32949
|
const ws = deps.getWs();
|
|
32373
32950
|
const reply = (payload) => sendResult(ws, msg.id, payload);
|
|
@@ -32381,6 +32958,24 @@ var handleSessionGitRequestMessage = (msg, deps) => {
|
|
|
32381
32958
|
});
|
|
32382
32959
|
return;
|
|
32383
32960
|
}
|
|
32961
|
+
if (action === "list_changes") {
|
|
32962
|
+
const repoRel = typeof msg.changesRepoRelPath === "string" ? msg.changesRepoRelPath.trim() : "";
|
|
32963
|
+
const view = msg.changesView === "commit" ? "commit" : "working";
|
|
32964
|
+
const commitSha = typeof msg.changesCommitSha === "string" ? msg.changesCommitSha.trim() : "";
|
|
32965
|
+
if (view === "commit") {
|
|
32966
|
+
if (!repoRel || !commitSha) {
|
|
32967
|
+
reply({ ok: false, error: "changesRepoRelPath and changesCommitSha are required for commit view" });
|
|
32968
|
+
return;
|
|
32969
|
+
}
|
|
32970
|
+
}
|
|
32971
|
+
const opts = repoRel && view === "commit" && commitSha ? { repoRelPath: repoRel, basis: { kind: "commit", sha: commitSha } } : repoRel ? { repoRelPath: repoRel, basis: { kind: "working" } } : void 0;
|
|
32972
|
+
const repos = await deps.sessionWorktreeManager.getSessionWorkingTreeChangeDetails(sessionId, opts);
|
|
32973
|
+
reply({
|
|
32974
|
+
ok: true,
|
|
32975
|
+
repos
|
|
32976
|
+
});
|
|
32977
|
+
return;
|
|
32978
|
+
}
|
|
32384
32979
|
if (action === "push") {
|
|
32385
32980
|
const pushRes = await deps.sessionWorktreeManager.pushSessionUpstream(sessionId);
|
|
32386
32981
|
if (!pushRes.ok) {
|
|
@@ -32447,7 +33042,7 @@ var handleSessionDiscardedMessage = (msg, deps) => {
|
|
|
32447
33042
|
};
|
|
32448
33043
|
|
|
32449
33044
|
// src/bridge/routing/handlers/revert-turn-snapshot.ts
|
|
32450
|
-
import * as
|
|
33045
|
+
import * as fs23 from "node:fs";
|
|
32451
33046
|
var handleRevertTurnSnapshotMessage = (msg, deps) => {
|
|
32452
33047
|
const id = typeof msg.id === "string" ? msg.id : "";
|
|
32453
33048
|
const sessionId = typeof msg.sessionId === "string" ? msg.sessionId : "";
|
|
@@ -32459,7 +33054,7 @@ var handleRevertTurnSnapshotMessage = (msg, deps) => {
|
|
|
32459
33054
|
if (!s) return;
|
|
32460
33055
|
const agentBase = sessionWorktreeManager.getAgentCwdForSession(sessionId) ?? getBridgeWorkspaceDirectory();
|
|
32461
33056
|
const file2 = snapshotFilePath(agentBase, turnId);
|
|
32462
|
-
if (!
|
|
33057
|
+
if (!fs23.existsSync(file2)) {
|
|
32463
33058
|
sendWsMessage(s, {
|
|
32464
33059
|
type: "revert_turn_snapshot_result",
|
|
32465
33060
|
id,
|
|
@@ -32788,6 +33383,7 @@ async function createBridgeConnection(options) {
|
|
|
32788
33383
|
|
|
32789
33384
|
// src/run-bridge.ts
|
|
32790
33385
|
async function runBridge(options) {
|
|
33386
|
+
installBridgeProcessResilience();
|
|
32791
33387
|
const { apiUrl, workspaceId, authToken, refreshToken, bridgeName, justAuthenticated, worktreesRootAbs } = options;
|
|
32792
33388
|
const firehoseServerUrl = options.firehoseServerUrl ?? options.proxyServerUrl;
|
|
32793
33389
|
const hasAuth = workspaceId && authToken;
|