@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/cli.js
CHANGED
|
@@ -973,8 +973,8 @@ var require_command = __commonJS({
|
|
|
973
973
|
"../../node_modules/.pnpm/commander@12.1.0/node_modules/commander/lib/command.js"(exports) {
|
|
974
974
|
var EventEmitter2 = __require("node:events").EventEmitter;
|
|
975
975
|
var childProcess = __require("node:child_process");
|
|
976
|
-
var
|
|
977
|
-
var
|
|
976
|
+
var path32 = __require("node:path");
|
|
977
|
+
var fs25 = __require("node:fs");
|
|
978
978
|
var process2 = __require("node:process");
|
|
979
979
|
var { Argument: Argument2, humanReadableArgName } = require_argument();
|
|
980
980
|
var { CommanderError: CommanderError2 } = require_error();
|
|
@@ -1906,11 +1906,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1906
1906
|
let launchWithNode = false;
|
|
1907
1907
|
const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
|
|
1908
1908
|
function findFile(baseDir, baseName) {
|
|
1909
|
-
const localBin =
|
|
1910
|
-
if (
|
|
1911
|
-
if (sourceExt.includes(
|
|
1909
|
+
const localBin = path32.resolve(baseDir, baseName);
|
|
1910
|
+
if (fs25.existsSync(localBin)) return localBin;
|
|
1911
|
+
if (sourceExt.includes(path32.extname(baseName))) return void 0;
|
|
1912
1912
|
const foundExt = sourceExt.find(
|
|
1913
|
-
(ext) =>
|
|
1913
|
+
(ext) => fs25.existsSync(`${localBin}${ext}`)
|
|
1914
1914
|
);
|
|
1915
1915
|
if (foundExt) return `${localBin}${foundExt}`;
|
|
1916
1916
|
return void 0;
|
|
@@ -1922,21 +1922,21 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1922
1922
|
if (this._scriptPath) {
|
|
1923
1923
|
let resolvedScriptPath;
|
|
1924
1924
|
try {
|
|
1925
|
-
resolvedScriptPath =
|
|
1925
|
+
resolvedScriptPath = fs25.realpathSync(this._scriptPath);
|
|
1926
1926
|
} catch (err) {
|
|
1927
1927
|
resolvedScriptPath = this._scriptPath;
|
|
1928
1928
|
}
|
|
1929
|
-
executableDir =
|
|
1930
|
-
|
|
1929
|
+
executableDir = path32.resolve(
|
|
1930
|
+
path32.dirname(resolvedScriptPath),
|
|
1931
1931
|
executableDir
|
|
1932
1932
|
);
|
|
1933
1933
|
}
|
|
1934
1934
|
if (executableDir) {
|
|
1935
1935
|
let localFile = findFile(executableDir, executableFile);
|
|
1936
1936
|
if (!localFile && !subcommand._executableFile && this._scriptPath) {
|
|
1937
|
-
const legacyName =
|
|
1937
|
+
const legacyName = path32.basename(
|
|
1938
1938
|
this._scriptPath,
|
|
1939
|
-
|
|
1939
|
+
path32.extname(this._scriptPath)
|
|
1940
1940
|
);
|
|
1941
1941
|
if (legacyName !== this._name) {
|
|
1942
1942
|
localFile = findFile(
|
|
@@ -1947,7 +1947,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1947
1947
|
}
|
|
1948
1948
|
executableFile = localFile || executableFile;
|
|
1949
1949
|
}
|
|
1950
|
-
launchWithNode = sourceExt.includes(
|
|
1950
|
+
launchWithNode = sourceExt.includes(path32.extname(executableFile));
|
|
1951
1951
|
let proc;
|
|
1952
1952
|
if (process2.platform !== "win32") {
|
|
1953
1953
|
if (launchWithNode) {
|
|
@@ -2787,7 +2787,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2787
2787
|
* @return {Command}
|
|
2788
2788
|
*/
|
|
2789
2789
|
nameFromFilename(filename) {
|
|
2790
|
-
this._name =
|
|
2790
|
+
this._name = path32.basename(filename, path32.extname(filename));
|
|
2791
2791
|
return this;
|
|
2792
2792
|
}
|
|
2793
2793
|
/**
|
|
@@ -2801,9 +2801,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2801
2801
|
* @param {string} [path]
|
|
2802
2802
|
* @return {(string|null|Command)}
|
|
2803
2803
|
*/
|
|
2804
|
-
executableDir(
|
|
2805
|
-
if (
|
|
2806
|
-
this._executableDir =
|
|
2804
|
+
executableDir(path33) {
|
|
2805
|
+
if (path33 === void 0) return this._executableDir;
|
|
2806
|
+
this._executableDir = path33;
|
|
2807
2807
|
return this;
|
|
2808
2808
|
}
|
|
2809
2809
|
/**
|
|
@@ -7423,10 +7423,10 @@ var require_src2 = __commonJS({
|
|
|
7423
7423
|
var fs_1 = __require("fs");
|
|
7424
7424
|
var debug_1 = __importDefault(require_src());
|
|
7425
7425
|
var log2 = debug_1.default("@kwsites/file-exists");
|
|
7426
|
-
function check2(
|
|
7427
|
-
log2(`checking %s`,
|
|
7426
|
+
function check2(path32, isFile, isDirectory) {
|
|
7427
|
+
log2(`checking %s`, path32);
|
|
7428
7428
|
try {
|
|
7429
|
-
const stat2 = fs_1.statSync(
|
|
7429
|
+
const stat2 = fs_1.statSync(path32);
|
|
7430
7430
|
if (stat2.isFile() && isFile) {
|
|
7431
7431
|
log2(`[OK] path represents a file`);
|
|
7432
7432
|
return true;
|
|
@@ -7446,8 +7446,8 @@ var require_src2 = __commonJS({
|
|
|
7446
7446
|
throw e;
|
|
7447
7447
|
}
|
|
7448
7448
|
}
|
|
7449
|
-
function exists2(
|
|
7450
|
-
return check2(
|
|
7449
|
+
function exists2(path32, type = exports.READABLE) {
|
|
7450
|
+
return check2(path32, (type & exports.FILE) > 0, (type & exports.FOLDER) > 0);
|
|
7451
7451
|
}
|
|
7452
7452
|
exports.exists = exists2;
|
|
7453
7453
|
exports.FILE = 1;
|
|
@@ -7922,8 +7922,8 @@ var init_parseUtil = __esm({
|
|
|
7922
7922
|
init_errors();
|
|
7923
7923
|
init_en();
|
|
7924
7924
|
makeIssue = (params) => {
|
|
7925
|
-
const { data, path:
|
|
7926
|
-
const fullPath = [...
|
|
7925
|
+
const { data, path: path32, errorMaps, issueData } = params;
|
|
7926
|
+
const fullPath = [...path32, ...issueData.path || []];
|
|
7927
7927
|
const fullIssue = {
|
|
7928
7928
|
...issueData,
|
|
7929
7929
|
path: fullPath
|
|
@@ -8231,11 +8231,11 @@ var init_types = __esm({
|
|
|
8231
8231
|
init_parseUtil();
|
|
8232
8232
|
init_util2();
|
|
8233
8233
|
ParseInputLazyPath = class {
|
|
8234
|
-
constructor(parent, value,
|
|
8234
|
+
constructor(parent, value, path32, key) {
|
|
8235
8235
|
this._cachedPath = [];
|
|
8236
8236
|
this.parent = parent;
|
|
8237
8237
|
this.data = value;
|
|
8238
|
-
this._path =
|
|
8238
|
+
this._path = path32;
|
|
8239
8239
|
this._key = key;
|
|
8240
8240
|
}
|
|
8241
8241
|
get path() {
|
|
@@ -11850,15 +11850,15 @@ function assignProp(target, prop, value) {
|
|
|
11850
11850
|
configurable: true
|
|
11851
11851
|
});
|
|
11852
11852
|
}
|
|
11853
|
-
function getElementAtPath(obj,
|
|
11854
|
-
if (!
|
|
11853
|
+
function getElementAtPath(obj, path32) {
|
|
11854
|
+
if (!path32)
|
|
11855
11855
|
return obj;
|
|
11856
|
-
return
|
|
11856
|
+
return path32.reduce((acc, key) => acc?.[key], obj);
|
|
11857
11857
|
}
|
|
11858
11858
|
function promiseAllObject(promisesObj) {
|
|
11859
11859
|
const keys = Object.keys(promisesObj);
|
|
11860
|
-
const
|
|
11861
|
-
return Promise.all(
|
|
11860
|
+
const promises3 = keys.map((key) => promisesObj[key]);
|
|
11861
|
+
return Promise.all(promises3).then((results) => {
|
|
11862
11862
|
const resolvedObj = {};
|
|
11863
11863
|
for (let i = 0; i < keys.length; i++) {
|
|
11864
11864
|
resolvedObj[keys[i]] = results[i];
|
|
@@ -12102,11 +12102,11 @@ function aborted(x, startIndex = 0) {
|
|
|
12102
12102
|
}
|
|
12103
12103
|
return false;
|
|
12104
12104
|
}
|
|
12105
|
-
function prefixIssues(
|
|
12105
|
+
function prefixIssues(path32, issues) {
|
|
12106
12106
|
return issues.map((iss) => {
|
|
12107
12107
|
var _a2;
|
|
12108
12108
|
(_a2 = iss).path ?? (_a2.path = []);
|
|
12109
|
-
iss.path.unshift(
|
|
12109
|
+
iss.path.unshift(path32);
|
|
12110
12110
|
return iss;
|
|
12111
12111
|
});
|
|
12112
12112
|
}
|
|
@@ -12295,7 +12295,7 @@ function treeifyError(error40, _mapper) {
|
|
|
12295
12295
|
return issue2.message;
|
|
12296
12296
|
};
|
|
12297
12297
|
const result = { errors: [] };
|
|
12298
|
-
const processError = (error41,
|
|
12298
|
+
const processError = (error41, path32 = []) => {
|
|
12299
12299
|
var _a2, _b;
|
|
12300
12300
|
for (const issue2 of error41.issues) {
|
|
12301
12301
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
@@ -12305,7 +12305,7 @@ function treeifyError(error40, _mapper) {
|
|
|
12305
12305
|
} else if (issue2.code === "invalid_element") {
|
|
12306
12306
|
processError({ issues: issue2.issues }, issue2.path);
|
|
12307
12307
|
} else {
|
|
12308
|
-
const fullpath = [...
|
|
12308
|
+
const fullpath = [...path32, ...issue2.path];
|
|
12309
12309
|
if (fullpath.length === 0) {
|
|
12310
12310
|
result.errors.push(mapper(issue2));
|
|
12311
12311
|
continue;
|
|
@@ -12335,9 +12335,9 @@ function treeifyError(error40, _mapper) {
|
|
|
12335
12335
|
processError(error40);
|
|
12336
12336
|
return result;
|
|
12337
12337
|
}
|
|
12338
|
-
function toDotPath(
|
|
12338
|
+
function toDotPath(path32) {
|
|
12339
12339
|
const segs = [];
|
|
12340
|
-
for (const seg of
|
|
12340
|
+
for (const seg of path32) {
|
|
12341
12341
|
if (typeof seg === "number")
|
|
12342
12342
|
segs.push(`[${seg}]`);
|
|
12343
12343
|
else if (typeof seg === "symbol")
|
|
@@ -24800,8 +24800,8 @@ var init_acp = __esm({
|
|
|
24800
24800
|
this.#requestHandler = requestHandler;
|
|
24801
24801
|
this.#notificationHandler = notificationHandler;
|
|
24802
24802
|
this.#stream = stream;
|
|
24803
|
-
this.#closedPromise = new Promise((
|
|
24804
|
-
this.#abortController.signal.addEventListener("abort", () =>
|
|
24803
|
+
this.#closedPromise = new Promise((resolve16) => {
|
|
24804
|
+
this.#abortController.signal.addEventListener("abort", () => resolve16());
|
|
24805
24805
|
});
|
|
24806
24806
|
this.#receive();
|
|
24807
24807
|
}
|
|
@@ -24950,8 +24950,8 @@ var init_acp = __esm({
|
|
|
24950
24950
|
}
|
|
24951
24951
|
async sendRequest(method, params) {
|
|
24952
24952
|
const id = this.#nextRequestId++;
|
|
24953
|
-
const responsePromise = new Promise((
|
|
24954
|
-
this.#pendingResponses.set(id, { resolve:
|
|
24953
|
+
const responsePromise = new Promise((resolve16, reject) => {
|
|
24954
|
+
this.#pendingResponses.set(id, { resolve: resolve16, reject });
|
|
24955
24955
|
});
|
|
24956
24956
|
await this.#sendMessage({ jsonrpc: "2.0", id, method, params });
|
|
24957
24957
|
return responsePromise;
|
|
@@ -25047,8 +25047,8 @@ var init_acp = __esm({
|
|
|
25047
25047
|
});
|
|
25048
25048
|
|
|
25049
25049
|
// src/cli.ts
|
|
25050
|
-
import * as
|
|
25051
|
-
import * as
|
|
25050
|
+
import * as fs24 from "node:fs";
|
|
25051
|
+
import * as path31 from "node:path";
|
|
25052
25052
|
|
|
25053
25053
|
// ../../node_modules/.pnpm/commander@12.1.0/node_modules/commander/esm.mjs
|
|
25054
25054
|
var import_index = __toESM(require_commander(), 1);
|
|
@@ -25169,6 +25169,19 @@ function logImmediate(line) {
|
|
|
25169
25169
|
`);
|
|
25170
25170
|
}
|
|
25171
25171
|
|
|
25172
|
+
// src/process-bridge-resilience.ts
|
|
25173
|
+
var installed = false;
|
|
25174
|
+
function installBridgeProcessResilience() {
|
|
25175
|
+
if (installed) return;
|
|
25176
|
+
installed = true;
|
|
25177
|
+
process.on("uncaughtException", (err) => {
|
|
25178
|
+
logImmediate(`[bridge] uncaughtException \u2014 continuing: ${err.stack ?? String(err)}`);
|
|
25179
|
+
});
|
|
25180
|
+
process.on("unhandledRejection", (reason) => {
|
|
25181
|
+
logImmediate(`[bridge] unhandledRejection \u2014 continuing: ${reason instanceof Error ? reason.stack : String(reason)}`);
|
|
25182
|
+
});
|
|
25183
|
+
}
|
|
25184
|
+
|
|
25172
25185
|
// ../../node_modules/.pnpm/ws@8.19.0/node_modules/ws/wrapper.mjs
|
|
25173
25186
|
var import_stream = __toESM(require_stream(), 1);
|
|
25174
25187
|
var import_receiver = __toESM(require_receiver(), 1);
|
|
@@ -25527,8 +25540,8 @@ function runPendingAuth(options) {
|
|
|
25527
25540
|
let hasOpenedBrowser = false;
|
|
25528
25541
|
let resolved = false;
|
|
25529
25542
|
let resolveAuth;
|
|
25530
|
-
const authPromise = new Promise((
|
|
25531
|
-
resolveAuth =
|
|
25543
|
+
const authPromise = new Promise((resolve16) => {
|
|
25544
|
+
resolveAuth = resolve16;
|
|
25532
25545
|
});
|
|
25533
25546
|
let reconnectAttempt = 0;
|
|
25534
25547
|
const signInQuiet = createEmptyReconnectQuietSlot();
|
|
@@ -25650,7 +25663,7 @@ function runPendingAuth(options) {
|
|
|
25650
25663
|
async function closeBridgeConnection(state, acpManager, devServerManager, log2) {
|
|
25651
25664
|
const say = log2 ?? logImmediate;
|
|
25652
25665
|
say("Cleaning up connections\u2026");
|
|
25653
|
-
await new Promise((
|
|
25666
|
+
await new Promise((resolve16) => setImmediate(resolve16));
|
|
25654
25667
|
state.closedByUser = true;
|
|
25655
25668
|
clearReconnectQuietTimer(state.mainQuiet);
|
|
25656
25669
|
clearReconnectQuietTimer(state.firehoseQuiet);
|
|
@@ -25772,8 +25785,8 @@ function pathspec(...paths) {
|
|
|
25772
25785
|
cache.set(key, paths);
|
|
25773
25786
|
return key;
|
|
25774
25787
|
}
|
|
25775
|
-
function isPathSpec(
|
|
25776
|
-
return
|
|
25788
|
+
function isPathSpec(path32) {
|
|
25789
|
+
return path32 instanceof String && cache.has(path32);
|
|
25777
25790
|
}
|
|
25778
25791
|
function toPaths(pathSpec) {
|
|
25779
25792
|
return cache.get(pathSpec) || [];
|
|
@@ -25862,8 +25875,8 @@ function toLinesWithContent(input = "", trimmed2 = true, separator = "\n") {
|
|
|
25862
25875
|
function forEachLineWithContent(input, callback) {
|
|
25863
25876
|
return toLinesWithContent(input, true).map((line) => callback(line));
|
|
25864
25877
|
}
|
|
25865
|
-
function folderExists(
|
|
25866
|
-
return (0, import_file_exists.exists)(
|
|
25878
|
+
function folderExists(path32) {
|
|
25879
|
+
return (0, import_file_exists.exists)(path32, import_file_exists.FOLDER);
|
|
25867
25880
|
}
|
|
25868
25881
|
function append(target, item) {
|
|
25869
25882
|
if (Array.isArray(target)) {
|
|
@@ -26267,8 +26280,8 @@ function checkIsRepoRootTask() {
|
|
|
26267
26280
|
commands,
|
|
26268
26281
|
format: "utf-8",
|
|
26269
26282
|
onError,
|
|
26270
|
-
parser(
|
|
26271
|
-
return /^\.(git)?$/.test(
|
|
26283
|
+
parser(path32) {
|
|
26284
|
+
return /^\.(git)?$/.test(path32.trim());
|
|
26272
26285
|
}
|
|
26273
26286
|
};
|
|
26274
26287
|
}
|
|
@@ -26702,11 +26715,11 @@ function parseGrep(grep) {
|
|
|
26702
26715
|
const paths = /* @__PURE__ */ new Set();
|
|
26703
26716
|
const results = {};
|
|
26704
26717
|
forEachLineWithContent(grep, (input) => {
|
|
26705
|
-
const [
|
|
26706
|
-
paths.add(
|
|
26707
|
-
(results[
|
|
26718
|
+
const [path32, line, preview] = input.split(NULL);
|
|
26719
|
+
paths.add(path32);
|
|
26720
|
+
(results[path32] = results[path32] || []).push({
|
|
26708
26721
|
line: asNumber(line),
|
|
26709
|
-
path:
|
|
26722
|
+
path: path32,
|
|
26710
26723
|
preview
|
|
26711
26724
|
});
|
|
26712
26725
|
});
|
|
@@ -27471,14 +27484,14 @@ var init_hash_object = __esm2({
|
|
|
27471
27484
|
init_task();
|
|
27472
27485
|
}
|
|
27473
27486
|
});
|
|
27474
|
-
function parseInit(bare,
|
|
27487
|
+
function parseInit(bare, path32, text) {
|
|
27475
27488
|
const response = String(text).trim();
|
|
27476
27489
|
let result;
|
|
27477
27490
|
if (result = initResponseRegex.exec(response)) {
|
|
27478
|
-
return new InitSummary(bare,
|
|
27491
|
+
return new InitSummary(bare, path32, false, result[1]);
|
|
27479
27492
|
}
|
|
27480
27493
|
if (result = reInitResponseRegex.exec(response)) {
|
|
27481
|
-
return new InitSummary(bare,
|
|
27494
|
+
return new InitSummary(bare, path32, true, result[1]);
|
|
27482
27495
|
}
|
|
27483
27496
|
let gitDir = "";
|
|
27484
27497
|
const tokens = response.split(" ");
|
|
@@ -27489,7 +27502,7 @@ function parseInit(bare, path30, text) {
|
|
|
27489
27502
|
break;
|
|
27490
27503
|
}
|
|
27491
27504
|
}
|
|
27492
|
-
return new InitSummary(bare,
|
|
27505
|
+
return new InitSummary(bare, path32, /^re/i.test(response), gitDir);
|
|
27493
27506
|
}
|
|
27494
27507
|
var InitSummary;
|
|
27495
27508
|
var initResponseRegex;
|
|
@@ -27498,9 +27511,9 @@ var init_InitSummary = __esm2({
|
|
|
27498
27511
|
"src/lib/responses/InitSummary.ts"() {
|
|
27499
27512
|
"use strict";
|
|
27500
27513
|
InitSummary = class {
|
|
27501
|
-
constructor(bare,
|
|
27514
|
+
constructor(bare, path32, existing, gitDir) {
|
|
27502
27515
|
this.bare = bare;
|
|
27503
|
-
this.path =
|
|
27516
|
+
this.path = path32;
|
|
27504
27517
|
this.existing = existing;
|
|
27505
27518
|
this.gitDir = gitDir;
|
|
27506
27519
|
}
|
|
@@ -27512,7 +27525,7 @@ var init_InitSummary = __esm2({
|
|
|
27512
27525
|
function hasBareCommand(command) {
|
|
27513
27526
|
return command.includes(bareCommand);
|
|
27514
27527
|
}
|
|
27515
|
-
function initTask(bare = false,
|
|
27528
|
+
function initTask(bare = false, path32, customArgs) {
|
|
27516
27529
|
const commands = ["init", ...customArgs];
|
|
27517
27530
|
if (bare && !hasBareCommand(commands)) {
|
|
27518
27531
|
commands.splice(1, 0, bareCommand);
|
|
@@ -27521,7 +27534,7 @@ function initTask(bare = false, path30, customArgs) {
|
|
|
27521
27534
|
commands,
|
|
27522
27535
|
format: "utf-8",
|
|
27523
27536
|
parser(text) {
|
|
27524
|
-
return parseInit(commands.includes("--bare"),
|
|
27537
|
+
return parseInit(commands.includes("--bare"), path32, text);
|
|
27525
27538
|
}
|
|
27526
27539
|
};
|
|
27527
27540
|
}
|
|
@@ -28337,12 +28350,12 @@ var init_FileStatusSummary = __esm2({
|
|
|
28337
28350
|
"use strict";
|
|
28338
28351
|
fromPathRegex = /^(.+)\0(.+)$/;
|
|
28339
28352
|
FileStatusSummary = class {
|
|
28340
|
-
constructor(
|
|
28341
|
-
this.path =
|
|
28353
|
+
constructor(path32, index, working_dir) {
|
|
28354
|
+
this.path = path32;
|
|
28342
28355
|
this.index = index;
|
|
28343
28356
|
this.working_dir = working_dir;
|
|
28344
28357
|
if (index === "R" || working_dir === "R") {
|
|
28345
|
-
const detail = fromPathRegex.exec(
|
|
28358
|
+
const detail = fromPathRegex.exec(path32) || [null, path32, path32];
|
|
28346
28359
|
this.from = detail[2] || "";
|
|
28347
28360
|
this.path = detail[1] || "";
|
|
28348
28361
|
}
|
|
@@ -28373,14 +28386,14 @@ function splitLine(result, lineStr) {
|
|
|
28373
28386
|
default:
|
|
28374
28387
|
return;
|
|
28375
28388
|
}
|
|
28376
|
-
function data(index, workingDir,
|
|
28389
|
+
function data(index, workingDir, path32) {
|
|
28377
28390
|
const raw = `${index}${workingDir}`;
|
|
28378
28391
|
const handler = parsers6.get(raw);
|
|
28379
28392
|
if (handler) {
|
|
28380
|
-
handler(result,
|
|
28393
|
+
handler(result, path32);
|
|
28381
28394
|
}
|
|
28382
28395
|
if (raw !== "##" && raw !== "!!") {
|
|
28383
|
-
result.files.push(new FileStatusSummary(
|
|
28396
|
+
result.files.push(new FileStatusSummary(path32, index, workingDir));
|
|
28384
28397
|
}
|
|
28385
28398
|
}
|
|
28386
28399
|
}
|
|
@@ -28551,14 +28564,14 @@ var init_status = __esm2({
|
|
|
28551
28564
|
ignoredOptions = ["--null", "-z"];
|
|
28552
28565
|
}
|
|
28553
28566
|
});
|
|
28554
|
-
function versionResponse(major = 0, minor = 0, patch = 0, agent = "",
|
|
28567
|
+
function versionResponse(major = 0, minor = 0, patch = 0, agent = "", installed2 = true) {
|
|
28555
28568
|
return Object.defineProperty(
|
|
28556
28569
|
{
|
|
28557
28570
|
major,
|
|
28558
28571
|
minor,
|
|
28559
28572
|
patch,
|
|
28560
28573
|
agent,
|
|
28561
|
-
installed
|
|
28574
|
+
installed: installed2
|
|
28562
28575
|
},
|
|
28563
28576
|
"toString",
|
|
28564
28577
|
{
|
|
@@ -28689,9 +28702,9 @@ var init_simple_git_api = __esm2({
|
|
|
28689
28702
|
next
|
|
28690
28703
|
);
|
|
28691
28704
|
}
|
|
28692
|
-
hashObject(
|
|
28705
|
+
hashObject(path32, write) {
|
|
28693
28706
|
return this._runTask(
|
|
28694
|
-
hashObjectTask(
|
|
28707
|
+
hashObjectTask(path32, write === true),
|
|
28695
28708
|
trailingFunctionArgument(arguments)
|
|
28696
28709
|
);
|
|
28697
28710
|
}
|
|
@@ -29044,8 +29057,8 @@ var init_branch = __esm2({
|
|
|
29044
29057
|
}
|
|
29045
29058
|
});
|
|
29046
29059
|
function toPath(input) {
|
|
29047
|
-
const
|
|
29048
|
-
return
|
|
29060
|
+
const path32 = input.trim().replace(/^["']|["']$/g, "");
|
|
29061
|
+
return path32 && normalize(path32);
|
|
29049
29062
|
}
|
|
29050
29063
|
var parseCheckIgnore;
|
|
29051
29064
|
var init_CheckIgnore = __esm2({
|
|
@@ -29359,8 +29372,8 @@ __export2(sub_module_exports, {
|
|
|
29359
29372
|
subModuleTask: () => subModuleTask,
|
|
29360
29373
|
updateSubModuleTask: () => updateSubModuleTask
|
|
29361
29374
|
});
|
|
29362
|
-
function addSubModuleTask(repo,
|
|
29363
|
-
return subModuleTask(["add", repo,
|
|
29375
|
+
function addSubModuleTask(repo, path32) {
|
|
29376
|
+
return subModuleTask(["add", repo, path32]);
|
|
29364
29377
|
}
|
|
29365
29378
|
function initSubModuleTask(customArgs) {
|
|
29366
29379
|
return subModuleTask(["init", ...customArgs]);
|
|
@@ -29693,8 +29706,8 @@ var require_git = __commonJS2({
|
|
|
29693
29706
|
}
|
|
29694
29707
|
return this._runTask(straightThroughStringTask2(command, this._trimmed), next);
|
|
29695
29708
|
};
|
|
29696
|
-
Git2.prototype.submoduleAdd = function(repo,
|
|
29697
|
-
return this._runTask(addSubModuleTask2(repo,
|
|
29709
|
+
Git2.prototype.submoduleAdd = function(repo, path32, then) {
|
|
29710
|
+
return this._runTask(addSubModuleTask2(repo, path32), trailingFunctionArgument2(arguments));
|
|
29698
29711
|
};
|
|
29699
29712
|
Git2.prototype.submoduleUpdate = function(args, then) {
|
|
29700
29713
|
return this._runTask(
|
|
@@ -30839,7 +30852,7 @@ async function createSdkStdioAcpClient(options) {
|
|
|
30839
30852
|
child.once("close", (code, signal) => {
|
|
30840
30853
|
onAgentSubprocessExit?.({ code, signal });
|
|
30841
30854
|
});
|
|
30842
|
-
return new Promise((
|
|
30855
|
+
return new Promise((resolve16, reject) => {
|
|
30843
30856
|
let initSettled = false;
|
|
30844
30857
|
const settleReject = (err) => {
|
|
30845
30858
|
if (initSettled) return;
|
|
@@ -30853,7 +30866,7 @@ async function createSdkStdioAcpClient(options) {
|
|
|
30853
30866
|
const settleResolve = (handle) => {
|
|
30854
30867
|
if (initSettled) return;
|
|
30855
30868
|
initSettled = true;
|
|
30856
|
-
|
|
30869
|
+
resolve16(handle);
|
|
30857
30870
|
};
|
|
30858
30871
|
child.on("error", (err) => {
|
|
30859
30872
|
settleReject(new Error(formatSpawnError(err, command[0])));
|
|
@@ -30889,8 +30902,8 @@ async function createSdkStdioAcpClient(options) {
|
|
|
30889
30902
|
});
|
|
30890
30903
|
} catch {
|
|
30891
30904
|
}
|
|
30892
|
-
return await new Promise((
|
|
30893
|
-
pendingPermissionResolvers.set(requestId,
|
|
30905
|
+
return await new Promise((resolve17) => {
|
|
30906
|
+
pendingPermissionResolvers.set(requestId, resolve17);
|
|
30894
30907
|
});
|
|
30895
30908
|
},
|
|
30896
30909
|
async readTextFile(params) {
|
|
@@ -30998,9 +31011,9 @@ async function createSdkStdioAcpClient(options) {
|
|
|
30998
31011
|
}
|
|
30999
31012
|
},
|
|
31000
31013
|
async cancel() {
|
|
31001
|
-
for (const [id,
|
|
31014
|
+
for (const [id, resolve17] of [...pendingPermissionResolvers.entries()]) {
|
|
31002
31015
|
pendingPermissionResolvers.delete(id);
|
|
31003
|
-
|
|
31016
|
+
resolve17({ outcome: { outcome: "cancelled" } });
|
|
31004
31017
|
}
|
|
31005
31018
|
try {
|
|
31006
31019
|
await connection.cancel({ sessionId });
|
|
@@ -31016,10 +31029,10 @@ async function createSdkStdioAcpClient(options) {
|
|
|
31016
31029
|
}
|
|
31017
31030
|
},
|
|
31018
31031
|
resolveRequest(requestId, result) {
|
|
31019
|
-
const
|
|
31020
|
-
if (!
|
|
31032
|
+
const resolve17 = pendingPermissionResolvers.get(requestId);
|
|
31033
|
+
if (!resolve17) return;
|
|
31021
31034
|
pendingPermissionResolvers.delete(requestId);
|
|
31022
|
-
|
|
31035
|
+
resolve17(result);
|
|
31023
31036
|
},
|
|
31024
31037
|
disconnect() {
|
|
31025
31038
|
child.kill();
|
|
@@ -31170,7 +31183,7 @@ async function createCursorAcpClient(options) {
|
|
|
31170
31183
|
});
|
|
31171
31184
|
const stderrCapture = createStderrCapture(child);
|
|
31172
31185
|
child.stderr?.on("data", (chunk) => stderrCapture.append(chunk));
|
|
31173
|
-
return new Promise((
|
|
31186
|
+
return new Promise((resolve16, reject) => {
|
|
31174
31187
|
child.on("error", (err) => {
|
|
31175
31188
|
child.kill();
|
|
31176
31189
|
reject(new Error(formatSpawnError2(err, command[0])));
|
|
@@ -31357,7 +31370,7 @@ async function createCursorAcpClient(options) {
|
|
|
31357
31370
|
const newResult = await send("session/new", { cwd, mcpServers: [] });
|
|
31358
31371
|
const sessionId = newResult?.sessionId ?? "";
|
|
31359
31372
|
if (!sessionId) throw new Error("Cursor ACP session/new did not return sessionId");
|
|
31360
|
-
|
|
31373
|
+
resolve16({
|
|
31361
31374
|
sessionId,
|
|
31362
31375
|
async sendPrompt(prompt, _options) {
|
|
31363
31376
|
promptOutputBuffer = "";
|
|
@@ -32415,7 +32428,7 @@ async function createAcpManager(options) {
|
|
|
32415
32428
|
}
|
|
32416
32429
|
|
|
32417
32430
|
// src/worktrees/session-worktree-manager.ts
|
|
32418
|
-
import * as
|
|
32431
|
+
import * as path15 from "node:path";
|
|
32419
32432
|
import os3 from "node:os";
|
|
32420
32433
|
|
|
32421
32434
|
// src/worktrees/prepare-new-session-worktrees.ts
|
|
@@ -32582,7 +32595,7 @@ async function removeSessionWorktrees(paths, log2) {
|
|
|
32582
32595
|
}
|
|
32583
32596
|
}
|
|
32584
32597
|
|
|
32585
|
-
// src/git/working-tree-status.ts
|
|
32598
|
+
// src/git/working-directory/status/working-tree-status.ts
|
|
32586
32599
|
async function tryConfigGet(g, key) {
|
|
32587
32600
|
try {
|
|
32588
32601
|
const out = await g.raw(["config", "--get", key]);
|
|
@@ -32592,11 +32605,24 @@ async function tryConfigGet(g, key) {
|
|
|
32592
32605
|
return null;
|
|
32593
32606
|
}
|
|
32594
32607
|
}
|
|
32608
|
+
async function revParseSafe(g, ref) {
|
|
32609
|
+
try {
|
|
32610
|
+
const v = (await g.raw(["rev-parse", ref])).trim();
|
|
32611
|
+
return v || null;
|
|
32612
|
+
} catch {
|
|
32613
|
+
return null;
|
|
32614
|
+
}
|
|
32615
|
+
}
|
|
32595
32616
|
async function resolveRemoteTrackingRefForAhead(g) {
|
|
32596
32617
|
try {
|
|
32597
|
-
await g.raw(["rev-parse", "--verify", "@{
|
|
32598
|
-
return "@{
|
|
32618
|
+
await g.raw(["rev-parse", "--verify", "HEAD@{upstream}"]);
|
|
32619
|
+
return "HEAD@{upstream}";
|
|
32599
32620
|
} catch {
|
|
32621
|
+
try {
|
|
32622
|
+
await g.raw(["rev-parse", "--verify", "@{u}"]);
|
|
32623
|
+
return "@{u}";
|
|
32624
|
+
} catch {
|
|
32625
|
+
}
|
|
32600
32626
|
}
|
|
32601
32627
|
const branch = (await g.raw(["rev-parse", "--abbrev-ref", "HEAD"])).trim();
|
|
32602
32628
|
if (!branch || branch === "HEAD") return null;
|
|
@@ -32619,16 +32645,76 @@ async function resolveRemoteTrackingRefForAhead(g) {
|
|
|
32619
32645
|
return null;
|
|
32620
32646
|
}
|
|
32621
32647
|
}
|
|
32648
|
+
async function remoteForCurrentBranch(g) {
|
|
32649
|
+
const branch = (await g.raw(["rev-parse", "--abbrev-ref", "HEAD"])).trim();
|
|
32650
|
+
if (!branch || branch === "HEAD") return "origin";
|
|
32651
|
+
return await tryConfigGet(g, `branch.${branch}.remote`) ?? "origin";
|
|
32652
|
+
}
|
|
32653
|
+
async function resolveDefaultRemoteBranchRef(g, remote) {
|
|
32654
|
+
const headSym = `refs/remotes/${remote}/HEAD`;
|
|
32655
|
+
try {
|
|
32656
|
+
const resolved = (await g.raw(["symbolic-ref", "-q", "--verify", headSym])).trim();
|
|
32657
|
+
if (resolved.startsWith("refs/remotes/")) return resolved;
|
|
32658
|
+
} catch {
|
|
32659
|
+
}
|
|
32660
|
+
for (const name of ["main", "master", "trunk", "develop"]) {
|
|
32661
|
+
const r = `refs/remotes/${remote}/${name}`;
|
|
32662
|
+
try {
|
|
32663
|
+
await g.raw(["rev-parse", "--verify", r]);
|
|
32664
|
+
return r;
|
|
32665
|
+
} catch {
|
|
32666
|
+
}
|
|
32667
|
+
}
|
|
32668
|
+
return null;
|
|
32669
|
+
}
|
|
32670
|
+
async function resolveBaseShaForUnpushedCommits(g) {
|
|
32671
|
+
const trackingRef = await resolveRemoteTrackingRefForAhead(g);
|
|
32672
|
+
if (trackingRef) {
|
|
32673
|
+
const sha = await revParseSafe(g, trackingRef);
|
|
32674
|
+
if (sha) return sha;
|
|
32675
|
+
}
|
|
32676
|
+
const remote = await remoteForCurrentBranch(g);
|
|
32677
|
+
const defaultRef = await resolveDefaultRemoteBranchRef(g, remote);
|
|
32678
|
+
if (!defaultRef) return null;
|
|
32679
|
+
return revParseSafe(g, defaultRef);
|
|
32680
|
+
}
|
|
32681
|
+
function parseLogShaDateSubjectLines(raw) {
|
|
32682
|
+
const out = [];
|
|
32683
|
+
for (const line of String(raw).split("\n")) {
|
|
32684
|
+
const l = line.trimEnd();
|
|
32685
|
+
if (!l.trim()) continue;
|
|
32686
|
+
const parts = l.split(" ");
|
|
32687
|
+
if (parts.length < 3) continue;
|
|
32688
|
+
const sha = parts[0].trim();
|
|
32689
|
+
const committedAt = parts[1].trim();
|
|
32690
|
+
const subject = parts.slice(2).join(" ").trim();
|
|
32691
|
+
if (!/^[0-9a-f]{7,40}$/i.test(sha)) continue;
|
|
32692
|
+
out.push({ sha, shortSha: sha.slice(0, 7), subject, committedAt });
|
|
32693
|
+
}
|
|
32694
|
+
return out;
|
|
32695
|
+
}
|
|
32696
|
+
async function gitLogNotReachableFromBase(g, baseSha, headSha) {
|
|
32697
|
+
if (baseSha === headSha) return [];
|
|
32698
|
+
try {
|
|
32699
|
+
const logOut = await g.raw(["log", "--format=%H %cI %s", `${baseSha}..${headSha}`]);
|
|
32700
|
+
return parseLogShaDateSubjectLines(logOut);
|
|
32701
|
+
} catch {
|
|
32702
|
+
return [];
|
|
32703
|
+
}
|
|
32704
|
+
}
|
|
32622
32705
|
async function commitsAheadOfRemoteTracking(repoDir) {
|
|
32623
32706
|
const g = simpleGit(repoDir);
|
|
32624
|
-
const
|
|
32625
|
-
if (!
|
|
32626
|
-
const
|
|
32627
|
-
|
|
32628
|
-
|
|
32629
|
-
|
|
32630
|
-
|
|
32631
|
-
|
|
32707
|
+
const headSha = await revParseSafe(g, "HEAD");
|
|
32708
|
+
if (!headSha) return 0;
|
|
32709
|
+
const baseSha = await resolveBaseShaForUnpushedCommits(g);
|
|
32710
|
+
if (!baseSha || baseSha === headSha) return 0;
|
|
32711
|
+
try {
|
|
32712
|
+
const out = await g.raw(["rev-list", "--count", `${baseSha}..${headSha}`]);
|
|
32713
|
+
const n = parseInt(String(out).trim(), 10);
|
|
32714
|
+
return Number.isNaN(n) ? 0 : n;
|
|
32715
|
+
} catch {
|
|
32716
|
+
return 0;
|
|
32717
|
+
}
|
|
32632
32718
|
}
|
|
32633
32719
|
async function getRepoWorkingTreeStatus(repoDir) {
|
|
32634
32720
|
const g = simpleGit(repoDir);
|
|
@@ -32637,6 +32723,14 @@ async function getRepoWorkingTreeStatus(repoDir) {
|
|
|
32637
32723
|
const ahead = await commitsAheadOfRemoteTracking(repoDir);
|
|
32638
32724
|
return { hasUncommittedChanges, hasUnpushedCommits: ahead > 0 };
|
|
32639
32725
|
}
|
|
32726
|
+
async function listUnpushedCommits(repoDir) {
|
|
32727
|
+
const g = simpleGit(repoDir);
|
|
32728
|
+
const headSha = await revParseSafe(g, "HEAD");
|
|
32729
|
+
if (!headSha) return [];
|
|
32730
|
+
const baseSha = await resolveBaseShaForUnpushedCommits(g);
|
|
32731
|
+
if (!baseSha) return [];
|
|
32732
|
+
return gitLogNotReachableFromBase(g, baseSha, headSha);
|
|
32733
|
+
}
|
|
32640
32734
|
async function aggregateSessionPathsWorkingTreeStatus(paths) {
|
|
32641
32735
|
let hasUncommittedChanges = false;
|
|
32642
32736
|
let hasUnpushedCommits = false;
|
|
@@ -32656,6 +32750,477 @@ async function pushAheadOfUpstreamForPaths(paths) {
|
|
|
32656
32750
|
}
|
|
32657
32751
|
}
|
|
32658
32752
|
|
|
32753
|
+
// src/git/working-directory/changes/types.ts
|
|
32754
|
+
var MAX_PATCH_CHARS = 35e4;
|
|
32755
|
+
|
|
32756
|
+
// src/git/working-directory/changes/repo-format.ts
|
|
32757
|
+
function posixJoinDirFile(dir, file2) {
|
|
32758
|
+
const d = dir === "." || dir === "" ? "" : dir.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
32759
|
+
const f = file2.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
32760
|
+
return d ? `${d}/${f}` : f;
|
|
32761
|
+
}
|
|
32762
|
+
function formatRepoShortTitle(remoteUrl, repoRelPath) {
|
|
32763
|
+
const u = remoteUrl.trim();
|
|
32764
|
+
if (u) {
|
|
32765
|
+
try {
|
|
32766
|
+
if (u.startsWith("git@")) {
|
|
32767
|
+
const colon = u.indexOf(":");
|
|
32768
|
+
if (colon > 0) {
|
|
32769
|
+
const pathPart = u.slice(colon + 1).replace(/\.git$/i, "").replace(/\/+$/, "");
|
|
32770
|
+
if (pathPart.includes("/")) return pathPart;
|
|
32771
|
+
}
|
|
32772
|
+
} else {
|
|
32773
|
+
const parsed = new URL(u);
|
|
32774
|
+
const p = parsed.pathname.replace(/^\//, "").replace(/\.git$/i, "");
|
|
32775
|
+
const parts = p.split("/").filter(Boolean);
|
|
32776
|
+
if (parts.length >= 2) {
|
|
32777
|
+
return `${parts[parts.length - 2]}/${parts[parts.length - 1]}`;
|
|
32778
|
+
}
|
|
32779
|
+
if (parts.length === 1) return parts[0];
|
|
32780
|
+
}
|
|
32781
|
+
} catch {
|
|
32782
|
+
}
|
|
32783
|
+
}
|
|
32784
|
+
if (repoRelPath && repoRelPath !== ".") {
|
|
32785
|
+
const segments = repoRelPath.split("/").filter(Boolean);
|
|
32786
|
+
const last2 = segments[segments.length - 1];
|
|
32787
|
+
if (last2) return last2;
|
|
32788
|
+
}
|
|
32789
|
+
return "Repository";
|
|
32790
|
+
}
|
|
32791
|
+
function formatRemoteDisplayLabel(remoteUrl) {
|
|
32792
|
+
const u = remoteUrl.trim();
|
|
32793
|
+
if (!u) return "";
|
|
32794
|
+
let hostPath = u;
|
|
32795
|
+
try {
|
|
32796
|
+
if (u.startsWith("git@")) {
|
|
32797
|
+
const rest = u.slice("git@".length);
|
|
32798
|
+
const slash = rest.indexOf(":");
|
|
32799
|
+
if (slash > 0) hostPath = `${rest.slice(0, slash)}/${rest.slice(slash + 1)}`;
|
|
32800
|
+
} else {
|
|
32801
|
+
const parsed = new URL(u);
|
|
32802
|
+
hostPath = `${parsed.hostname}${parsed.pathname}`.replace(/\/\.git$/i, "").replace(/\.git$/i, "");
|
|
32803
|
+
}
|
|
32804
|
+
} catch {
|
|
32805
|
+
hostPath = u.replace(/^https?:\/\//i, "").replace(/\.git$/i, "");
|
|
32806
|
+
}
|
|
32807
|
+
return `origin \xB7 ${hostPath}`;
|
|
32808
|
+
}
|
|
32809
|
+
|
|
32810
|
+
// src/git/working-directory/changes/get-working-tree-change-repo-details.ts
|
|
32811
|
+
import * as path14 from "node:path";
|
|
32812
|
+
|
|
32813
|
+
// src/git/working-directory/changes/parse-git-status.ts
|
|
32814
|
+
function parseNameStatusLines(lines) {
|
|
32815
|
+
const m = /* @__PURE__ */ new Map();
|
|
32816
|
+
for (const line of lines) {
|
|
32817
|
+
if (!line.trim()) continue;
|
|
32818
|
+
const tabParts = line.split(" ");
|
|
32819
|
+
if (tabParts.length < 2) continue;
|
|
32820
|
+
const status = tabParts[0].trim();
|
|
32821
|
+
const code = status[0];
|
|
32822
|
+
if (code === "A") {
|
|
32823
|
+
m.set(tabParts[tabParts.length - 1], "added");
|
|
32824
|
+
} else if (code === "D") {
|
|
32825
|
+
m.set(tabParts[tabParts.length - 1], "removed");
|
|
32826
|
+
} else if (code === "R" || code === "C") {
|
|
32827
|
+
if (tabParts.length >= 3) m.set(tabParts[tabParts.length - 1], "modified");
|
|
32828
|
+
} else if (code === "M" || code === "U" || code === "T") {
|
|
32829
|
+
m.set(tabParts[tabParts.length - 1], "modified");
|
|
32830
|
+
}
|
|
32831
|
+
}
|
|
32832
|
+
return m;
|
|
32833
|
+
}
|
|
32834
|
+
function parseNumstatFirstLine(line) {
|
|
32835
|
+
const parts = line.split(" ");
|
|
32836
|
+
if (parts.length < 3) return null;
|
|
32837
|
+
const [a, d] = parts;
|
|
32838
|
+
const additions = a === "-" ? 0 : parseInt(String(a), 10) || 0;
|
|
32839
|
+
const deletions = d === "-" ? 0 : parseInt(String(d), 10) || 0;
|
|
32840
|
+
return { additions, deletions };
|
|
32841
|
+
}
|
|
32842
|
+
function parseNumstat(lines) {
|
|
32843
|
+
const m = /* @__PURE__ */ new Map();
|
|
32844
|
+
for (const line of lines) {
|
|
32845
|
+
if (!line.trim()) continue;
|
|
32846
|
+
const parts = line.split(" ");
|
|
32847
|
+
if (parts.length < 3) continue;
|
|
32848
|
+
const [a, d, p] = parts;
|
|
32849
|
+
const additions = a === "-" ? 0 : parseInt(String(a), 10) || 0;
|
|
32850
|
+
const deletions = d === "-" ? 0 : parseInt(String(d), 10) || 0;
|
|
32851
|
+
m.set(p, { additions, deletions });
|
|
32852
|
+
}
|
|
32853
|
+
return m;
|
|
32854
|
+
}
|
|
32855
|
+
async function numstatFromGitNoIndex(g, pathInRepo) {
|
|
32856
|
+
const devNull = process.platform === "win32" ? "NUL" : "/dev/null";
|
|
32857
|
+
try {
|
|
32858
|
+
const out = await g.raw(["diff", "--numstat", "--no-index", "--", devNull, pathInRepo]);
|
|
32859
|
+
const first2 = String(out).split("\n").find((l) => l.trim()) ?? "";
|
|
32860
|
+
return parseNumstatFirstLine(first2);
|
|
32861
|
+
} catch {
|
|
32862
|
+
return null;
|
|
32863
|
+
}
|
|
32864
|
+
}
|
|
32865
|
+
|
|
32866
|
+
// src/git/working-directory/changes/patch-truncate.ts
|
|
32867
|
+
function truncatePatch(s) {
|
|
32868
|
+
if (s.length <= MAX_PATCH_CHARS) return s;
|
|
32869
|
+
return `${s.slice(0, MAX_PATCH_CHARS)}
|
|
32870
|
+
|
|
32871
|
+
\u2026 (diff truncated)`;
|
|
32872
|
+
}
|
|
32873
|
+
|
|
32874
|
+
// src/git/working-directory/changes/list-changed-files-for-commit.ts
|
|
32875
|
+
var EMPTY_TREE = "4b825dc642cb6eb9a060e54bf8d69288fbee4904";
|
|
32876
|
+
async function parentForCommitDiff(g, sha) {
|
|
32877
|
+
try {
|
|
32878
|
+
return (await g.raw(["rev-parse", `${sha}^1`])).trim();
|
|
32879
|
+
} catch {
|
|
32880
|
+
try {
|
|
32881
|
+
return (await g.raw(["rev-parse", `${sha}^`])).trim();
|
|
32882
|
+
} catch {
|
|
32883
|
+
return EMPTY_TREE;
|
|
32884
|
+
}
|
|
32885
|
+
}
|
|
32886
|
+
}
|
|
32887
|
+
async function listChangedFilesForCommit(repoGitCwd, repoRelPath, commitSha) {
|
|
32888
|
+
const g = simpleGit(repoGitCwd);
|
|
32889
|
+
const parent = await parentForCommitDiff(g, commitSha);
|
|
32890
|
+
const range = `${parent}..${commitSha}`;
|
|
32891
|
+
const [nameStatusRaw, numstatRaw] = await Promise.all([
|
|
32892
|
+
g.raw(["diff", "--name-status", range]).catch(() => ""),
|
|
32893
|
+
g.raw(["diff", "--numstat", range]).catch(() => "")
|
|
32894
|
+
]);
|
|
32895
|
+
const kindByPath = parseNameStatusLines(String(nameStatusRaw).split("\n"));
|
|
32896
|
+
const numByPath = parseNumstat(String(numstatRaw).split("\n"));
|
|
32897
|
+
const paths = new Set([...kindByPath.keys(), ...numByPath.keys()].filter(Boolean));
|
|
32898
|
+
const rows = [];
|
|
32899
|
+
const normRel = repoRelPath === "." || repoRelPath === "" ? "." : repoRelPath;
|
|
32900
|
+
for (const pathInRepo of paths) {
|
|
32901
|
+
const relLauncher = posixJoinDirFile(normRel, pathInRepo.replace(/\\/g, "/"));
|
|
32902
|
+
const nums = numByPath.get(pathInRepo);
|
|
32903
|
+
let additions = nums?.additions ?? 0;
|
|
32904
|
+
let deletions = nums?.deletions ?? 0;
|
|
32905
|
+
let change = kindByPath.get(pathInRepo) ?? "modified";
|
|
32906
|
+
if (!kindByPath.has(pathInRepo) && nums) {
|
|
32907
|
+
if (additions > 0 && deletions === 0) change = "added";
|
|
32908
|
+
else if (deletions > 0 && additions === 0) change = "removed";
|
|
32909
|
+
else change = "modified";
|
|
32910
|
+
}
|
|
32911
|
+
rows.push({ pathRelLauncher: relLauncher, additions, deletions, change });
|
|
32912
|
+
}
|
|
32913
|
+
for (const row of rows) {
|
|
32914
|
+
let pathInRepo;
|
|
32915
|
+
if (normRel === ".") {
|
|
32916
|
+
pathInRepo = row.pathRelLauncher;
|
|
32917
|
+
} else if (row.pathRelLauncher.startsWith(`${normRel}/`)) {
|
|
32918
|
+
pathInRepo = row.pathRelLauncher.slice(normRel.length + 1);
|
|
32919
|
+
} else {
|
|
32920
|
+
pathInRepo = row.pathRelLauncher;
|
|
32921
|
+
}
|
|
32922
|
+
const raw = await g.raw(["diff", "-U20000", range, "--", pathInRepo]).catch(() => "");
|
|
32923
|
+
const t = String(raw).trim();
|
|
32924
|
+
row.patchContent = t ? truncatePatch(t) : void 0;
|
|
32925
|
+
}
|
|
32926
|
+
rows.sort((a, b) => a.pathRelLauncher.localeCompare(b.pathRelLauncher));
|
|
32927
|
+
return rows;
|
|
32928
|
+
}
|
|
32929
|
+
|
|
32930
|
+
// src/git/working-directory/changes/list-changed-files-for-repo.ts
|
|
32931
|
+
import * as fs11 from "node:fs";
|
|
32932
|
+
import * as path13 from "node:path";
|
|
32933
|
+
|
|
32934
|
+
// src/git/working-directory/changes/count-lines.ts
|
|
32935
|
+
import { createReadStream } from "node:fs";
|
|
32936
|
+
import * as readline2 from "node:readline";
|
|
32937
|
+
async function countTextFileLines(absFile) {
|
|
32938
|
+
let bytes = 0;
|
|
32939
|
+
const maxBytes = 512e3;
|
|
32940
|
+
let lines = 0;
|
|
32941
|
+
const stream = createReadStream(absFile, { encoding: "utf8" });
|
|
32942
|
+
const rl = readline2.createInterface({ input: stream, crlfDelay: Infinity });
|
|
32943
|
+
for await (const _line of rl) {
|
|
32944
|
+
lines += 1;
|
|
32945
|
+
bytes += Buffer.byteLength(String(_line), "utf8") + 1;
|
|
32946
|
+
if (bytes > maxBytes) {
|
|
32947
|
+
rl.close();
|
|
32948
|
+
stream.destroy();
|
|
32949
|
+
return lines;
|
|
32950
|
+
}
|
|
32951
|
+
}
|
|
32952
|
+
return lines;
|
|
32953
|
+
}
|
|
32954
|
+
|
|
32955
|
+
// src/git/working-directory/changes/hydrate-patch.ts
|
|
32956
|
+
import * as fs10 from "node:fs";
|
|
32957
|
+
var UNIFIED_HUNK_HEADER_RE = /^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/;
|
|
32958
|
+
var MAX_HYDRATE_LINES_PER_GAP = 8e3;
|
|
32959
|
+
var MAX_HYDRATE_LINES_PER_FILE = 8e4;
|
|
32960
|
+
async function readGitBlobLines(repoCwd, pathInRepo) {
|
|
32961
|
+
try {
|
|
32962
|
+
const rel = pathInRepo.replace(/\\/g, "/");
|
|
32963
|
+
const raw = await simpleGit(repoCwd).show([`HEAD:${rel}`]);
|
|
32964
|
+
return String(raw).split(/\r?\n/);
|
|
32965
|
+
} catch {
|
|
32966
|
+
return null;
|
|
32967
|
+
}
|
|
32968
|
+
}
|
|
32969
|
+
async function readWorktreeFileLines(abs) {
|
|
32970
|
+
try {
|
|
32971
|
+
const raw = await fs10.promises.readFile(abs, "utf8");
|
|
32972
|
+
return raw.split(/\r?\n/);
|
|
32973
|
+
} catch {
|
|
32974
|
+
return null;
|
|
32975
|
+
}
|
|
32976
|
+
}
|
|
32977
|
+
async function hydrateUnifiedPatchWithFileContext(patch, absFile, repoGitCwd, pathInRepo, change) {
|
|
32978
|
+
if (!patch.trim() || patch.includes("Binary files")) return patch;
|
|
32979
|
+
const all = patch.split("\n");
|
|
32980
|
+
const out = [];
|
|
32981
|
+
let prevOldEnd = 0;
|
|
32982
|
+
let prevNewEnd = 0;
|
|
32983
|
+
let injectedTotal = 0;
|
|
32984
|
+
let i = 0;
|
|
32985
|
+
let blobCache;
|
|
32986
|
+
let diskCache;
|
|
32987
|
+
const blobLines = async () => {
|
|
32988
|
+
if (blobCache !== void 0) return blobCache;
|
|
32989
|
+
blobCache = await readGitBlobLines(repoGitCwd, pathInRepo);
|
|
32990
|
+
return blobCache;
|
|
32991
|
+
};
|
|
32992
|
+
const diskLines = async () => {
|
|
32993
|
+
if (diskCache !== void 0) return diskCache;
|
|
32994
|
+
diskCache = await readWorktreeFileLines(absFile);
|
|
32995
|
+
return diskCache;
|
|
32996
|
+
};
|
|
32997
|
+
while (i < all.length) {
|
|
32998
|
+
const line = all[i];
|
|
32999
|
+
const hm = line.match(UNIFIED_HUNK_HEADER_RE);
|
|
33000
|
+
if (!hm) {
|
|
33001
|
+
out.push(line);
|
|
33002
|
+
i++;
|
|
33003
|
+
continue;
|
|
33004
|
+
}
|
|
33005
|
+
const oldStart = parseInt(hm[1], 10) || 0;
|
|
33006
|
+
const newStart = parseInt(hm[3], 10) || 0;
|
|
33007
|
+
const gapOldStart = prevOldEnd + 1;
|
|
33008
|
+
const gapOldEnd = oldStart - 1;
|
|
33009
|
+
const gapNewStart = prevNewEnd + 1;
|
|
33010
|
+
const gapNewEnd = newStart - 1;
|
|
33011
|
+
if (injectedTotal < MAX_HYDRATE_LINES_PER_FILE) {
|
|
33012
|
+
let inject = null;
|
|
33013
|
+
if (gapNewEnd >= gapNewStart && change !== "removed") {
|
|
33014
|
+
const nNew = gapNewEnd - gapNewStart + 1;
|
|
33015
|
+
if (gapOldEnd < gapOldStart || gapOldEnd - gapOldStart + 1 === nNew) {
|
|
33016
|
+
const cap = Math.min(nNew, MAX_HYDRATE_LINES_PER_GAP, MAX_HYDRATE_LINES_PER_FILE - injectedTotal);
|
|
33017
|
+
const dl = await diskLines();
|
|
33018
|
+
if (dl && cap > 0) {
|
|
33019
|
+
inject = dl.slice(gapNewStart - 1, gapNewStart - 1 + cap);
|
|
33020
|
+
}
|
|
33021
|
+
}
|
|
33022
|
+
} else if (gapOldEnd >= gapOldStart && change === "removed") {
|
|
33023
|
+
const nOld = gapOldEnd - gapOldStart + 1;
|
|
33024
|
+
const cap = Math.min(nOld, MAX_HYDRATE_LINES_PER_GAP, MAX_HYDRATE_LINES_PER_FILE - injectedTotal);
|
|
33025
|
+
const bl = await blobLines();
|
|
33026
|
+
if (bl && cap > 0) {
|
|
33027
|
+
inject = bl.slice(gapOldStart - 1, gapOldStart - 1 + cap);
|
|
33028
|
+
}
|
|
33029
|
+
}
|
|
33030
|
+
if (inject && inject.length > 0) {
|
|
33031
|
+
for (const t of inject) {
|
|
33032
|
+
out.push(` ${t}`);
|
|
33033
|
+
injectedTotal++;
|
|
33034
|
+
}
|
|
33035
|
+
}
|
|
33036
|
+
}
|
|
33037
|
+
out.push(line);
|
|
33038
|
+
i++;
|
|
33039
|
+
let oldConsumed = 0;
|
|
33040
|
+
let newConsumed = 0;
|
|
33041
|
+
while (i < all.length) {
|
|
33042
|
+
const bl = all[i];
|
|
33043
|
+
if (UNIFIED_HUNK_HEADER_RE.test(bl)) break;
|
|
33044
|
+
out.push(bl);
|
|
33045
|
+
i++;
|
|
33046
|
+
if (bl.startsWith("\\")) continue;
|
|
33047
|
+
const ch = bl[0];
|
|
33048
|
+
if (ch === " ") {
|
|
33049
|
+
oldConsumed++;
|
|
33050
|
+
newConsumed++;
|
|
33051
|
+
} else if (ch === "-") {
|
|
33052
|
+
oldConsumed++;
|
|
33053
|
+
} else if (ch === "+") {
|
|
33054
|
+
newConsumed++;
|
|
33055
|
+
}
|
|
33056
|
+
}
|
|
33057
|
+
if (oldStart > 0) {
|
|
33058
|
+
prevOldEnd = oldStart + oldConsumed - 1;
|
|
33059
|
+
} else {
|
|
33060
|
+
prevOldEnd = 0;
|
|
33061
|
+
}
|
|
33062
|
+
if (newStart > 0) {
|
|
33063
|
+
prevNewEnd = newStart + newConsumed - 1;
|
|
33064
|
+
} else {
|
|
33065
|
+
prevNewEnd = 0;
|
|
33066
|
+
}
|
|
33067
|
+
}
|
|
33068
|
+
return truncatePatch(out.join("\n"));
|
|
33069
|
+
}
|
|
33070
|
+
|
|
33071
|
+
// src/git/working-directory/changes/unified-diff-for-file.ts
|
|
33072
|
+
async function unifiedDiffForFile(repoCwd, pathInRepo, change) {
|
|
33073
|
+
const g = simpleGit(repoCwd);
|
|
33074
|
+
try {
|
|
33075
|
+
let raw;
|
|
33076
|
+
if (change === "added") {
|
|
33077
|
+
const devNull = process.platform === "win32" ? "NUL" : "/dev/null";
|
|
33078
|
+
raw = await g.raw(["diff", "--no-index", "--", devNull, pathInRepo]);
|
|
33079
|
+
} else {
|
|
33080
|
+
raw = await g.raw(["diff", "HEAD", "--", pathInRepo]);
|
|
33081
|
+
}
|
|
33082
|
+
const t = String(raw).trim();
|
|
33083
|
+
if (!t) return void 0;
|
|
33084
|
+
return truncatePatch(t);
|
|
33085
|
+
} catch {
|
|
33086
|
+
return void 0;
|
|
33087
|
+
}
|
|
33088
|
+
}
|
|
33089
|
+
|
|
33090
|
+
// src/git/working-directory/changes/list-changed-files-for-repo.ts
|
|
33091
|
+
async function listChangedFilesForRepo(repoGitCwd, repoRelPath) {
|
|
33092
|
+
const g = simpleGit(repoGitCwd);
|
|
33093
|
+
const [nameStatusRaw, numstatRaw, untrackedRaw] = await Promise.all([
|
|
33094
|
+
g.raw(["diff", "--name-status", "HEAD"]).catch(() => ""),
|
|
33095
|
+
g.raw(["diff", "HEAD", "--numstat"]).catch(() => ""),
|
|
33096
|
+
g.raw(["ls-files", "--others", "--exclude-standard"]).catch(() => "")
|
|
33097
|
+
]);
|
|
33098
|
+
const kindByPath = parseNameStatusLines(String(nameStatusRaw).split("\n"));
|
|
33099
|
+
const numByPath = parseNumstat(String(numstatRaw).split("\n"));
|
|
33100
|
+
const paths = /* @__PURE__ */ new Set([...kindByPath.keys(), ...numByPath.keys()]);
|
|
33101
|
+
const untracked = String(untrackedRaw).split("\n").map((s) => s.trim()).filter(Boolean);
|
|
33102
|
+
for (const p of untracked) paths.add(p);
|
|
33103
|
+
const rows = [];
|
|
33104
|
+
for (const pathInRepo of paths) {
|
|
33105
|
+
const relLauncher = posixJoinDirFile(repoRelPath, pathInRepo.replace(/\\/g, "/"));
|
|
33106
|
+
const abs = path13.join(repoGitCwd, pathInRepo);
|
|
33107
|
+
const nums = numByPath.get(pathInRepo);
|
|
33108
|
+
let additions = nums?.additions ?? 0;
|
|
33109
|
+
let deletions = nums?.deletions ?? 0;
|
|
33110
|
+
let change = kindByPath.get(pathInRepo) ?? "modified";
|
|
33111
|
+
if (untracked.includes(pathInRepo) && !kindByPath.has(pathInRepo)) {
|
|
33112
|
+
change = "added";
|
|
33113
|
+
const fromGit = await numstatFromGitNoIndex(g, pathInRepo);
|
|
33114
|
+
if (fromGit) {
|
|
33115
|
+
additions = fromGit.additions;
|
|
33116
|
+
deletions = fromGit.deletions;
|
|
33117
|
+
} else {
|
|
33118
|
+
try {
|
|
33119
|
+
const st = await fs11.promises.stat(abs);
|
|
33120
|
+
if (st.isFile()) additions = await countTextFileLines(abs);
|
|
33121
|
+
else additions = 0;
|
|
33122
|
+
} catch {
|
|
33123
|
+
additions = 0;
|
|
33124
|
+
}
|
|
33125
|
+
deletions = 0;
|
|
33126
|
+
}
|
|
33127
|
+
}
|
|
33128
|
+
if (!kindByPath.has(pathInRepo) && nums) {
|
|
33129
|
+
if (additions > 0 && deletions === 0) change = "added";
|
|
33130
|
+
else if (deletions > 0 && additions === 0) change = "removed";
|
|
33131
|
+
else change = "modified";
|
|
33132
|
+
}
|
|
33133
|
+
rows.push({ pathRelLauncher: relLauncher, additions, deletions, change });
|
|
33134
|
+
}
|
|
33135
|
+
const normRel = repoRelPath === "." || repoRelPath === "" ? "." : repoRelPath;
|
|
33136
|
+
for (const row of rows) {
|
|
33137
|
+
let pathInRepo;
|
|
33138
|
+
if (normRel === ".") {
|
|
33139
|
+
pathInRepo = row.pathRelLauncher;
|
|
33140
|
+
} else if (row.pathRelLauncher.startsWith(`${normRel}/`)) {
|
|
33141
|
+
pathInRepo = row.pathRelLauncher.slice(normRel.length + 1);
|
|
33142
|
+
} else {
|
|
33143
|
+
pathInRepo = row.pathRelLauncher;
|
|
33144
|
+
}
|
|
33145
|
+
const absFile = path13.join(repoGitCwd, pathInRepo);
|
|
33146
|
+
let patch = await unifiedDiffForFile(repoGitCwd, pathInRepo, row.change);
|
|
33147
|
+
if (patch) {
|
|
33148
|
+
patch = await hydrateUnifiedPatchWithFileContext(patch, absFile, repoGitCwd, pathInRepo, row.change);
|
|
33149
|
+
}
|
|
33150
|
+
row.patchContent = patch;
|
|
33151
|
+
}
|
|
33152
|
+
return rows;
|
|
33153
|
+
}
|
|
33154
|
+
|
|
33155
|
+
// src/git/working-directory/changes/get-working-tree-change-repo-details.ts
|
|
33156
|
+
function normRepoRel(p) {
|
|
33157
|
+
const x = p.replace(/\\/g, "/").trim();
|
|
33158
|
+
return x === "" ? "." : x;
|
|
33159
|
+
}
|
|
33160
|
+
async function getWorkingTreeChangeRepoDetails(options) {
|
|
33161
|
+
const launcher = path14.resolve(getBridgeWorkspaceDirectory());
|
|
33162
|
+
const mirror = options.agentMirrorRootAbs ? path14.resolve(options.agentMirrorRootAbs) : null;
|
|
33163
|
+
const out = [];
|
|
33164
|
+
const filter = options.repoFilterRelPath != null ? normRepoRel(options.repoFilterRelPath) : null;
|
|
33165
|
+
const basisInput = options.basis ?? { kind: "working" };
|
|
33166
|
+
if (basisInput.kind === "commit" && !filter) {
|
|
33167
|
+
throw new Error("repoFilterRelPath is required for commit changes");
|
|
33168
|
+
}
|
|
33169
|
+
if (basisInput.kind === "commit" && !basisInput.sha.trim()) {
|
|
33170
|
+
throw new Error("commit sha is required for commit changes");
|
|
33171
|
+
}
|
|
33172
|
+
const basis = filter == null && basisInput.kind === "commit" ? { kind: "working" } : basisInput;
|
|
33173
|
+
for (const target of options.commitTargetAbsDirs) {
|
|
33174
|
+
const t = path14.resolve(target);
|
|
33175
|
+
if (!await isGitRepoDirectory(t)) continue;
|
|
33176
|
+
const g = simpleGit(t);
|
|
33177
|
+
let branch = "HEAD";
|
|
33178
|
+
try {
|
|
33179
|
+
branch = (await g.raw(["rev-parse", "--abbrev-ref", "HEAD"])).trim() || "HEAD";
|
|
33180
|
+
} catch {
|
|
33181
|
+
branch = "HEAD";
|
|
33182
|
+
}
|
|
33183
|
+
const remoteUrl = await getRemoteOriginUrl(t);
|
|
33184
|
+
const remoteDisplay = formatRemoteDisplayLabel(remoteUrl);
|
|
33185
|
+
let repoRelPath;
|
|
33186
|
+
if (mirror) {
|
|
33187
|
+
const relNorm = path14.relative(mirror, path14.dirname(t));
|
|
33188
|
+
repoRelPath = relNorm === "" ? "." : relNorm.replace(/\\/g, "/");
|
|
33189
|
+
} else {
|
|
33190
|
+
let top = t;
|
|
33191
|
+
try {
|
|
33192
|
+
top = (await g.raw(["rev-parse", "--show-toplevel"])).trim();
|
|
33193
|
+
} catch {
|
|
33194
|
+
top = t;
|
|
33195
|
+
}
|
|
33196
|
+
const rel = path14.relative(launcher, path14.resolve(top)).replace(/\\/g, "/") || ".";
|
|
33197
|
+
repoRelPath = rel.startsWith("..") ? path14.basename(path14.resolve(top)) : rel;
|
|
33198
|
+
}
|
|
33199
|
+
const norm = normRepoRel(repoRelPath === "" ? "." : repoRelPath);
|
|
33200
|
+
if (filter && norm !== filter) continue;
|
|
33201
|
+
const repoDisplayName = formatRepoShortTitle(remoteUrl, norm === "." ? "." : norm);
|
|
33202
|
+
const relForList = norm === "." ? "." : norm;
|
|
33203
|
+
const files = basis.kind === "commit" ? await listChangedFilesForCommit(t, relForList, basis.sha.trim()) : await listChangedFilesForRepo(t, relForList);
|
|
33204
|
+
const st = await g.status();
|
|
33205
|
+
const hasUncommittedChanges = (st.files?.length ?? 0) > 0;
|
|
33206
|
+
const unpushedCommits = await listUnpushedCommits(t);
|
|
33207
|
+
out.push({
|
|
33208
|
+
repoRelPath: norm,
|
|
33209
|
+
repoDisplayName,
|
|
33210
|
+
branch,
|
|
33211
|
+
remoteUrl,
|
|
33212
|
+
remoteDisplay,
|
|
33213
|
+
files,
|
|
33214
|
+
hasUncommittedChanges,
|
|
33215
|
+
unpushedCommits,
|
|
33216
|
+
changesView: basis.kind === "commit" ? "commit" : "working",
|
|
33217
|
+
changesCommitSha: basis.kind === "commit" ? basis.sha.trim() : null
|
|
33218
|
+
});
|
|
33219
|
+
if (filter) return out;
|
|
33220
|
+
}
|
|
33221
|
+
return out;
|
|
33222
|
+
}
|
|
33223
|
+
|
|
32659
33224
|
// src/git/commit-and-push.ts
|
|
32660
33225
|
async function gitCommitAllIfDirty(repoDir, message, options) {
|
|
32661
33226
|
const g = simpleGit(repoDir);
|
|
@@ -32721,7 +33286,7 @@ var SessionWorktreeManager = class {
|
|
|
32721
33286
|
}
|
|
32722
33287
|
if (!opts.isNewSession) {
|
|
32723
33288
|
const agentCwd = this.sessionAgentCwd.get(sessionId);
|
|
32724
|
-
if (agentCwd) return
|
|
33289
|
+
if (agentCwd) return path15.resolve(agentCwd);
|
|
32725
33290
|
return void 0;
|
|
32726
33291
|
}
|
|
32727
33292
|
const prep = await prepareNewSessionWorktrees({
|
|
@@ -32734,7 +33299,7 @@ var SessionWorktreeManager = class {
|
|
|
32734
33299
|
if (!prep) return void 0;
|
|
32735
33300
|
this.sessionPaths.set(sessionId, prep.worktreePaths);
|
|
32736
33301
|
this.sessionAgentCwd.set(sessionId, prep.agentCwd);
|
|
32737
|
-
return
|
|
33302
|
+
return path15.resolve(prep.agentCwd);
|
|
32738
33303
|
}
|
|
32739
33304
|
async renameSessionBranch(sessionId, newBranch) {
|
|
32740
33305
|
const paths = this.sessionPaths.get(sessionId);
|
|
@@ -32755,7 +33320,7 @@ var SessionWorktreeManager = class {
|
|
|
32755
33320
|
getAgentCwdForSession(sessionId) {
|
|
32756
33321
|
if (!sessionId) return null;
|
|
32757
33322
|
const c = this.sessionAgentCwd.get(sessionId);
|
|
32758
|
-
return c ?
|
|
33323
|
+
return c ? path15.resolve(c) : null;
|
|
32759
33324
|
}
|
|
32760
33325
|
async removeSessionWorktrees(sessionId) {
|
|
32761
33326
|
const paths = this.sessionPaths.get(sessionId);
|
|
@@ -32781,6 +33346,17 @@ var SessionWorktreeManager = class {
|
|
|
32781
33346
|
async getSessionWorkingTreeStatus(sessionId) {
|
|
32782
33347
|
return aggregateSessionPathsWorkingTreeStatus(this.resolveCommitTargets(sessionId));
|
|
32783
33348
|
}
|
|
33349
|
+
/** Per-repo changed files vs HEAD (or a single commit vs parent) for the same git roots used for commit/push. */
|
|
33350
|
+
async getSessionWorkingTreeChangeDetails(sessionId, opts) {
|
|
33351
|
+
const targets = this.resolveCommitTargets(sessionId);
|
|
33352
|
+
const mirror = this.getAgentCwdForSession(sessionId);
|
|
33353
|
+
return getWorkingTreeChangeRepoDetails({
|
|
33354
|
+
commitTargetAbsDirs: targets,
|
|
33355
|
+
agentMirrorRootAbs: mirror,
|
|
33356
|
+
repoFilterRelPath: opts?.repoRelPath?.trim() ? opts.repoRelPath.trim() : null,
|
|
33357
|
+
basis: opts?.basis
|
|
33358
|
+
});
|
|
33359
|
+
}
|
|
32784
33360
|
async pushSessionUpstream(sessionId) {
|
|
32785
33361
|
try {
|
|
32786
33362
|
await pushAheadOfUpstreamForPaths(this.resolveCommitTargets(sessionId));
|
|
@@ -32792,30 +33368,30 @@ var SessionWorktreeManager = class {
|
|
|
32792
33368
|
}
|
|
32793
33369
|
};
|
|
32794
33370
|
function defaultWorktreesRootAbs() {
|
|
32795
|
-
return
|
|
33371
|
+
return path15.join(os3.homedir(), ".buildautomaton", "worktrees");
|
|
32796
33372
|
}
|
|
32797
33373
|
|
|
32798
33374
|
// src/files/watch-file-index.ts
|
|
32799
33375
|
import { watch } from "node:fs";
|
|
32800
|
-
import
|
|
33376
|
+
import path22 from "node:path";
|
|
32801
33377
|
|
|
32802
33378
|
// src/files/index/build-file-index.ts
|
|
32803
|
-
import
|
|
33379
|
+
import path19 from "node:path";
|
|
32804
33380
|
|
|
32805
33381
|
// src/runtime/yield-to-event-loop.ts
|
|
32806
33382
|
function yieldToEventLoop() {
|
|
32807
|
-
return new Promise((
|
|
33383
|
+
return new Promise((resolve16) => setImmediate(resolve16));
|
|
32808
33384
|
}
|
|
32809
33385
|
|
|
32810
33386
|
// src/files/index/walk-workspace-tree.ts
|
|
32811
|
-
import
|
|
32812
|
-
import
|
|
33387
|
+
import fs12 from "node:fs";
|
|
33388
|
+
import path17 from "node:path";
|
|
32813
33389
|
|
|
32814
33390
|
// src/files/index/constants.ts
|
|
32815
|
-
import
|
|
33391
|
+
import path16 from "node:path";
|
|
32816
33392
|
import os4 from "node:os";
|
|
32817
33393
|
var INDEX_WORK_YIELD_EVERY = 256;
|
|
32818
|
-
var INDEX_DIR =
|
|
33394
|
+
var INDEX_DIR = path16.join(os4.homedir(), ".buildautomaton");
|
|
32819
33395
|
var INDEX_HASH_LEN = 16;
|
|
32820
33396
|
var INDEX_VERSION = 2;
|
|
32821
33397
|
var INDEX_LOG_PREFIX = "[file-index]";
|
|
@@ -32824,31 +33400,31 @@ var INDEX_LOG_PREFIX = "[file-index]";
|
|
|
32824
33400
|
function walkWorkspaceTreeSync(dir, baseDir, out) {
|
|
32825
33401
|
let names;
|
|
32826
33402
|
try {
|
|
32827
|
-
names =
|
|
33403
|
+
names = fs12.readdirSync(dir);
|
|
32828
33404
|
} catch {
|
|
32829
33405
|
return;
|
|
32830
33406
|
}
|
|
32831
33407
|
for (const name of names) {
|
|
32832
33408
|
if (name.startsWith(".")) continue;
|
|
32833
|
-
const full =
|
|
33409
|
+
const full = path17.join(dir, name);
|
|
32834
33410
|
let stat2;
|
|
32835
33411
|
try {
|
|
32836
|
-
stat2 =
|
|
33412
|
+
stat2 = fs12.statSync(full);
|
|
32837
33413
|
} catch {
|
|
32838
33414
|
continue;
|
|
32839
33415
|
}
|
|
32840
|
-
const
|
|
33416
|
+
const relative5 = path17.relative(baseDir, full).replace(/\\/g, "/");
|
|
32841
33417
|
if (stat2.isDirectory()) {
|
|
32842
33418
|
walkWorkspaceTreeSync(full, baseDir, out);
|
|
32843
33419
|
} else if (stat2.isFile()) {
|
|
32844
|
-
out.push(
|
|
33420
|
+
out.push(relative5);
|
|
32845
33421
|
}
|
|
32846
33422
|
}
|
|
32847
33423
|
}
|
|
32848
33424
|
async function walkWorkspaceTreeAsync(dir, baseDir, out, state) {
|
|
32849
33425
|
let names;
|
|
32850
33426
|
try {
|
|
32851
|
-
names = await
|
|
33427
|
+
names = await fs12.promises.readdir(dir);
|
|
32852
33428
|
} catch {
|
|
32853
33429
|
return;
|
|
32854
33430
|
}
|
|
@@ -32858,18 +33434,18 @@ async function walkWorkspaceTreeAsync(dir, baseDir, out, state) {
|
|
|
32858
33434
|
await yieldToEventLoop();
|
|
32859
33435
|
}
|
|
32860
33436
|
state.n++;
|
|
32861
|
-
const full =
|
|
33437
|
+
const full = path17.join(dir, name);
|
|
32862
33438
|
let stat2;
|
|
32863
33439
|
try {
|
|
32864
|
-
stat2 = await
|
|
33440
|
+
stat2 = await fs12.promises.stat(full);
|
|
32865
33441
|
} catch {
|
|
32866
33442
|
continue;
|
|
32867
33443
|
}
|
|
32868
|
-
const
|
|
33444
|
+
const relative5 = path17.relative(baseDir, full).replace(/\\/g, "/");
|
|
32869
33445
|
if (stat2.isDirectory()) {
|
|
32870
33446
|
await walkWorkspaceTreeAsync(full, baseDir, out, state);
|
|
32871
33447
|
} else if (stat2.isFile()) {
|
|
32872
|
-
out.push(
|
|
33448
|
+
out.push(relative5);
|
|
32873
33449
|
}
|
|
32874
33450
|
}
|
|
32875
33451
|
}
|
|
@@ -32946,22 +33522,22 @@ async function buildTrigramMapForPathsAsync(paths) {
|
|
|
32946
33522
|
}
|
|
32947
33523
|
|
|
32948
33524
|
// src/files/index/write-index-file.ts
|
|
32949
|
-
import
|
|
33525
|
+
import fs13 from "node:fs";
|
|
32950
33526
|
|
|
32951
33527
|
// src/files/index/paths.ts
|
|
32952
|
-
import
|
|
33528
|
+
import path18 from "node:path";
|
|
32953
33529
|
import crypto2 from "node:crypto";
|
|
32954
33530
|
function getIndexPathForCwd(resolvedCwd) {
|
|
32955
33531
|
const hash = crypto2.createHash("sha256").update(resolvedCwd).digest("hex").slice(0, INDEX_HASH_LEN);
|
|
32956
|
-
return
|
|
33532
|
+
return path18.join(INDEX_DIR, `.file-index-${hash}.json`);
|
|
32957
33533
|
}
|
|
32958
33534
|
|
|
32959
33535
|
// src/files/index/write-index-file.ts
|
|
32960
33536
|
function writeIndexFileSync(resolvedCwd, data) {
|
|
32961
33537
|
const indexPath = getIndexPathForCwd(resolvedCwd);
|
|
32962
33538
|
try {
|
|
32963
|
-
if (!
|
|
32964
|
-
|
|
33539
|
+
if (!fs13.existsSync(INDEX_DIR)) fs13.mkdirSync(INDEX_DIR, { recursive: true });
|
|
33540
|
+
fs13.writeFileSync(indexPath, JSON.stringify(data), "utf8");
|
|
32965
33541
|
} catch (e) {
|
|
32966
33542
|
console.error(`${INDEX_LOG_PREFIX} Failed to write index:`, e);
|
|
32967
33543
|
}
|
|
@@ -32969,8 +33545,8 @@ function writeIndexFileSync(resolvedCwd, data) {
|
|
|
32969
33545
|
async function writeIndexFileAsync(resolvedCwd, data) {
|
|
32970
33546
|
const indexPath = getIndexPathForCwd(resolvedCwd);
|
|
32971
33547
|
try {
|
|
32972
|
-
await
|
|
32973
|
-
await
|
|
33548
|
+
await fs13.promises.mkdir(INDEX_DIR, { recursive: true });
|
|
33549
|
+
await fs13.promises.writeFile(indexPath, JSON.stringify(data), "utf8");
|
|
32974
33550
|
} catch (e) {
|
|
32975
33551
|
console.error(`${INDEX_LOG_PREFIX} Failed to write index:`, e);
|
|
32976
33552
|
}
|
|
@@ -32984,7 +33560,7 @@ function sortPaths(paths) {
|
|
|
32984
33560
|
paths.sort((a, b) => a.localeCompare(b, void 0, { sensitivity: "base" }));
|
|
32985
33561
|
}
|
|
32986
33562
|
function buildFileIndex(cwd) {
|
|
32987
|
-
const resolved =
|
|
33563
|
+
const resolved = path19.resolve(cwd);
|
|
32988
33564
|
const paths = [];
|
|
32989
33565
|
walkWorkspaceTreeSync(resolved, resolved, paths);
|
|
32990
33566
|
sortPaths(paths);
|
|
@@ -32994,7 +33570,7 @@ function buildFileIndex(cwd) {
|
|
|
32994
33570
|
return data;
|
|
32995
33571
|
}
|
|
32996
33572
|
async function buildFileIndexAsync(cwd) {
|
|
32997
|
-
const resolved =
|
|
33573
|
+
const resolved = path19.resolve(cwd);
|
|
32998
33574
|
const paths = [];
|
|
32999
33575
|
await walkWorkspaceTreeAsync(resolved, resolved, paths, createWalkYieldState());
|
|
33000
33576
|
await yieldToEventLoop();
|
|
@@ -33006,13 +33582,13 @@ async function buildFileIndexAsync(cwd) {
|
|
|
33006
33582
|
}
|
|
33007
33583
|
|
|
33008
33584
|
// src/files/index/load-file-index.ts
|
|
33009
|
-
import
|
|
33010
|
-
import
|
|
33585
|
+
import fs14 from "node:fs";
|
|
33586
|
+
import path20 from "node:path";
|
|
33011
33587
|
function loadFileIndex(cwd) {
|
|
33012
|
-
const resolved =
|
|
33588
|
+
const resolved = path20.resolve(cwd);
|
|
33013
33589
|
const indexPath = getIndexPathForCwd(resolved);
|
|
33014
33590
|
try {
|
|
33015
|
-
const raw =
|
|
33591
|
+
const raw = fs14.readFileSync(indexPath, "utf8");
|
|
33016
33592
|
const parsed = JSON.parse(raw);
|
|
33017
33593
|
if (parsed !== null && typeof parsed === "object" && Array.isArray(parsed.paths)) {
|
|
33018
33594
|
const obj = parsed;
|
|
@@ -33031,9 +33607,9 @@ function loadFileIndex(cwd) {
|
|
|
33031
33607
|
}
|
|
33032
33608
|
|
|
33033
33609
|
// src/files/index/ensure-file-index.ts
|
|
33034
|
-
import
|
|
33610
|
+
import path21 from "node:path";
|
|
33035
33611
|
async function ensureFileIndexAsync(cwd) {
|
|
33036
|
-
const resolved =
|
|
33612
|
+
const resolved = path21.resolve(cwd);
|
|
33037
33613
|
const cached2 = loadFileIndex(resolved);
|
|
33038
33614
|
if (cached2 !== null) return { data: cached2, fromCache: true };
|
|
33039
33615
|
const data = await buildFileIndexAsync(resolved);
|
|
@@ -33116,7 +33692,7 @@ function createFsWatcher(resolved, schedule) {
|
|
|
33116
33692
|
}
|
|
33117
33693
|
}
|
|
33118
33694
|
function startFileIndexWatcher(cwd = getBridgeWorkspaceDirectory()) {
|
|
33119
|
-
const resolved =
|
|
33695
|
+
const resolved = path22.resolve(cwd);
|
|
33120
33696
|
void buildFileIndexAsync(resolved).catch((e) => {
|
|
33121
33697
|
console.error("[file-index] Initial index build failed:", e);
|
|
33122
33698
|
});
|
|
@@ -33163,15 +33739,15 @@ function sendDevServerStatus(getWs, serverId, status, options) {
|
|
|
33163
33739
|
|
|
33164
33740
|
// src/dev-servers/process/terminate-child-process.ts
|
|
33165
33741
|
async function sigtermAndWaitForExit(proc, graceMs, log2, shortId) {
|
|
33166
|
-
const exited = new Promise((
|
|
33167
|
-
proc.once("exit", () =>
|
|
33742
|
+
const exited = new Promise((resolve16) => {
|
|
33743
|
+
proc.once("exit", () => resolve16());
|
|
33168
33744
|
});
|
|
33169
33745
|
log2(`[dev-server] Sending SIGTERM to ${shortId} (pid=${proc.pid ?? "?"}).`);
|
|
33170
33746
|
try {
|
|
33171
33747
|
proc.kill("SIGTERM");
|
|
33172
33748
|
} catch {
|
|
33173
33749
|
}
|
|
33174
|
-
await Promise.race([exited, new Promise((
|
|
33750
|
+
await Promise.race([exited, new Promise((resolve16) => setTimeout(resolve16, graceMs))]);
|
|
33175
33751
|
}
|
|
33176
33752
|
function forceKillChild(proc, log2, shortId, graceMs) {
|
|
33177
33753
|
log2(
|
|
@@ -33185,7 +33761,7 @@ function forceKillChild(proc, log2, shortId, graceMs) {
|
|
|
33185
33761
|
}
|
|
33186
33762
|
|
|
33187
33763
|
// src/dev-servers/process/wire-dev-server-child-process.ts
|
|
33188
|
-
import
|
|
33764
|
+
import fs15 from "node:fs";
|
|
33189
33765
|
|
|
33190
33766
|
// src/dev-servers/manager/forward-pipe.ts
|
|
33191
33767
|
function forwardChildPipe(childReadable, terminal, onData) {
|
|
@@ -33221,7 +33797,7 @@ function wireDevServerChildProcess(d) {
|
|
|
33221
33797
|
d.setPollInterval(void 0);
|
|
33222
33798
|
return;
|
|
33223
33799
|
}
|
|
33224
|
-
|
|
33800
|
+
fs15.readFile(d.mergedLogPath, (err, buf) => {
|
|
33225
33801
|
if (err || (d.getSpawnGeneration() ?? 0) !== d.scheduledGen) return;
|
|
33226
33802
|
if (buf.length <= d.mergedReadPos.value) return;
|
|
33227
33803
|
const chunk = Buffer.from(buf.subarray(d.mergedReadPos.value));
|
|
@@ -33259,7 +33835,7 @@ ${errTail}` : ""}`);
|
|
|
33259
33835
|
d.sendStatus(code === 0 || code == null ? "stopped" : "error", detail, tails);
|
|
33260
33836
|
};
|
|
33261
33837
|
if (mergedPath) {
|
|
33262
|
-
|
|
33838
|
+
fs15.readFile(mergedPath, (err, buf) => {
|
|
33263
33839
|
if (!err && buf.length > d.mergedReadPos.value) {
|
|
33264
33840
|
const chunk = Buffer.from(buf.subarray(d.mergedReadPos.value));
|
|
33265
33841
|
if (chunk.length > 0) {
|
|
@@ -33361,13 +33937,13 @@ function parseDevServerDefs(servers) {
|
|
|
33361
33937
|
}
|
|
33362
33938
|
|
|
33363
33939
|
// src/dev-servers/manager/shell-spawn/utils.ts
|
|
33364
|
-
import
|
|
33940
|
+
import fs16 from "node:fs";
|
|
33365
33941
|
function isSpawnEbadf(e) {
|
|
33366
33942
|
return typeof e === "object" && e !== null && "code" in e && e.code === "EBADF";
|
|
33367
33943
|
}
|
|
33368
33944
|
function rmDirQuiet(dir) {
|
|
33369
33945
|
try {
|
|
33370
|
-
|
|
33946
|
+
fs16.rmSync(dir, { recursive: true, force: true });
|
|
33371
33947
|
} catch {
|
|
33372
33948
|
}
|
|
33373
33949
|
}
|
|
@@ -33375,7 +33951,7 @@ var cachedDevNullReadFd;
|
|
|
33375
33951
|
function devNullReadFd() {
|
|
33376
33952
|
if (cachedDevNullReadFd === void 0) {
|
|
33377
33953
|
const devPath = process.platform === "win32" ? "nul" : "/dev/null";
|
|
33378
|
-
cachedDevNullReadFd =
|
|
33954
|
+
cachedDevNullReadFd = fs16.openSync(devPath, "r");
|
|
33379
33955
|
}
|
|
33380
33956
|
return cachedDevNullReadFd;
|
|
33381
33957
|
}
|
|
@@ -33449,15 +34025,15 @@ function trySpawnShellTruePiped(command, env, cwd, devNullFd, signal) {
|
|
|
33449
34025
|
|
|
33450
34026
|
// src/dev-servers/manager/shell-spawn/try-spawn-merged-log-file.ts
|
|
33451
34027
|
import { spawn as spawn6 } from "node:child_process";
|
|
33452
|
-
import
|
|
34028
|
+
import fs17 from "node:fs";
|
|
33453
34029
|
import { tmpdir } from "node:os";
|
|
33454
|
-
import
|
|
34030
|
+
import path23 from "node:path";
|
|
33455
34031
|
function trySpawnMergedLogFile(command, env, cwd, signal) {
|
|
33456
|
-
const tmpRoot =
|
|
33457
|
-
const logPath =
|
|
34032
|
+
const tmpRoot = fs17.mkdtempSync(path23.join(tmpdir(), "ba-devsrv-log-"));
|
|
34033
|
+
const logPath = path23.join(tmpRoot, "combined.log");
|
|
33458
34034
|
let logFd;
|
|
33459
34035
|
try {
|
|
33460
|
-
logFd =
|
|
34036
|
+
logFd = fs17.openSync(logPath, "a");
|
|
33461
34037
|
} catch {
|
|
33462
34038
|
rmDirQuiet(tmpRoot);
|
|
33463
34039
|
return null;
|
|
@@ -33476,7 +34052,7 @@ function trySpawnMergedLogFile(command, env, cwd, signal) {
|
|
|
33476
34052
|
} else {
|
|
33477
34053
|
proc = spawn6("/bin/sh", ["-c", command], { env, cwd, stdio, ...signal ? { signal } : {} });
|
|
33478
34054
|
}
|
|
33479
|
-
|
|
34055
|
+
fs17.closeSync(logFd);
|
|
33480
34056
|
return {
|
|
33481
34057
|
proc,
|
|
33482
34058
|
pipedStdoutStderr: true,
|
|
@@ -33485,7 +34061,7 @@ function trySpawnMergedLogFile(command, env, cwd, signal) {
|
|
|
33485
34061
|
};
|
|
33486
34062
|
} catch (e) {
|
|
33487
34063
|
try {
|
|
33488
|
-
|
|
34064
|
+
fs17.closeSync(logFd);
|
|
33489
34065
|
} catch {
|
|
33490
34066
|
}
|
|
33491
34067
|
rmDirQuiet(tmpRoot);
|
|
@@ -33496,22 +34072,22 @@ function trySpawnMergedLogFile(command, env, cwd, signal) {
|
|
|
33496
34072
|
|
|
33497
34073
|
// src/dev-servers/manager/shell-spawn/try-spawn-shell-script-log-redirect.ts
|
|
33498
34074
|
import { spawn as spawn7 } from "node:child_process";
|
|
33499
|
-
import
|
|
34075
|
+
import fs18 from "node:fs";
|
|
33500
34076
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
33501
|
-
import
|
|
34077
|
+
import path24 from "node:path";
|
|
33502
34078
|
function shSingleQuote(s) {
|
|
33503
34079
|
return `'${s.replace(/'/g, `'\\''`)}'`;
|
|
33504
34080
|
}
|
|
33505
34081
|
function trySpawnShellScriptLogRedirectUnix(command, env, cwd, signal) {
|
|
33506
|
-
const tmpRoot =
|
|
33507
|
-
const logPath =
|
|
33508
|
-
const innerPath =
|
|
33509
|
-
const runnerPath =
|
|
34082
|
+
const tmpRoot = fs18.mkdtempSync(path24.join(tmpdir2(), "ba-devsrv-sh-"));
|
|
34083
|
+
const logPath = path24.join(tmpRoot, "combined.log");
|
|
34084
|
+
const innerPath = path24.join(tmpRoot, "_cmd.sh");
|
|
34085
|
+
const runnerPath = path24.join(tmpRoot, "_run.sh");
|
|
33510
34086
|
try {
|
|
33511
|
-
|
|
34087
|
+
fs18.writeFileSync(innerPath, `#!/bin/sh
|
|
33512
34088
|
${command}
|
|
33513
34089
|
`);
|
|
33514
|
-
|
|
34090
|
+
fs18.writeFileSync(
|
|
33515
34091
|
runnerPath,
|
|
33516
34092
|
`#!/bin/sh
|
|
33517
34093
|
cd ${shSingleQuote(cwd)}
|
|
@@ -33537,13 +34113,13 @@ cd ${shSingleQuote(cwd)}
|
|
|
33537
34113
|
}
|
|
33538
34114
|
}
|
|
33539
34115
|
function trySpawnShellScriptLogRedirectWin(command, env, cwd, signal) {
|
|
33540
|
-
const tmpRoot =
|
|
33541
|
-
const logPath =
|
|
33542
|
-
const runnerPath =
|
|
34116
|
+
const tmpRoot = fs18.mkdtempSync(path24.join(tmpdir2(), "ba-devsrv-sh-"));
|
|
34117
|
+
const logPath = path24.join(tmpRoot, "combined.log");
|
|
34118
|
+
const runnerPath = path24.join(tmpRoot, "_run.bat");
|
|
33543
34119
|
const q = (p) => `"${p.replace(/"/g, '""')}"`;
|
|
33544
34120
|
const com = process.env.ComSpec || "cmd.exe";
|
|
33545
34121
|
try {
|
|
33546
|
-
|
|
34122
|
+
fs18.writeFileSync(
|
|
33547
34123
|
runnerPath,
|
|
33548
34124
|
`@ECHO OFF\r
|
|
33549
34125
|
CD /D ${q(cwd)}\r
|
|
@@ -34012,7 +34588,7 @@ async function proxyToLocal(request) {
|
|
|
34012
34588
|
};
|
|
34013
34589
|
const maxAttempts = isIdempotentProxyMethod(request.method) ? LOCAL_PREVIEW_FETCH_RETRY_DELAYS_MS.length + 1 : 1;
|
|
34014
34590
|
for (let attempt = 0; attempt < maxAttempts; attempt += 1) {
|
|
34015
|
-
const once = await new Promise((
|
|
34591
|
+
const once = await new Promise((resolve16) => {
|
|
34016
34592
|
const req = mod.request(opts, (res) => {
|
|
34017
34593
|
const chunks = [];
|
|
34018
34594
|
res.on("data", (c) => chunks.push(c));
|
|
@@ -34023,7 +34599,7 @@ async function proxyToLocal(request) {
|
|
|
34023
34599
|
if (typeof v === "string") headers[k] = v;
|
|
34024
34600
|
else if (Array.isArray(v) && v[0]) headers[k] = v[0];
|
|
34025
34601
|
}
|
|
34026
|
-
|
|
34602
|
+
resolve16({
|
|
34027
34603
|
id: request.id,
|
|
34028
34604
|
statusCode: res.statusCode ?? 0,
|
|
34029
34605
|
headers,
|
|
@@ -34032,7 +34608,7 @@ async function proxyToLocal(request) {
|
|
|
34032
34608
|
});
|
|
34033
34609
|
});
|
|
34034
34610
|
req.on("error", (err) => {
|
|
34035
|
-
|
|
34611
|
+
resolve16({
|
|
34036
34612
|
id: request.id,
|
|
34037
34613
|
statusCode: 0,
|
|
34038
34614
|
headers: {},
|
|
@@ -34393,30 +34969,30 @@ function createOnBridgeIdentified(opts) {
|
|
|
34393
34969
|
}
|
|
34394
34970
|
|
|
34395
34971
|
// src/skills/discover-local-agent-skills.ts
|
|
34396
|
-
import
|
|
34397
|
-
import
|
|
34972
|
+
import fs19 from "node:fs";
|
|
34973
|
+
import path25 from "node:path";
|
|
34398
34974
|
var SKILL_DISCOVERY_ROOTS = [".agents/skills", ".claude/skills", ".cursor/skills", "skills"];
|
|
34399
34975
|
function discoverLocalSkills(cwd) {
|
|
34400
34976
|
const out = [];
|
|
34401
34977
|
const seenKeys = /* @__PURE__ */ new Set();
|
|
34402
34978
|
for (const rel of SKILL_DISCOVERY_ROOTS) {
|
|
34403
|
-
const base =
|
|
34404
|
-
if (!
|
|
34979
|
+
const base = path25.join(cwd, rel);
|
|
34980
|
+
if (!fs19.existsSync(base) || !fs19.statSync(base).isDirectory()) continue;
|
|
34405
34981
|
let entries = [];
|
|
34406
34982
|
try {
|
|
34407
|
-
entries =
|
|
34983
|
+
entries = fs19.readdirSync(base);
|
|
34408
34984
|
} catch {
|
|
34409
34985
|
continue;
|
|
34410
34986
|
}
|
|
34411
34987
|
for (const name of entries) {
|
|
34412
|
-
const dir =
|
|
34988
|
+
const dir = path25.join(base, name);
|
|
34413
34989
|
try {
|
|
34414
|
-
if (!
|
|
34990
|
+
if (!fs19.statSync(dir).isDirectory()) continue;
|
|
34415
34991
|
} catch {
|
|
34416
34992
|
continue;
|
|
34417
34993
|
}
|
|
34418
|
-
const skillMd =
|
|
34419
|
-
if (!
|
|
34994
|
+
const skillMd = path25.join(dir, "SKILL.md");
|
|
34995
|
+
if (!fs19.existsSync(skillMd)) continue;
|
|
34420
34996
|
const key = `${rel}/${name}`;
|
|
34421
34997
|
if (seenKeys.has(key)) continue;
|
|
34422
34998
|
seenKeys.add(key);
|
|
@@ -34428,23 +35004,23 @@ function discoverLocalSkills(cwd) {
|
|
|
34428
35004
|
function discoverSkillLayoutRoots(cwd) {
|
|
34429
35005
|
const roots = [];
|
|
34430
35006
|
for (const rel of SKILL_DISCOVERY_ROOTS) {
|
|
34431
|
-
const base =
|
|
34432
|
-
if (!
|
|
35007
|
+
const base = path25.join(cwd, rel);
|
|
35008
|
+
if (!fs19.existsSync(base) || !fs19.statSync(base).isDirectory()) continue;
|
|
34433
35009
|
let entries = [];
|
|
34434
35010
|
try {
|
|
34435
|
-
entries =
|
|
35011
|
+
entries = fs19.readdirSync(base);
|
|
34436
35012
|
} catch {
|
|
34437
35013
|
continue;
|
|
34438
35014
|
}
|
|
34439
35015
|
const skills2 = [];
|
|
34440
35016
|
for (const name of entries) {
|
|
34441
|
-
const dir =
|
|
35017
|
+
const dir = path25.join(base, name);
|
|
34442
35018
|
try {
|
|
34443
|
-
if (!
|
|
35019
|
+
if (!fs19.statSync(dir).isDirectory()) continue;
|
|
34444
35020
|
} catch {
|
|
34445
35021
|
continue;
|
|
34446
35022
|
}
|
|
34447
|
-
if (!
|
|
35023
|
+
if (!fs19.existsSync(path25.join(dir, "SKILL.md"))) continue;
|
|
34448
35024
|
const relPath = `${rel}/${name}`.replace(/\\/g, "/");
|
|
34449
35025
|
skills2.push({ name, relPath });
|
|
34450
35026
|
}
|
|
@@ -34589,12 +35165,12 @@ var handleAgentConfigMessage = (msg, deps) => {
|
|
|
34589
35165
|
};
|
|
34590
35166
|
|
|
34591
35167
|
// src/agents/acp/from-bridge/handle-bridge-prompt.ts
|
|
34592
|
-
import * as
|
|
35168
|
+
import * as path27 from "node:path";
|
|
34593
35169
|
import { execFile as execFile5 } from "node:child_process";
|
|
34594
35170
|
import { promisify as promisify5 } from "node:util";
|
|
34595
35171
|
|
|
34596
35172
|
// src/git/bridge-queue-key.ts
|
|
34597
|
-
import * as
|
|
35173
|
+
import * as path26 from "node:path";
|
|
34598
35174
|
import { createHash } from "node:crypto";
|
|
34599
35175
|
function normalizeCanonicalGitUrl(url2) {
|
|
34600
35176
|
let s = url2.trim();
|
|
@@ -34622,11 +35198,11 @@ function canonicalUrlToRepoIdSync(url2) {
|
|
|
34622
35198
|
return createHash("sha256").update(normalized).digest("hex").slice(0, 32);
|
|
34623
35199
|
}
|
|
34624
35200
|
function fallbackRepoIdFromPath(absPath) {
|
|
34625
|
-
return createHash("sha256").update(
|
|
35201
|
+
return createHash("sha256").update(path26.resolve(absPath)).digest("hex").slice(0, 32);
|
|
34626
35202
|
}
|
|
34627
35203
|
async function resolveBridgeQueueBindFields(options) {
|
|
34628
35204
|
const { effectiveCwd, worktreePaths, primaryRepoRoots, log: log2 } = options;
|
|
34629
|
-
const cwdAbs = worktreePaths.length > 0 ?
|
|
35205
|
+
const cwdAbs = worktreePaths.length > 0 ? path26.resolve(worktreePaths[0]) : path26.resolve(effectiveCwd);
|
|
34630
35206
|
if (!primaryRepoRoots.length) {
|
|
34631
35207
|
log2("[Bridge service] Prompt queue bind skipped: no Git repository roots under the working directory.");
|
|
34632
35208
|
return null;
|
|
@@ -34691,7 +35267,7 @@ function handleBridgePrompt(msg, deps) {
|
|
|
34691
35267
|
};
|
|
34692
35268
|
async function preambleAndPrompt(resolvedCwd) {
|
|
34693
35269
|
const s = getWs();
|
|
34694
|
-
const effectiveCwd =
|
|
35270
|
+
const effectiveCwd = path27.resolve(resolvedCwd ?? getBridgeWorkspaceDirectory());
|
|
34695
35271
|
const worktreePaths = sessionWorktreeManager.getWorktreePathsForSession(sessionId) ?? [];
|
|
34696
35272
|
const repoRoots = await resolveSnapshotRepoRoots({
|
|
34697
35273
|
worktreePaths,
|
|
@@ -34814,8 +35390,8 @@ function randomSecret() {
|
|
|
34814
35390
|
}
|
|
34815
35391
|
return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
34816
35392
|
}
|
|
34817
|
-
async function requestPreviewApi(port, secret, method,
|
|
34818
|
-
const url2 = `http://127.0.0.1:${port}${
|
|
35393
|
+
async function requestPreviewApi(port, secret, method, path32, body) {
|
|
35394
|
+
const url2 = `http://127.0.0.1:${port}${path32}`;
|
|
34819
35395
|
const headers = {
|
|
34820
35396
|
[PREVIEW_SECRET_HEADER]: secret,
|
|
34821
35397
|
"Content-Type": "application/json"
|
|
@@ -34827,7 +35403,7 @@ async function requestPreviewApi(port, secret, method, path30, body) {
|
|
|
34827
35403
|
});
|
|
34828
35404
|
const data = await res.json().catch(() => ({}));
|
|
34829
35405
|
if (!res.ok) {
|
|
34830
|
-
throw new Error(data?.error ?? `Preview API ${method} ${
|
|
35406
|
+
throw new Error(data?.error ?? `Preview API ${method} ${path32}: ${res.status}`);
|
|
34831
35407
|
}
|
|
34832
35408
|
return data;
|
|
34833
35409
|
}
|
|
@@ -34990,15 +35566,15 @@ var handleSkillCallMessage = (msg, { getWs, log: log2 }) => {
|
|
|
34990
35566
|
};
|
|
34991
35567
|
|
|
34992
35568
|
// src/files/list-dir.ts
|
|
34993
|
-
import
|
|
34994
|
-
import
|
|
35569
|
+
import fs20 from "node:fs";
|
|
35570
|
+
import path29 from "node:path";
|
|
34995
35571
|
|
|
34996
35572
|
// src/files/ensure-under-cwd.ts
|
|
34997
|
-
import
|
|
35573
|
+
import path28 from "node:path";
|
|
34998
35574
|
function ensureUnderCwd(relativePath, cwd = getBridgeWorkspaceDirectory()) {
|
|
34999
|
-
const normalized =
|
|
35000
|
-
const resolved =
|
|
35001
|
-
if (!resolved.startsWith(cwd +
|
|
35575
|
+
const normalized = path28.normalize(relativePath).replace(/^(\.\/)+/, "");
|
|
35576
|
+
const resolved = path28.resolve(cwd, normalized);
|
|
35577
|
+
if (!resolved.startsWith(cwd + path28.sep) && resolved !== cwd) {
|
|
35002
35578
|
return null;
|
|
35003
35579
|
}
|
|
35004
35580
|
return resolved;
|
|
@@ -35012,7 +35588,7 @@ async function listDirAsync(relativePath) {
|
|
|
35012
35588
|
return { error: "Path is outside working directory" };
|
|
35013
35589
|
}
|
|
35014
35590
|
try {
|
|
35015
|
-
const names = await
|
|
35591
|
+
const names = await fs20.promises.readdir(resolved, { withFileTypes: true });
|
|
35016
35592
|
const visible = names.filter((d) => !d.name.startsWith("."));
|
|
35017
35593
|
const entries = [];
|
|
35018
35594
|
for (let i = 0; i < visible.length; i++) {
|
|
@@ -35020,12 +35596,12 @@ async function listDirAsync(relativePath) {
|
|
|
35020
35596
|
await yieldToEventLoop();
|
|
35021
35597
|
}
|
|
35022
35598
|
const d = visible[i];
|
|
35023
|
-
const entryPath =
|
|
35024
|
-
const fullPath =
|
|
35599
|
+
const entryPath = path29.join(relativePath || ".", d.name).replace(/\\/g, "/");
|
|
35600
|
+
const fullPath = path29.join(resolved, d.name);
|
|
35025
35601
|
let isDir = d.isDirectory();
|
|
35026
35602
|
if (d.isSymbolicLink()) {
|
|
35027
35603
|
try {
|
|
35028
|
-
const targetStat = await
|
|
35604
|
+
const targetStat = await fs20.promises.stat(fullPath);
|
|
35029
35605
|
isDir = targetStat.isDirectory();
|
|
35030
35606
|
} catch {
|
|
35031
35607
|
isDir = false;
|
|
@@ -35050,25 +35626,25 @@ async function listDirAsync(relativePath) {
|
|
|
35050
35626
|
}
|
|
35051
35627
|
|
|
35052
35628
|
// src/files/read-file.ts
|
|
35053
|
-
import
|
|
35629
|
+
import fs21 from "node:fs";
|
|
35054
35630
|
import { StringDecoder } from "node:string_decoder";
|
|
35055
35631
|
function resolveFilePath(relativePath) {
|
|
35056
35632
|
const resolved = ensureUnderCwd(relativePath, getBridgeWorkspaceDirectory());
|
|
35057
35633
|
if (!resolved) return { error: "Path is outside working directory" };
|
|
35058
35634
|
let real;
|
|
35059
35635
|
try {
|
|
35060
|
-
real =
|
|
35636
|
+
real = fs21.realpathSync(resolved);
|
|
35061
35637
|
} catch {
|
|
35062
35638
|
real = resolved;
|
|
35063
35639
|
}
|
|
35064
|
-
const stat2 =
|
|
35640
|
+
const stat2 = fs21.statSync(real);
|
|
35065
35641
|
if (!stat2.isFile()) return { error: "Not a file" };
|
|
35066
35642
|
return real;
|
|
35067
35643
|
}
|
|
35068
35644
|
var LINE_CHUNK_SIZE = 64 * 1024;
|
|
35069
35645
|
function readFileRange(filePath, startLine, endLine, lineOffsetIn, lineChunkSize = LINE_CHUNK_SIZE) {
|
|
35070
|
-
const fileSize =
|
|
35071
|
-
const fd =
|
|
35646
|
+
const fileSize = fs21.statSync(filePath).size;
|
|
35647
|
+
const fd = fs21.openSync(filePath, "r");
|
|
35072
35648
|
const bufSize = 64 * 1024;
|
|
35073
35649
|
const buf = Buffer.alloc(bufSize);
|
|
35074
35650
|
const decoder = new StringDecoder("utf8");
|
|
@@ -35081,7 +35657,7 @@ function readFileRange(filePath, startLine, endLine, lineOffsetIn, lineChunkSize
|
|
|
35081
35657
|
let line0Accum = "";
|
|
35082
35658
|
try {
|
|
35083
35659
|
let bytesRead;
|
|
35084
|
-
while (!done && (bytesRead =
|
|
35660
|
+
while (!done && (bytesRead = fs21.readSync(fd, buf, 0, bufSize, null)) > 0) {
|
|
35085
35661
|
const text = partial2 + decoder.write(buf.subarray(0, bytesRead));
|
|
35086
35662
|
partial2 = "";
|
|
35087
35663
|
let lineStart = 0;
|
|
@@ -35216,7 +35792,7 @@ function readFileRange(filePath, startLine, endLine, lineOffsetIn, lineChunkSize
|
|
|
35216
35792
|
}
|
|
35217
35793
|
return { content: resultLines.join("\n"), size: fileSize };
|
|
35218
35794
|
} finally {
|
|
35219
|
-
|
|
35795
|
+
fs21.closeSync(fd);
|
|
35220
35796
|
}
|
|
35221
35797
|
}
|
|
35222
35798
|
function readFile2(relativePath, startLine, endLine, lineOffset, lineChunkSize = LINE_CHUNK_SIZE) {
|
|
@@ -35227,8 +35803,8 @@ function readFile2(relativePath, startLine, endLine, lineOffset, lineChunkSize =
|
|
|
35227
35803
|
if (hasRange) {
|
|
35228
35804
|
return readFileRange(result, startLine, endLine, lineOffset, lineChunkSize);
|
|
35229
35805
|
}
|
|
35230
|
-
const stat2 =
|
|
35231
|
-
const raw =
|
|
35806
|
+
const stat2 = fs21.statSync(result);
|
|
35807
|
+
const raw = fs21.readFileSync(result, "utf8");
|
|
35232
35808
|
const lines = raw.split(/\r?\n/);
|
|
35233
35809
|
return { content: raw, totalLines: lines.length, size: stat2.size };
|
|
35234
35810
|
} catch (err) {
|
|
@@ -35338,10 +35914,10 @@ function handleSkillLayoutRequest(msg, deps) {
|
|
|
35338
35914
|
}
|
|
35339
35915
|
|
|
35340
35916
|
// src/skills/install-remote-skills.ts
|
|
35341
|
-
import
|
|
35342
|
-
import
|
|
35917
|
+
import fs22 from "node:fs";
|
|
35918
|
+
import path30 from "node:path";
|
|
35343
35919
|
function installRemoteSkills(cwd, targetDir, items) {
|
|
35344
|
-
const
|
|
35920
|
+
const installed2 = [];
|
|
35345
35921
|
if (!Array.isArray(items)) {
|
|
35346
35922
|
return { success: false, error: "Invalid items" };
|
|
35347
35923
|
}
|
|
@@ -35350,24 +35926,24 @@ function installRemoteSkills(cwd, targetDir, items) {
|
|
|
35350
35926
|
if (typeof item.sourceId !== "string" || typeof item.skillName !== "string" || typeof item.versionHash !== "string" || !Array.isArray(item.files)) {
|
|
35351
35927
|
continue;
|
|
35352
35928
|
}
|
|
35353
|
-
const skillDir =
|
|
35929
|
+
const skillDir = path30.join(cwd, targetDir, item.skillName);
|
|
35354
35930
|
for (const f of item.files) {
|
|
35355
35931
|
if (typeof f.path !== "string" || !f.text && !f.base64) continue;
|
|
35356
|
-
const dest =
|
|
35357
|
-
|
|
35932
|
+
const dest = path30.join(skillDir, f.path);
|
|
35933
|
+
fs22.mkdirSync(path30.dirname(dest), { recursive: true });
|
|
35358
35934
|
if (f.text !== void 0) {
|
|
35359
|
-
|
|
35935
|
+
fs22.writeFileSync(dest, f.text, "utf8");
|
|
35360
35936
|
} else if (f.base64) {
|
|
35361
|
-
|
|
35937
|
+
fs22.writeFileSync(dest, Buffer.from(f.base64, "base64"));
|
|
35362
35938
|
}
|
|
35363
35939
|
}
|
|
35364
|
-
|
|
35940
|
+
installed2.push({
|
|
35365
35941
|
sourceId: item.sourceId,
|
|
35366
35942
|
skillName: item.skillName,
|
|
35367
35943
|
versionHash: item.versionHash
|
|
35368
35944
|
});
|
|
35369
35945
|
}
|
|
35370
|
-
return { success: true, installed };
|
|
35946
|
+
return { success: true, installed: installed2 };
|
|
35371
35947
|
} catch (e) {
|
|
35372
35948
|
return { success: false, error: e instanceof Error ? e.message : String(e) };
|
|
35373
35949
|
}
|
|
@@ -35404,7 +35980,8 @@ var handleSessionGitRequestMessage = (msg, deps) => {
|
|
|
35404
35980
|
if (typeof msg.id !== "string") return;
|
|
35405
35981
|
const sessionId = typeof msg.sessionId === "string" ? msg.sessionId : "";
|
|
35406
35982
|
const action = msg.action;
|
|
35407
|
-
if (!sessionId || action !== "status" && action !== "push" && action !== "commit")
|
|
35983
|
+
if (!sessionId || action !== "status" && action !== "push" && action !== "commit" && action !== "list_changes")
|
|
35984
|
+
return;
|
|
35408
35985
|
void (async () => {
|
|
35409
35986
|
const ws = deps.getWs();
|
|
35410
35987
|
const reply = (payload) => sendResult(ws, msg.id, payload);
|
|
@@ -35418,6 +35995,24 @@ var handleSessionGitRequestMessage = (msg, deps) => {
|
|
|
35418
35995
|
});
|
|
35419
35996
|
return;
|
|
35420
35997
|
}
|
|
35998
|
+
if (action === "list_changes") {
|
|
35999
|
+
const repoRel = typeof msg.changesRepoRelPath === "string" ? msg.changesRepoRelPath.trim() : "";
|
|
36000
|
+
const view = msg.changesView === "commit" ? "commit" : "working";
|
|
36001
|
+
const commitSha = typeof msg.changesCommitSha === "string" ? msg.changesCommitSha.trim() : "";
|
|
36002
|
+
if (view === "commit") {
|
|
36003
|
+
if (!repoRel || !commitSha) {
|
|
36004
|
+
reply({ ok: false, error: "changesRepoRelPath and changesCommitSha are required for commit view" });
|
|
36005
|
+
return;
|
|
36006
|
+
}
|
|
36007
|
+
}
|
|
36008
|
+
const opts = repoRel && view === "commit" && commitSha ? { repoRelPath: repoRel, basis: { kind: "commit", sha: commitSha } } : repoRel ? { repoRelPath: repoRel, basis: { kind: "working" } } : void 0;
|
|
36009
|
+
const repos = await deps.sessionWorktreeManager.getSessionWorkingTreeChangeDetails(sessionId, opts);
|
|
36010
|
+
reply({
|
|
36011
|
+
ok: true,
|
|
36012
|
+
repos
|
|
36013
|
+
});
|
|
36014
|
+
return;
|
|
36015
|
+
}
|
|
35421
36016
|
if (action === "push") {
|
|
35422
36017
|
const pushRes = await deps.sessionWorktreeManager.pushSessionUpstream(sessionId);
|
|
35423
36018
|
if (!pushRes.ok) {
|
|
@@ -35484,7 +36079,7 @@ var handleSessionDiscardedMessage = (msg, deps) => {
|
|
|
35484
36079
|
};
|
|
35485
36080
|
|
|
35486
36081
|
// src/bridge/routing/handlers/revert-turn-snapshot.ts
|
|
35487
|
-
import * as
|
|
36082
|
+
import * as fs23 from "node:fs";
|
|
35488
36083
|
var handleRevertTurnSnapshotMessage = (msg, deps) => {
|
|
35489
36084
|
const id = typeof msg.id === "string" ? msg.id : "";
|
|
35490
36085
|
const sessionId = typeof msg.sessionId === "string" ? msg.sessionId : "";
|
|
@@ -35496,7 +36091,7 @@ var handleRevertTurnSnapshotMessage = (msg, deps) => {
|
|
|
35496
36091
|
if (!s) return;
|
|
35497
36092
|
const agentBase = sessionWorktreeManager.getAgentCwdForSession(sessionId) ?? getBridgeWorkspaceDirectory();
|
|
35498
36093
|
const file2 = snapshotFilePath(agentBase, turnId);
|
|
35499
|
-
if (!
|
|
36094
|
+
if (!fs23.existsSync(file2)) {
|
|
35500
36095
|
sendWsMessage(s, {
|
|
35501
36096
|
type: "revert_turn_snapshot_result",
|
|
35502
36097
|
id,
|
|
@@ -35825,6 +36420,7 @@ async function createBridgeConnection(options) {
|
|
|
35825
36420
|
|
|
35826
36421
|
// src/run-bridge.ts
|
|
35827
36422
|
async function runBridge(options) {
|
|
36423
|
+
installBridgeProcessResilience();
|
|
35828
36424
|
const { apiUrl, workspaceId, authToken, refreshToken, bridgeName, justAuthenticated, worktreesRootAbs } = options;
|
|
35829
36425
|
const firehoseServerUrl = options.firehoseServerUrl ?? options.proxyServerUrl;
|
|
35830
36426
|
const hasAuth = workspaceId && authToken;
|
|
@@ -35936,9 +36532,9 @@ async function main() {
|
|
|
35936
36532
|
let authToken = opts.token;
|
|
35937
36533
|
const firehoseServerUrl = opts.firehoseUrl ?? opts.proxyUrl ?? process.env.BUILDAMATON_FIREHOSE_URL ?? process.env.BUILDAMATON_PROXY_URL ?? DEFAULT_FIREHOSE_URL;
|
|
35938
36534
|
if (opts.cwd && typeof opts.cwd === "string" && opts.cwd.trim()) {
|
|
35939
|
-
const resolvedCwd =
|
|
36535
|
+
const resolvedCwd = path31.resolve(process.cwd(), opts.cwd.trim());
|
|
35940
36536
|
try {
|
|
35941
|
-
const st =
|
|
36537
|
+
const st = fs24.statSync(resolvedCwd);
|
|
35942
36538
|
if (!st.isDirectory()) {
|
|
35943
36539
|
console.error(`--cwd is not a directory: ${resolvedCwd}`);
|
|
35944
36540
|
process.exit(1);
|
|
@@ -35952,7 +36548,7 @@ async function main() {
|
|
|
35952
36548
|
initBridgeWorkspaceDirectory();
|
|
35953
36549
|
let worktreesRootAbs;
|
|
35954
36550
|
if (opts.worktreesRoot && opts.worktreesRoot.trim()) {
|
|
35955
|
-
worktreesRootAbs =
|
|
36551
|
+
worktreesRootAbs = path31.resolve(opts.worktreesRoot.trim());
|
|
35956
36552
|
}
|
|
35957
36553
|
let refreshToken;
|
|
35958
36554
|
if ((!workspaceId || !authToken) && opts.config !== false) {
|