@buildautomaton/cli 0.1.13 → 0.1.15
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 +1508 -384
- package/dist/cli.js.map +4 -4
- package/dist/index.js +1455 -331
- package/dist/index.js.map +4 -4
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -3179,7 +3179,7 @@ var require_stream = __commonJS({
|
|
|
3179
3179
|
};
|
|
3180
3180
|
duplex._final = function(callback) {
|
|
3181
3181
|
if (ws.readyState === ws.CONNECTING) {
|
|
3182
|
-
ws.once("open", function
|
|
3182
|
+
ws.once("open", function open2() {
|
|
3183
3183
|
duplex._final(callback);
|
|
3184
3184
|
});
|
|
3185
3185
|
return;
|
|
@@ -3200,7 +3200,7 @@ var require_stream = __commonJS({
|
|
|
3200
3200
|
};
|
|
3201
3201
|
duplex._write = function(chunk, encoding, callback) {
|
|
3202
3202
|
if (ws.readyState === ws.CONNECTING) {
|
|
3203
|
-
ws.once("open", function
|
|
3203
|
+
ws.once("open", function open2() {
|
|
3204
3204
|
duplex._write(chunk, encoding, callback);
|
|
3205
3205
|
});
|
|
3206
3206
|
return;
|
|
@@ -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: path32, errorMaps, issueData } = params;
|
|
4069
|
+
const fullPath = [...path32, ...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, path32, key) {
|
|
4378
4378
|
this._cachedPath = [];
|
|
4379
4379
|
this.parent = parent;
|
|
4380
4380
|
this.data = value;
|
|
4381
|
-
this._path =
|
|
4381
|
+
this._path = path32;
|
|
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, path32) {
|
|
7997
|
+
if (!path32)
|
|
7998
7998
|
return obj;
|
|
7999
|
-
return
|
|
7999
|
+
return path32.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(path32, 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(path32);
|
|
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, path32 = []) => {
|
|
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 = [...path32, ...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(path32) {
|
|
8482
8482
|
const segs = [];
|
|
8483
|
-
for (const seg of
|
|
8483
|
+
for (const seg of path32) {
|
|
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;
|
|
@@ -21669,7 +21669,7 @@ var require_has_flag = __commonJS({
|
|
|
21669
21669
|
var require_supports_color = __commonJS({
|
|
21670
21670
|
"../../node_modules/.pnpm/supports-color@7.2.0/node_modules/supports-color/index.js"(exports, module) {
|
|
21671
21671
|
"use strict";
|
|
21672
|
-
var
|
|
21672
|
+
var os6 = __require("os");
|
|
21673
21673
|
var tty = __require("tty");
|
|
21674
21674
|
var hasFlag = require_has_flag();
|
|
21675
21675
|
var { env } = process;
|
|
@@ -21717,7 +21717,7 @@ var require_supports_color = __commonJS({
|
|
|
21717
21717
|
return min;
|
|
21718
21718
|
}
|
|
21719
21719
|
if (process.platform === "win32") {
|
|
21720
|
-
const osRelease =
|
|
21720
|
+
const osRelease = os6.release().split(".");
|
|
21721
21721
|
if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
|
|
21722
21722
|
return Number(osRelease[2]) >= 14931 ? 3 : 2;
|
|
21723
21723
|
}
|
|
@@ -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(path32, isFile, isDirectory) {
|
|
21967
|
+
log2(`checking %s`, path32);
|
|
21968
21968
|
try {
|
|
21969
|
-
const stat2 = fs_1.statSync(
|
|
21969
|
+
const stat2 = fs_1.statSync(path32);
|
|
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(path32, type = exports.READABLE) {
|
|
21990
|
+
return check2(path32, (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, path32, body) {
|
|
22806
|
+
const url2 = `http://127.0.0.1:${port}${path32}`;
|
|
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} ${path32}: ${res.status}`);
|
|
22819
22819
|
}
|
|
22820
22820
|
return data;
|
|
22821
22821
|
}
|
|
@@ -23027,8 +23027,534 @@ 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
|
+
|
|
23043
|
+
// ../../node_modules/.pnpm/open@10.2.0/node_modules/open/index.js
|
|
23044
|
+
import process7 from "node:process";
|
|
23045
|
+
import { Buffer as Buffer2 } from "node:buffer";
|
|
23046
|
+
import path4 from "node:path";
|
|
23047
|
+
import { fileURLToPath } from "node:url";
|
|
23048
|
+
import { promisify as promisify5 } from "node:util";
|
|
23049
|
+
import childProcess from "node:child_process";
|
|
23050
|
+
import fs6, { constants as fsConstants2 } from "node:fs/promises";
|
|
23051
|
+
|
|
23052
|
+
// ../../node_modules/.pnpm/wsl-utils@0.1.0/node_modules/wsl-utils/index.js
|
|
23053
|
+
import process3 from "node:process";
|
|
23054
|
+
import fs5, { constants as fsConstants } from "node:fs/promises";
|
|
23055
|
+
|
|
23056
|
+
// ../../node_modules/.pnpm/is-wsl@3.1.1/node_modules/is-wsl/index.js
|
|
23057
|
+
import process2 from "node:process";
|
|
23058
|
+
import os2 from "node:os";
|
|
23059
|
+
import fs4 from "node:fs";
|
|
23060
|
+
|
|
23061
|
+
// ../../node_modules/.pnpm/is-inside-container@1.0.0/node_modules/is-inside-container/index.js
|
|
23062
|
+
import fs3 from "node:fs";
|
|
23063
|
+
|
|
23064
|
+
// ../../node_modules/.pnpm/is-docker@3.0.0/node_modules/is-docker/index.js
|
|
23065
|
+
import fs2 from "node:fs";
|
|
23066
|
+
var isDockerCached;
|
|
23067
|
+
function hasDockerEnv() {
|
|
23068
|
+
try {
|
|
23069
|
+
fs2.statSync("/.dockerenv");
|
|
23070
|
+
return true;
|
|
23071
|
+
} catch {
|
|
23072
|
+
return false;
|
|
23073
|
+
}
|
|
23074
|
+
}
|
|
23075
|
+
function hasDockerCGroup() {
|
|
23076
|
+
try {
|
|
23077
|
+
return fs2.readFileSync("/proc/self/cgroup", "utf8").includes("docker");
|
|
23078
|
+
} catch {
|
|
23079
|
+
return false;
|
|
23080
|
+
}
|
|
23081
|
+
}
|
|
23082
|
+
function isDocker() {
|
|
23083
|
+
if (isDockerCached === void 0) {
|
|
23084
|
+
isDockerCached = hasDockerEnv() || hasDockerCGroup();
|
|
23085
|
+
}
|
|
23086
|
+
return isDockerCached;
|
|
23087
|
+
}
|
|
23088
|
+
|
|
23089
|
+
// ../../node_modules/.pnpm/is-inside-container@1.0.0/node_modules/is-inside-container/index.js
|
|
23090
|
+
var cachedResult;
|
|
23091
|
+
var hasContainerEnv = () => {
|
|
23092
|
+
try {
|
|
23093
|
+
fs3.statSync("/run/.containerenv");
|
|
23094
|
+
return true;
|
|
23095
|
+
} catch {
|
|
23096
|
+
return false;
|
|
23097
|
+
}
|
|
23098
|
+
};
|
|
23099
|
+
function isInsideContainer() {
|
|
23100
|
+
if (cachedResult === void 0) {
|
|
23101
|
+
cachedResult = hasContainerEnv() || isDocker();
|
|
23102
|
+
}
|
|
23103
|
+
return cachedResult;
|
|
23104
|
+
}
|
|
23105
|
+
|
|
23106
|
+
// ../../node_modules/.pnpm/is-wsl@3.1.1/node_modules/is-wsl/index.js
|
|
23107
|
+
var isWsl = () => {
|
|
23108
|
+
if (process2.platform !== "linux") {
|
|
23109
|
+
return false;
|
|
23110
|
+
}
|
|
23111
|
+
if (os2.release().toLowerCase().includes("microsoft")) {
|
|
23112
|
+
if (isInsideContainer()) {
|
|
23113
|
+
return false;
|
|
23114
|
+
}
|
|
23115
|
+
return true;
|
|
23116
|
+
}
|
|
23117
|
+
try {
|
|
23118
|
+
if (fs4.readFileSync("/proc/version", "utf8").toLowerCase().includes("microsoft")) {
|
|
23119
|
+
return !isInsideContainer();
|
|
23120
|
+
}
|
|
23121
|
+
} catch {
|
|
23122
|
+
}
|
|
23123
|
+
if (fs4.existsSync("/proc/sys/fs/binfmt_misc/WSLInterop") || fs4.existsSync("/run/WSL")) {
|
|
23124
|
+
return !isInsideContainer();
|
|
23125
|
+
}
|
|
23126
|
+
return false;
|
|
23127
|
+
};
|
|
23128
|
+
var is_wsl_default = process2.env.__IS_WSL_TEST__ ? isWsl : isWsl();
|
|
23129
|
+
|
|
23130
|
+
// ../../node_modules/.pnpm/wsl-utils@0.1.0/node_modules/wsl-utils/index.js
|
|
23131
|
+
var wslDrivesMountPoint = /* @__PURE__ */ (() => {
|
|
23132
|
+
const defaultMountPoint = "/mnt/";
|
|
23133
|
+
let mountPoint;
|
|
23134
|
+
return async function() {
|
|
23135
|
+
if (mountPoint) {
|
|
23136
|
+
return mountPoint;
|
|
23137
|
+
}
|
|
23138
|
+
const configFilePath2 = "/etc/wsl.conf";
|
|
23139
|
+
let isConfigFileExists = false;
|
|
23140
|
+
try {
|
|
23141
|
+
await fs5.access(configFilePath2, fsConstants.F_OK);
|
|
23142
|
+
isConfigFileExists = true;
|
|
23143
|
+
} catch {
|
|
23144
|
+
}
|
|
23145
|
+
if (!isConfigFileExists) {
|
|
23146
|
+
return defaultMountPoint;
|
|
23147
|
+
}
|
|
23148
|
+
const configContent = await fs5.readFile(configFilePath2, { encoding: "utf8" });
|
|
23149
|
+
const configMountPoint = /(?<!#.*)root\s*=\s*(?<mountPoint>.*)/g.exec(configContent);
|
|
23150
|
+
if (!configMountPoint) {
|
|
23151
|
+
return defaultMountPoint;
|
|
23152
|
+
}
|
|
23153
|
+
mountPoint = configMountPoint.groups.mountPoint.trim();
|
|
23154
|
+
mountPoint = mountPoint.endsWith("/") ? mountPoint : `${mountPoint}/`;
|
|
23155
|
+
return mountPoint;
|
|
23156
|
+
};
|
|
23157
|
+
})();
|
|
23158
|
+
var powerShellPathFromWsl = async () => {
|
|
23159
|
+
const mountPoint = await wslDrivesMountPoint();
|
|
23160
|
+
return `${mountPoint}c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe`;
|
|
23161
|
+
};
|
|
23162
|
+
var powerShellPath = async () => {
|
|
23163
|
+
if (is_wsl_default) {
|
|
23164
|
+
return powerShellPathFromWsl();
|
|
23165
|
+
}
|
|
23166
|
+
return `${process3.env.SYSTEMROOT || process3.env.windir || String.raw`C:\Windows`}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe`;
|
|
23167
|
+
};
|
|
23168
|
+
|
|
23169
|
+
// ../../node_modules/.pnpm/define-lazy-prop@3.0.0/node_modules/define-lazy-prop/index.js
|
|
23170
|
+
function defineLazyProperty(object2, propertyName, valueGetter) {
|
|
23171
|
+
const define = (value) => Object.defineProperty(object2, propertyName, { value, enumerable: true, writable: true });
|
|
23172
|
+
Object.defineProperty(object2, propertyName, {
|
|
23173
|
+
configurable: true,
|
|
23174
|
+
enumerable: true,
|
|
23175
|
+
get() {
|
|
23176
|
+
const result = valueGetter();
|
|
23177
|
+
define(result);
|
|
23178
|
+
return result;
|
|
23179
|
+
},
|
|
23180
|
+
set(value) {
|
|
23181
|
+
define(value);
|
|
23182
|
+
}
|
|
23183
|
+
});
|
|
23184
|
+
return object2;
|
|
23185
|
+
}
|
|
23186
|
+
|
|
23187
|
+
// ../../node_modules/.pnpm/default-browser@5.5.0/node_modules/default-browser/index.js
|
|
23188
|
+
import { promisify as promisify4 } from "node:util";
|
|
23189
|
+
import process6 from "node:process";
|
|
23190
|
+
import { execFile as execFile4 } from "node:child_process";
|
|
23191
|
+
|
|
23192
|
+
// ../../node_modules/.pnpm/default-browser-id@5.0.1/node_modules/default-browser-id/index.js
|
|
23193
|
+
import { promisify } from "node:util";
|
|
23194
|
+
import process4 from "node:process";
|
|
23195
|
+
import { execFile } from "node:child_process";
|
|
23196
|
+
var execFileAsync = promisify(execFile);
|
|
23197
|
+
async function defaultBrowserId() {
|
|
23198
|
+
if (process4.platform !== "darwin") {
|
|
23199
|
+
throw new Error("macOS only");
|
|
23200
|
+
}
|
|
23201
|
+
const { stdout } = await execFileAsync("defaults", ["read", "com.apple.LaunchServices/com.apple.launchservices.secure", "LSHandlers"]);
|
|
23202
|
+
const match = /LSHandlerRoleAll = "(?!-)(?<id>[^"]+?)";\s+?LSHandlerURLScheme = (?:http|https);/.exec(stdout);
|
|
23203
|
+
const browserId = match?.groups.id ?? "com.apple.Safari";
|
|
23204
|
+
if (browserId === "com.apple.safari") {
|
|
23205
|
+
return "com.apple.Safari";
|
|
23206
|
+
}
|
|
23207
|
+
return browserId;
|
|
23208
|
+
}
|
|
23209
|
+
|
|
23210
|
+
// ../../node_modules/.pnpm/run-applescript@7.1.0/node_modules/run-applescript/index.js
|
|
23211
|
+
import process5 from "node:process";
|
|
23212
|
+
import { promisify as promisify2 } from "node:util";
|
|
23213
|
+
import { execFile as execFile2, execFileSync } from "node:child_process";
|
|
23214
|
+
var execFileAsync2 = promisify2(execFile2);
|
|
23215
|
+
async function runAppleScript(script, { humanReadableOutput = true, signal } = {}) {
|
|
23216
|
+
if (process5.platform !== "darwin") {
|
|
23217
|
+
throw new Error("macOS only");
|
|
23218
|
+
}
|
|
23219
|
+
const outputArguments = humanReadableOutput ? [] : ["-ss"];
|
|
23220
|
+
const execOptions = {};
|
|
23221
|
+
if (signal) {
|
|
23222
|
+
execOptions.signal = signal;
|
|
23223
|
+
}
|
|
23224
|
+
const { stdout } = await execFileAsync2("osascript", ["-e", script, outputArguments], execOptions);
|
|
23225
|
+
return stdout.trim();
|
|
23226
|
+
}
|
|
23227
|
+
|
|
23228
|
+
// ../../node_modules/.pnpm/bundle-name@4.1.0/node_modules/bundle-name/index.js
|
|
23229
|
+
async function bundleName(bundleId) {
|
|
23230
|
+
return runAppleScript(`tell application "Finder" to set app_path to application file id "${bundleId}" as string
|
|
23231
|
+
tell application "System Events" to get value of property list item "CFBundleName" of property list file (app_path & ":Contents:Info.plist")`);
|
|
23232
|
+
}
|
|
23233
|
+
|
|
23234
|
+
// ../../node_modules/.pnpm/default-browser@5.5.0/node_modules/default-browser/windows.js
|
|
23235
|
+
import { promisify as promisify3 } from "node:util";
|
|
23236
|
+
import { execFile as execFile3 } from "node:child_process";
|
|
23237
|
+
var execFileAsync3 = promisify3(execFile3);
|
|
23238
|
+
var windowsBrowserProgIds = {
|
|
23239
|
+
MSEdgeHTM: { name: "Edge", id: "com.microsoft.edge" },
|
|
23240
|
+
// The missing `L` is correct.
|
|
23241
|
+
MSEdgeBHTML: { name: "Edge Beta", id: "com.microsoft.edge.beta" },
|
|
23242
|
+
MSEdgeDHTML: { name: "Edge Dev", id: "com.microsoft.edge.dev" },
|
|
23243
|
+
AppXq0fevzme2pys62n3e0fbqa7peapykr8v: { name: "Edge", id: "com.microsoft.edge.old" },
|
|
23244
|
+
ChromeHTML: { name: "Chrome", id: "com.google.chrome" },
|
|
23245
|
+
ChromeBHTML: { name: "Chrome Beta", id: "com.google.chrome.beta" },
|
|
23246
|
+
ChromeDHTML: { name: "Chrome Dev", id: "com.google.chrome.dev" },
|
|
23247
|
+
ChromiumHTM: { name: "Chromium", id: "org.chromium.Chromium" },
|
|
23248
|
+
BraveHTML: { name: "Brave", id: "com.brave.Browser" },
|
|
23249
|
+
BraveBHTML: { name: "Brave Beta", id: "com.brave.Browser.beta" },
|
|
23250
|
+
BraveDHTML: { name: "Brave Dev", id: "com.brave.Browser.dev" },
|
|
23251
|
+
BraveSSHTM: { name: "Brave Nightly", id: "com.brave.Browser.nightly" },
|
|
23252
|
+
FirefoxURL: { name: "Firefox", id: "org.mozilla.firefox" },
|
|
23253
|
+
OperaStable: { name: "Opera", id: "com.operasoftware.Opera" },
|
|
23254
|
+
VivaldiHTM: { name: "Vivaldi", id: "com.vivaldi.Vivaldi" },
|
|
23255
|
+
"IE.HTTP": { name: "Internet Explorer", id: "com.microsoft.ie" }
|
|
23256
|
+
};
|
|
23257
|
+
var _windowsBrowserProgIdMap = new Map(Object.entries(windowsBrowserProgIds));
|
|
23258
|
+
var UnknownBrowserError = class extends Error {
|
|
23259
|
+
};
|
|
23260
|
+
async function defaultBrowser(_execFileAsync = execFileAsync3) {
|
|
23261
|
+
const { stdout } = await _execFileAsync("reg", [
|
|
23262
|
+
"QUERY",
|
|
23263
|
+
" HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\http\\UserChoice",
|
|
23264
|
+
"/v",
|
|
23265
|
+
"ProgId"
|
|
23266
|
+
]);
|
|
23267
|
+
const match = /ProgId\s*REG_SZ\s*(?<id>\S+)/.exec(stdout);
|
|
23268
|
+
if (!match) {
|
|
23269
|
+
throw new UnknownBrowserError(`Cannot find Windows browser in stdout: ${JSON.stringify(stdout)}`);
|
|
23270
|
+
}
|
|
23271
|
+
const { id } = match.groups;
|
|
23272
|
+
const dotIndex = id.lastIndexOf(".");
|
|
23273
|
+
const hyphenIndex = id.lastIndexOf("-");
|
|
23274
|
+
const baseIdByDot = dotIndex === -1 ? void 0 : id.slice(0, dotIndex);
|
|
23275
|
+
const baseIdByHyphen = hyphenIndex === -1 ? void 0 : id.slice(0, hyphenIndex);
|
|
23276
|
+
return windowsBrowserProgIds[id] ?? windowsBrowserProgIds[baseIdByDot] ?? windowsBrowserProgIds[baseIdByHyphen] ?? { name: id, id };
|
|
23277
|
+
}
|
|
23278
|
+
|
|
23279
|
+
// ../../node_modules/.pnpm/default-browser@5.5.0/node_modules/default-browser/index.js
|
|
23280
|
+
var execFileAsync4 = promisify4(execFile4);
|
|
23281
|
+
var titleize = (string4) => string4.toLowerCase().replaceAll(/(?:^|\s|-)\S/g, (x) => x.toUpperCase());
|
|
23282
|
+
async function defaultBrowser2() {
|
|
23283
|
+
if (process6.platform === "darwin") {
|
|
23284
|
+
const id = await defaultBrowserId();
|
|
23285
|
+
const name = await bundleName(id);
|
|
23286
|
+
return { name, id };
|
|
23287
|
+
}
|
|
23288
|
+
if (process6.platform === "linux") {
|
|
23289
|
+
const { stdout } = await execFileAsync4("xdg-mime", ["query", "default", "x-scheme-handler/http"]);
|
|
23290
|
+
const id = stdout.trim();
|
|
23291
|
+
const name = titleize(id.replace(/.desktop$/, "").replace("-", " "));
|
|
23292
|
+
return { name, id };
|
|
23293
|
+
}
|
|
23294
|
+
if (process6.platform === "win32") {
|
|
23295
|
+
return defaultBrowser();
|
|
23296
|
+
}
|
|
23297
|
+
throw new Error("Only macOS, Linux, and Windows are supported");
|
|
23298
|
+
}
|
|
23299
|
+
|
|
23300
|
+
// ../../node_modules/.pnpm/open@10.2.0/node_modules/open/index.js
|
|
23301
|
+
var execFile5 = promisify5(childProcess.execFile);
|
|
23302
|
+
var __dirname = path4.dirname(fileURLToPath(import.meta.url));
|
|
23303
|
+
var localXdgOpenPath = path4.join(__dirname, "xdg-open");
|
|
23304
|
+
var { platform, arch } = process7;
|
|
23305
|
+
async function getWindowsDefaultBrowserFromWsl() {
|
|
23306
|
+
const powershellPath = await powerShellPath();
|
|
23307
|
+
const rawCommand = String.raw`(Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice").ProgId`;
|
|
23308
|
+
const encodedCommand = Buffer2.from(rawCommand, "utf16le").toString("base64");
|
|
23309
|
+
const { stdout } = await execFile5(
|
|
23310
|
+
powershellPath,
|
|
23311
|
+
[
|
|
23312
|
+
"-NoProfile",
|
|
23313
|
+
"-NonInteractive",
|
|
23314
|
+
"-ExecutionPolicy",
|
|
23315
|
+
"Bypass",
|
|
23316
|
+
"-EncodedCommand",
|
|
23317
|
+
encodedCommand
|
|
23318
|
+
],
|
|
23319
|
+
{ encoding: "utf8" }
|
|
23320
|
+
);
|
|
23321
|
+
const progId = stdout.trim();
|
|
23322
|
+
const browserMap = {
|
|
23323
|
+
ChromeHTML: "com.google.chrome",
|
|
23324
|
+
BraveHTML: "com.brave.Browser",
|
|
23325
|
+
MSEdgeHTM: "com.microsoft.edge",
|
|
23326
|
+
FirefoxURL: "org.mozilla.firefox"
|
|
23327
|
+
};
|
|
23328
|
+
return browserMap[progId] ? { id: browserMap[progId] } : {};
|
|
23329
|
+
}
|
|
23330
|
+
var pTryEach = async (array2, mapper) => {
|
|
23331
|
+
let latestError;
|
|
23332
|
+
for (const item of array2) {
|
|
23333
|
+
try {
|
|
23334
|
+
return await mapper(item);
|
|
23335
|
+
} catch (error40) {
|
|
23336
|
+
latestError = error40;
|
|
23337
|
+
}
|
|
23338
|
+
}
|
|
23339
|
+
throw latestError;
|
|
23340
|
+
};
|
|
23341
|
+
var baseOpen = async (options) => {
|
|
23342
|
+
options = {
|
|
23343
|
+
wait: false,
|
|
23344
|
+
background: false,
|
|
23345
|
+
newInstance: false,
|
|
23346
|
+
allowNonzeroExitCode: false,
|
|
23347
|
+
...options
|
|
23348
|
+
};
|
|
23349
|
+
if (Array.isArray(options.app)) {
|
|
23350
|
+
return pTryEach(options.app, (singleApp) => baseOpen({
|
|
23351
|
+
...options,
|
|
23352
|
+
app: singleApp
|
|
23353
|
+
}));
|
|
23354
|
+
}
|
|
23355
|
+
let { name: app, arguments: appArguments = [] } = options.app ?? {};
|
|
23356
|
+
appArguments = [...appArguments];
|
|
23357
|
+
if (Array.isArray(app)) {
|
|
23358
|
+
return pTryEach(app, (appName) => baseOpen({
|
|
23359
|
+
...options,
|
|
23360
|
+
app: {
|
|
23361
|
+
name: appName,
|
|
23362
|
+
arguments: appArguments
|
|
23363
|
+
}
|
|
23364
|
+
}));
|
|
23365
|
+
}
|
|
23366
|
+
if (app === "browser" || app === "browserPrivate") {
|
|
23367
|
+
const ids = {
|
|
23368
|
+
"com.google.chrome": "chrome",
|
|
23369
|
+
"google-chrome.desktop": "chrome",
|
|
23370
|
+
"com.brave.Browser": "brave",
|
|
23371
|
+
"org.mozilla.firefox": "firefox",
|
|
23372
|
+
"firefox.desktop": "firefox",
|
|
23373
|
+
"com.microsoft.msedge": "edge",
|
|
23374
|
+
"com.microsoft.edge": "edge",
|
|
23375
|
+
"com.microsoft.edgemac": "edge",
|
|
23376
|
+
"microsoft-edge.desktop": "edge"
|
|
23377
|
+
};
|
|
23378
|
+
const flags = {
|
|
23379
|
+
chrome: "--incognito",
|
|
23380
|
+
brave: "--incognito",
|
|
23381
|
+
firefox: "--private-window",
|
|
23382
|
+
edge: "--inPrivate"
|
|
23383
|
+
};
|
|
23384
|
+
const browser = is_wsl_default ? await getWindowsDefaultBrowserFromWsl() : await defaultBrowser2();
|
|
23385
|
+
if (browser.id in ids) {
|
|
23386
|
+
const browserName = ids[browser.id];
|
|
23387
|
+
if (app === "browserPrivate") {
|
|
23388
|
+
appArguments.push(flags[browserName]);
|
|
23389
|
+
}
|
|
23390
|
+
return baseOpen({
|
|
23391
|
+
...options,
|
|
23392
|
+
app: {
|
|
23393
|
+
name: apps[browserName],
|
|
23394
|
+
arguments: appArguments
|
|
23395
|
+
}
|
|
23396
|
+
});
|
|
23397
|
+
}
|
|
23398
|
+
throw new Error(`${browser.name} is not supported as a default browser`);
|
|
23399
|
+
}
|
|
23400
|
+
let command;
|
|
23401
|
+
const cliArguments = [];
|
|
23402
|
+
const childProcessOptions = {};
|
|
23403
|
+
if (platform === "darwin") {
|
|
23404
|
+
command = "open";
|
|
23405
|
+
if (options.wait) {
|
|
23406
|
+
cliArguments.push("--wait-apps");
|
|
23407
|
+
}
|
|
23408
|
+
if (options.background) {
|
|
23409
|
+
cliArguments.push("--background");
|
|
23410
|
+
}
|
|
23411
|
+
if (options.newInstance) {
|
|
23412
|
+
cliArguments.push("--new");
|
|
23413
|
+
}
|
|
23414
|
+
if (app) {
|
|
23415
|
+
cliArguments.push("-a", app);
|
|
23416
|
+
}
|
|
23417
|
+
} else if (platform === "win32" || is_wsl_default && !isInsideContainer() && !app) {
|
|
23418
|
+
command = await powerShellPath();
|
|
23419
|
+
cliArguments.push(
|
|
23420
|
+
"-NoProfile",
|
|
23421
|
+
"-NonInteractive",
|
|
23422
|
+
"-ExecutionPolicy",
|
|
23423
|
+
"Bypass",
|
|
23424
|
+
"-EncodedCommand"
|
|
23425
|
+
);
|
|
23426
|
+
if (!is_wsl_default) {
|
|
23427
|
+
childProcessOptions.windowsVerbatimArguments = true;
|
|
23428
|
+
}
|
|
23429
|
+
const encodedArguments = ["Start"];
|
|
23430
|
+
if (options.wait) {
|
|
23431
|
+
encodedArguments.push("-Wait");
|
|
23432
|
+
}
|
|
23433
|
+
if (app) {
|
|
23434
|
+
encodedArguments.push(`"\`"${app}\`""`);
|
|
23435
|
+
if (options.target) {
|
|
23436
|
+
appArguments.push(options.target);
|
|
23437
|
+
}
|
|
23438
|
+
} else if (options.target) {
|
|
23439
|
+
encodedArguments.push(`"${options.target}"`);
|
|
23440
|
+
}
|
|
23441
|
+
if (appArguments.length > 0) {
|
|
23442
|
+
appArguments = appArguments.map((argument) => `"\`"${argument}\`""`);
|
|
23443
|
+
encodedArguments.push("-ArgumentList", appArguments.join(","));
|
|
23444
|
+
}
|
|
23445
|
+
options.target = Buffer2.from(encodedArguments.join(" "), "utf16le").toString("base64");
|
|
23446
|
+
} else {
|
|
23447
|
+
if (app) {
|
|
23448
|
+
command = app;
|
|
23449
|
+
} else {
|
|
23450
|
+
const isBundled = !__dirname || __dirname === "/";
|
|
23451
|
+
let exeLocalXdgOpen = false;
|
|
23452
|
+
try {
|
|
23453
|
+
await fs6.access(localXdgOpenPath, fsConstants2.X_OK);
|
|
23454
|
+
exeLocalXdgOpen = true;
|
|
23455
|
+
} catch {
|
|
23456
|
+
}
|
|
23457
|
+
const useSystemXdgOpen = process7.versions.electron ?? (platform === "android" || isBundled || !exeLocalXdgOpen);
|
|
23458
|
+
command = useSystemXdgOpen ? "xdg-open" : localXdgOpenPath;
|
|
23459
|
+
}
|
|
23460
|
+
if (appArguments.length > 0) {
|
|
23461
|
+
cliArguments.push(...appArguments);
|
|
23462
|
+
}
|
|
23463
|
+
if (!options.wait) {
|
|
23464
|
+
childProcessOptions.stdio = "ignore";
|
|
23465
|
+
childProcessOptions.detached = true;
|
|
23466
|
+
}
|
|
23467
|
+
}
|
|
23468
|
+
if (platform === "darwin" && appArguments.length > 0) {
|
|
23469
|
+
cliArguments.push("--args", ...appArguments);
|
|
23470
|
+
}
|
|
23471
|
+
if (options.target) {
|
|
23472
|
+
cliArguments.push(options.target);
|
|
23473
|
+
}
|
|
23474
|
+
const subprocess = childProcess.spawn(command, cliArguments, childProcessOptions);
|
|
23475
|
+
if (options.wait) {
|
|
23476
|
+
return new Promise((resolve15, reject) => {
|
|
23477
|
+
subprocess.once("error", reject);
|
|
23478
|
+
subprocess.once("close", (exitCode) => {
|
|
23479
|
+
if (!options.allowNonzeroExitCode && exitCode > 0) {
|
|
23480
|
+
reject(new Error(`Exited with code ${exitCode}`));
|
|
23481
|
+
return;
|
|
23482
|
+
}
|
|
23483
|
+
resolve15(subprocess);
|
|
23484
|
+
});
|
|
23485
|
+
});
|
|
23486
|
+
}
|
|
23487
|
+
subprocess.unref();
|
|
23488
|
+
return subprocess;
|
|
23489
|
+
};
|
|
23490
|
+
var open = (target, options) => {
|
|
23491
|
+
if (typeof target !== "string") {
|
|
23492
|
+
throw new TypeError("Expected a `target`");
|
|
23493
|
+
}
|
|
23494
|
+
return baseOpen({
|
|
23495
|
+
...options,
|
|
23496
|
+
target
|
|
23497
|
+
});
|
|
23498
|
+
};
|
|
23499
|
+
function detectArchBinary(binary) {
|
|
23500
|
+
if (typeof binary === "string" || Array.isArray(binary)) {
|
|
23501
|
+
return binary;
|
|
23502
|
+
}
|
|
23503
|
+
const { [arch]: archBinary } = binary;
|
|
23504
|
+
if (!archBinary) {
|
|
23505
|
+
throw new Error(`${arch} is not supported`);
|
|
23506
|
+
}
|
|
23507
|
+
return archBinary;
|
|
23508
|
+
}
|
|
23509
|
+
function detectPlatformBinary({ [platform]: platformBinary }, { wsl }) {
|
|
23510
|
+
if (wsl && is_wsl_default) {
|
|
23511
|
+
return detectArchBinary(wsl);
|
|
23512
|
+
}
|
|
23513
|
+
if (!platformBinary) {
|
|
23514
|
+
throw new Error(`${platform} is not supported`);
|
|
23515
|
+
}
|
|
23516
|
+
return detectArchBinary(platformBinary);
|
|
23517
|
+
}
|
|
23518
|
+
var apps = {};
|
|
23519
|
+
defineLazyProperty(apps, "chrome", () => detectPlatformBinary({
|
|
23520
|
+
darwin: "google chrome",
|
|
23521
|
+
win32: "chrome",
|
|
23522
|
+
linux: ["google-chrome", "google-chrome-stable", "chromium"]
|
|
23523
|
+
}, {
|
|
23524
|
+
wsl: {
|
|
23525
|
+
ia32: "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe",
|
|
23526
|
+
x64: ["/mnt/c/Program Files/Google/Chrome/Application/chrome.exe", "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe"]
|
|
23527
|
+
}
|
|
23528
|
+
}));
|
|
23529
|
+
defineLazyProperty(apps, "brave", () => detectPlatformBinary({
|
|
23530
|
+
darwin: "brave browser",
|
|
23531
|
+
win32: "brave",
|
|
23532
|
+
linux: ["brave-browser", "brave"]
|
|
23533
|
+
}, {
|
|
23534
|
+
wsl: {
|
|
23535
|
+
ia32: "/mnt/c/Program Files (x86)/BraveSoftware/Brave-Browser/Application/brave.exe",
|
|
23536
|
+
x64: ["/mnt/c/Program Files/BraveSoftware/Brave-Browser/Application/brave.exe", "/mnt/c/Program Files (x86)/BraveSoftware/Brave-Browser/Application/brave.exe"]
|
|
23537
|
+
}
|
|
23538
|
+
}));
|
|
23539
|
+
defineLazyProperty(apps, "firefox", () => detectPlatformBinary({
|
|
23540
|
+
darwin: "firefox",
|
|
23541
|
+
win32: String.raw`C:\Program Files\Mozilla Firefox\firefox.exe`,
|
|
23542
|
+
linux: "firefox"
|
|
23543
|
+
}, {
|
|
23544
|
+
wsl: "/mnt/c/Program Files/Mozilla Firefox/firefox.exe"
|
|
23545
|
+
}));
|
|
23546
|
+
defineLazyProperty(apps, "edge", () => detectPlatformBinary({
|
|
23547
|
+
darwin: "microsoft edge",
|
|
23548
|
+
win32: "msedge",
|
|
23549
|
+
linux: ["microsoft-edge", "microsoft-edge-dev"]
|
|
23550
|
+
}, {
|
|
23551
|
+
wsl: "/mnt/c/Program Files (x86)/Microsoft/Edge/Application/msedge.exe"
|
|
23552
|
+
}));
|
|
23553
|
+
defineLazyProperty(apps, "browser", () => "browser");
|
|
23554
|
+
defineLazyProperty(apps, "browserPrivate", () => "browserPrivate");
|
|
23555
|
+
var open_default = open;
|
|
23556
|
+
|
|
23030
23557
|
// src/auth/open-browser.ts
|
|
23031
|
-
import { execSync } from "node:child_process";
|
|
23032
23558
|
function isLocalApiUrl(apiUrl) {
|
|
23033
23559
|
try {
|
|
23034
23560
|
const u = new URL(apiUrl);
|
|
@@ -23038,7 +23564,7 @@ function isLocalApiUrl(apiUrl) {
|
|
|
23038
23564
|
return false;
|
|
23039
23565
|
}
|
|
23040
23566
|
}
|
|
23041
|
-
function openBrowser(connectionId, initialWorkspaceId, preferredBridgeName, apiUrl, logFn = log) {
|
|
23567
|
+
async function openBrowser(connectionId, initialWorkspaceId, preferredBridgeName, apiUrl, logFn = log) {
|
|
23042
23568
|
const appUrl = apiUrl && isLocalApiUrl(apiUrl) ? process.env.BUILDAUTOMATON_APP_URL ?? "http://localhost:3000" : process.env.BUILDAUTOMATON_APP_URL ?? "https://app.buildautomaton.com";
|
|
23043
23569
|
let connectCliUrl = `${appUrl.replace(/\/$/, "")}/bridges/connect?connectionId=${connectionId}`;
|
|
23044
23570
|
if (initialWorkspaceId) {
|
|
@@ -23052,10 +23578,11 @@ function openBrowser(connectionId, initialWorkspaceId, preferredBridgeName, apiU
|
|
|
23052
23578
|
connectCliUrl += `&bridgeName=${encodeURIComponent(preferredBridgeName.trim())}`;
|
|
23053
23579
|
}
|
|
23054
23580
|
logFn("Opening browser to link this CLI\u2026");
|
|
23055
|
-
logFn(
|
|
23581
|
+
logFn(
|
|
23582
|
+
"If you\u2019re already signed in with one workspace, the CLI will connect automatically. Otherwise sign in and link to a workspace."
|
|
23583
|
+
);
|
|
23056
23584
|
try {
|
|
23057
|
-
|
|
23058
|
-
execSync(`${cmd} "${connectCliUrl}"`, { stdio: "ignore" });
|
|
23585
|
+
await open_default(connectCliUrl, { wait: false });
|
|
23059
23586
|
} catch {
|
|
23060
23587
|
logFn("Could not open browser. Open this URL manually:");
|
|
23061
23588
|
logFn(connectCliUrl);
|
|
@@ -23246,8 +23773,8 @@ function runPendingAuth(options) {
|
|
|
23246
23773
|
let hasOpenedBrowser = false;
|
|
23247
23774
|
let resolved = false;
|
|
23248
23775
|
let resolveAuth;
|
|
23249
|
-
const authPromise = new Promise((
|
|
23250
|
-
resolveAuth =
|
|
23776
|
+
const authPromise = new Promise((resolve15) => {
|
|
23777
|
+
resolveAuth = resolve15;
|
|
23251
23778
|
});
|
|
23252
23779
|
let reconnectAttempt = 0;
|
|
23253
23780
|
const signInQuiet = createEmptyReconnectQuietSlot();
|
|
@@ -23310,7 +23837,7 @@ function runPendingAuth(options) {
|
|
|
23310
23837
|
}
|
|
23311
23838
|
if (!hasOpenedBrowser) {
|
|
23312
23839
|
hasOpenedBrowser = true;
|
|
23313
|
-
openBrowser(connectionId, initialWorkspaceId, preferredBridgeName, apiUrl, logFn);
|
|
23840
|
+
void openBrowser(connectionId, initialWorkspaceId, preferredBridgeName, apiUrl, logFn);
|
|
23314
23841
|
}
|
|
23315
23842
|
},
|
|
23316
23843
|
onClose: (code, reason) => {
|
|
@@ -23352,7 +23879,7 @@ function runPendingAuth(options) {
|
|
|
23352
23879
|
browserFallback = null;
|
|
23353
23880
|
if (!hasOpenedBrowser) {
|
|
23354
23881
|
hasOpenedBrowser = true;
|
|
23355
|
-
openBrowser(connectionId, initialWorkspaceId, preferredBridgeName, apiUrl, logFn);
|
|
23882
|
+
void openBrowser(connectionId, initialWorkspaceId, preferredBridgeName, apiUrl, logFn);
|
|
23356
23883
|
}
|
|
23357
23884
|
}, BROWSER_OPEN_FALLBACK_MS);
|
|
23358
23885
|
connect();
|
|
@@ -23369,7 +23896,7 @@ function runPendingAuth(options) {
|
|
|
23369
23896
|
async function closeBridgeConnection(state, acpManager, devServerManager, log2) {
|
|
23370
23897
|
const say = log2 ?? logImmediate;
|
|
23371
23898
|
say("Cleaning up connections\u2026");
|
|
23372
|
-
await new Promise((
|
|
23899
|
+
await new Promise((resolve15) => setImmediate(resolve15));
|
|
23373
23900
|
state.closedByUser = true;
|
|
23374
23901
|
clearReconnectQuietTimer(state.mainQuiet);
|
|
23375
23902
|
clearReconnectQuietTimer(state.firehoseQuiet);
|
|
@@ -23412,27 +23939,27 @@ async function closeBridgeConnection(state, acpManager, devServerManager, log2)
|
|
|
23412
23939
|
}
|
|
23413
23940
|
|
|
23414
23941
|
// src/git/session-git-queue.ts
|
|
23415
|
-
import { execFile as
|
|
23942
|
+
import { execFile as execFile7 } from "node:child_process";
|
|
23416
23943
|
import { readFile, stat } from "node:fs/promises";
|
|
23417
|
-
import { promisify as
|
|
23418
|
-
import * as
|
|
23944
|
+
import { promisify as promisify7 } from "node:util";
|
|
23945
|
+
import * as path7 from "node:path";
|
|
23419
23946
|
|
|
23420
23947
|
// src/git/pre-turn-snapshot.ts
|
|
23421
|
-
import * as
|
|
23422
|
-
import * as
|
|
23423
|
-
import { execFile } from "node:child_process";
|
|
23424
|
-
import { promisify } from "node:util";
|
|
23948
|
+
import * as fs8 from "node:fs";
|
|
23949
|
+
import * as path6 from "node:path";
|
|
23950
|
+
import { execFile as execFile6 } from "node:child_process";
|
|
23951
|
+
import { promisify as promisify6 } from "node:util";
|
|
23425
23952
|
|
|
23426
23953
|
// src/git/discover-repos.ts
|
|
23427
|
-
import * as
|
|
23428
|
-
import * as
|
|
23954
|
+
import * as fs7 from "node:fs";
|
|
23955
|
+
import * as path5 from "node:path";
|
|
23429
23956
|
|
|
23430
23957
|
// ../../node_modules/.pnpm/simple-git@3.32.3/node_modules/simple-git/dist/esm/index.js
|
|
23431
23958
|
var import_file_exists = __toESM(require_dist(), 1);
|
|
23432
23959
|
var import_debug = __toESM(require_src(), 1);
|
|
23433
23960
|
var import_promise_deferred = __toESM(require_dist2(), 1);
|
|
23434
23961
|
var import_promise_deferred2 = __toESM(require_dist2(), 1);
|
|
23435
|
-
import { Buffer as
|
|
23962
|
+
import { Buffer as Buffer22 } from "node:buffer";
|
|
23436
23963
|
import { spawn as spawn3 } from "child_process";
|
|
23437
23964
|
import { normalize as normalize2 } from "node:path";
|
|
23438
23965
|
import { EventEmitter } from "node:events";
|
|
@@ -23464,8 +23991,8 @@ function pathspec(...paths) {
|
|
|
23464
23991
|
cache.set(key, paths);
|
|
23465
23992
|
return key;
|
|
23466
23993
|
}
|
|
23467
|
-
function isPathSpec(
|
|
23468
|
-
return
|
|
23994
|
+
function isPathSpec(path32) {
|
|
23995
|
+
return path32 instanceof String && cache.has(path32);
|
|
23469
23996
|
}
|
|
23470
23997
|
function toPaths(pathSpec) {
|
|
23471
23998
|
return cache.get(pathSpec) || [];
|
|
@@ -23554,8 +24081,8 @@ function toLinesWithContent(input = "", trimmed2 = true, separator = "\n") {
|
|
|
23554
24081
|
function forEachLineWithContent(input, callback) {
|
|
23555
24082
|
return toLinesWithContent(input, true).map((line) => callback(line));
|
|
23556
24083
|
}
|
|
23557
|
-
function folderExists(
|
|
23558
|
-
return (0, import_file_exists.exists)(
|
|
24084
|
+
function folderExists(path32) {
|
|
24085
|
+
return (0, import_file_exists.exists)(path32, import_file_exists.FOLDER);
|
|
23559
24086
|
}
|
|
23560
24087
|
function append(target, item) {
|
|
23561
24088
|
if (Array.isArray(target)) {
|
|
@@ -23612,7 +24139,7 @@ function prefixedArray(input, prefix) {
|
|
|
23612
24139
|
return output;
|
|
23613
24140
|
}
|
|
23614
24141
|
function bufferToString(input) {
|
|
23615
|
-
return (Array.isArray(input) ?
|
|
24142
|
+
return (Array.isArray(input) ? Buffer22.concat(input) : input).toString("utf-8");
|
|
23616
24143
|
}
|
|
23617
24144
|
function pick2(source, properties) {
|
|
23618
24145
|
const out = {};
|
|
@@ -23959,8 +24486,8 @@ function checkIsRepoRootTask() {
|
|
|
23959
24486
|
commands,
|
|
23960
24487
|
format: "utf-8",
|
|
23961
24488
|
onError,
|
|
23962
|
-
parser(
|
|
23963
|
-
return /^\.(git)?$/.test(
|
|
24489
|
+
parser(path32) {
|
|
24490
|
+
return /^\.(git)?$/.test(path32.trim());
|
|
23964
24491
|
}
|
|
23965
24492
|
};
|
|
23966
24493
|
}
|
|
@@ -24394,11 +24921,11 @@ function parseGrep(grep) {
|
|
|
24394
24921
|
const paths = /* @__PURE__ */ new Set();
|
|
24395
24922
|
const results = {};
|
|
24396
24923
|
forEachLineWithContent(grep, (input) => {
|
|
24397
|
-
const [
|
|
24398
|
-
paths.add(
|
|
24399
|
-
(results[
|
|
24924
|
+
const [path32, line, preview] = input.split(NULL);
|
|
24925
|
+
paths.add(path32);
|
|
24926
|
+
(results[path32] = results[path32] || []).push({
|
|
24400
24927
|
line: asNumber(line),
|
|
24401
|
-
path:
|
|
24928
|
+
path: path32,
|
|
24402
24929
|
preview
|
|
24403
24930
|
});
|
|
24404
24931
|
});
|
|
@@ -25163,14 +25690,14 @@ var init_hash_object = __esm2({
|
|
|
25163
25690
|
init_task();
|
|
25164
25691
|
}
|
|
25165
25692
|
});
|
|
25166
|
-
function parseInit(bare,
|
|
25693
|
+
function parseInit(bare, path32, text) {
|
|
25167
25694
|
const response = String(text).trim();
|
|
25168
25695
|
let result;
|
|
25169
25696
|
if (result = initResponseRegex.exec(response)) {
|
|
25170
|
-
return new InitSummary(bare,
|
|
25697
|
+
return new InitSummary(bare, path32, false, result[1]);
|
|
25171
25698
|
}
|
|
25172
25699
|
if (result = reInitResponseRegex.exec(response)) {
|
|
25173
|
-
return new InitSummary(bare,
|
|
25700
|
+
return new InitSummary(bare, path32, true, result[1]);
|
|
25174
25701
|
}
|
|
25175
25702
|
let gitDir = "";
|
|
25176
25703
|
const tokens = response.split(" ");
|
|
@@ -25181,7 +25708,7 @@ function parseInit(bare, path29, text) {
|
|
|
25181
25708
|
break;
|
|
25182
25709
|
}
|
|
25183
25710
|
}
|
|
25184
|
-
return new InitSummary(bare,
|
|
25711
|
+
return new InitSummary(bare, path32, /^re/i.test(response), gitDir);
|
|
25185
25712
|
}
|
|
25186
25713
|
var InitSummary;
|
|
25187
25714
|
var initResponseRegex;
|
|
@@ -25190,9 +25717,9 @@ var init_InitSummary = __esm2({
|
|
|
25190
25717
|
"src/lib/responses/InitSummary.ts"() {
|
|
25191
25718
|
"use strict";
|
|
25192
25719
|
InitSummary = class {
|
|
25193
|
-
constructor(bare,
|
|
25720
|
+
constructor(bare, path32, existing, gitDir) {
|
|
25194
25721
|
this.bare = bare;
|
|
25195
|
-
this.path =
|
|
25722
|
+
this.path = path32;
|
|
25196
25723
|
this.existing = existing;
|
|
25197
25724
|
this.gitDir = gitDir;
|
|
25198
25725
|
}
|
|
@@ -25204,7 +25731,7 @@ var init_InitSummary = __esm2({
|
|
|
25204
25731
|
function hasBareCommand(command) {
|
|
25205
25732
|
return command.includes(bareCommand);
|
|
25206
25733
|
}
|
|
25207
|
-
function initTask(bare = false,
|
|
25734
|
+
function initTask(bare = false, path32, customArgs) {
|
|
25208
25735
|
const commands = ["init", ...customArgs];
|
|
25209
25736
|
if (bare && !hasBareCommand(commands)) {
|
|
25210
25737
|
commands.splice(1, 0, bareCommand);
|
|
@@ -25213,7 +25740,7 @@ function initTask(bare = false, path29, customArgs) {
|
|
|
25213
25740
|
commands,
|
|
25214
25741
|
format: "utf-8",
|
|
25215
25742
|
parser(text) {
|
|
25216
|
-
return parseInit(commands.includes("--bare"),
|
|
25743
|
+
return parseInit(commands.includes("--bare"), path32, text);
|
|
25217
25744
|
}
|
|
25218
25745
|
};
|
|
25219
25746
|
}
|
|
@@ -26029,12 +26556,12 @@ var init_FileStatusSummary = __esm2({
|
|
|
26029
26556
|
"use strict";
|
|
26030
26557
|
fromPathRegex = /^(.+)\0(.+)$/;
|
|
26031
26558
|
FileStatusSummary = class {
|
|
26032
|
-
constructor(
|
|
26033
|
-
this.path =
|
|
26559
|
+
constructor(path32, index, working_dir) {
|
|
26560
|
+
this.path = path32;
|
|
26034
26561
|
this.index = index;
|
|
26035
26562
|
this.working_dir = working_dir;
|
|
26036
26563
|
if (index === "R" || working_dir === "R") {
|
|
26037
|
-
const detail = fromPathRegex.exec(
|
|
26564
|
+
const detail = fromPathRegex.exec(path32) || [null, path32, path32];
|
|
26038
26565
|
this.from = detail[2] || "";
|
|
26039
26566
|
this.path = detail[1] || "";
|
|
26040
26567
|
}
|
|
@@ -26065,14 +26592,14 @@ function splitLine(result, lineStr) {
|
|
|
26065
26592
|
default:
|
|
26066
26593
|
return;
|
|
26067
26594
|
}
|
|
26068
|
-
function data(index, workingDir,
|
|
26595
|
+
function data(index, workingDir, path32) {
|
|
26069
26596
|
const raw = `${index}${workingDir}`;
|
|
26070
26597
|
const handler = parsers6.get(raw);
|
|
26071
26598
|
if (handler) {
|
|
26072
|
-
handler(result,
|
|
26599
|
+
handler(result, path32);
|
|
26073
26600
|
}
|
|
26074
26601
|
if (raw !== "##" && raw !== "!!") {
|
|
26075
|
-
result.files.push(new FileStatusSummary(
|
|
26602
|
+
result.files.push(new FileStatusSummary(path32, index, workingDir));
|
|
26076
26603
|
}
|
|
26077
26604
|
}
|
|
26078
26605
|
}
|
|
@@ -26243,14 +26770,14 @@ var init_status = __esm2({
|
|
|
26243
26770
|
ignoredOptions = ["--null", "-z"];
|
|
26244
26771
|
}
|
|
26245
26772
|
});
|
|
26246
|
-
function versionResponse(major = 0, minor = 0, patch = 0, agent = "",
|
|
26773
|
+
function versionResponse(major = 0, minor = 0, patch = 0, agent = "", installed2 = true) {
|
|
26247
26774
|
return Object.defineProperty(
|
|
26248
26775
|
{
|
|
26249
26776
|
major,
|
|
26250
26777
|
minor,
|
|
26251
26778
|
patch,
|
|
26252
26779
|
agent,
|
|
26253
|
-
installed
|
|
26780
|
+
installed: installed2
|
|
26254
26781
|
},
|
|
26255
26782
|
"toString",
|
|
26256
26783
|
{
|
|
@@ -26381,9 +26908,9 @@ var init_simple_git_api = __esm2({
|
|
|
26381
26908
|
next
|
|
26382
26909
|
);
|
|
26383
26910
|
}
|
|
26384
|
-
hashObject(
|
|
26911
|
+
hashObject(path32, write) {
|
|
26385
26912
|
return this._runTask(
|
|
26386
|
-
hashObjectTask(
|
|
26913
|
+
hashObjectTask(path32, write === true),
|
|
26387
26914
|
trailingFunctionArgument(arguments)
|
|
26388
26915
|
);
|
|
26389
26916
|
}
|
|
@@ -26736,8 +27263,8 @@ var init_branch = __esm2({
|
|
|
26736
27263
|
}
|
|
26737
27264
|
});
|
|
26738
27265
|
function toPath(input) {
|
|
26739
|
-
const
|
|
26740
|
-
return
|
|
27266
|
+
const path32 = input.trim().replace(/^["']|["']$/g, "");
|
|
27267
|
+
return path32 && normalize2(path32);
|
|
26741
27268
|
}
|
|
26742
27269
|
var parseCheckIgnore;
|
|
26743
27270
|
var init_CheckIgnore = __esm2({
|
|
@@ -27051,8 +27578,8 @@ __export2(sub_module_exports, {
|
|
|
27051
27578
|
subModuleTask: () => subModuleTask,
|
|
27052
27579
|
updateSubModuleTask: () => updateSubModuleTask
|
|
27053
27580
|
});
|
|
27054
|
-
function addSubModuleTask(repo,
|
|
27055
|
-
return subModuleTask(["add", repo,
|
|
27581
|
+
function addSubModuleTask(repo, path32) {
|
|
27582
|
+
return subModuleTask(["add", repo, path32]);
|
|
27056
27583
|
}
|
|
27057
27584
|
function initSubModuleTask(customArgs) {
|
|
27058
27585
|
return subModuleTask(["init", ...customArgs]);
|
|
@@ -27385,8 +27912,8 @@ var require_git = __commonJS2({
|
|
|
27385
27912
|
}
|
|
27386
27913
|
return this._runTask(straightThroughStringTask2(command, this._trimmed), next);
|
|
27387
27914
|
};
|
|
27388
|
-
Git2.prototype.submoduleAdd = function(repo,
|
|
27389
|
-
return this._runTask(addSubModuleTask2(repo,
|
|
27915
|
+
Git2.prototype.submoduleAdd = function(repo, path32, then) {
|
|
27916
|
+
return this._runTask(addSubModuleTask2(repo, path32), trailingFunctionArgument2(arguments));
|
|
27390
27917
|
};
|
|
27391
27918
|
Git2.prototype.submoduleUpdate = function(args, then) {
|
|
27392
27919
|
return this._runTask(
|
|
@@ -28012,20 +28539,20 @@ async function isGitRepoDirectory(dirPath) {
|
|
|
28012
28539
|
// src/git/discover-repos.ts
|
|
28013
28540
|
async function discoverGitRepos(cwd = getBridgeWorkspaceDirectory()) {
|
|
28014
28541
|
const result = [];
|
|
28015
|
-
const cwdResolved =
|
|
28542
|
+
const cwdResolved = path5.resolve(cwd);
|
|
28016
28543
|
if (await isGitRepoDirectory(cwdResolved)) {
|
|
28017
28544
|
const remoteUrl = await getRemoteOriginUrl(cwdResolved);
|
|
28018
28545
|
result.push({ absolutePath: cwdResolved, remoteUrl });
|
|
28019
28546
|
}
|
|
28020
28547
|
let entries;
|
|
28021
28548
|
try {
|
|
28022
|
-
entries =
|
|
28549
|
+
entries = fs7.readdirSync(cwdResolved, { withFileTypes: true });
|
|
28023
28550
|
} catch {
|
|
28024
28551
|
return result;
|
|
28025
28552
|
}
|
|
28026
28553
|
for (const ent of entries) {
|
|
28027
28554
|
if (!ent.isDirectory()) continue;
|
|
28028
|
-
const childPath =
|
|
28555
|
+
const childPath = path5.join(cwdResolved, ent.name);
|
|
28029
28556
|
if (await isGitRepoDirectory(childPath)) {
|
|
28030
28557
|
const remoteUrl = await getRemoteOriginUrl(childPath);
|
|
28031
28558
|
result.push({ absolutePath: childPath, remoteUrl });
|
|
@@ -28034,22 +28561,22 @@ async function discoverGitRepos(cwd = getBridgeWorkspaceDirectory()) {
|
|
|
28034
28561
|
return result;
|
|
28035
28562
|
}
|
|
28036
28563
|
async function discoverGitReposUnderRoot(rootAbs) {
|
|
28037
|
-
const root =
|
|
28564
|
+
const root = path5.resolve(rootAbs);
|
|
28038
28565
|
const roots = [];
|
|
28039
28566
|
async function walk(dir) {
|
|
28040
28567
|
if (await isGitRepoDirectory(dir)) {
|
|
28041
|
-
roots.push(
|
|
28568
|
+
roots.push(path5.resolve(dir));
|
|
28042
28569
|
return;
|
|
28043
28570
|
}
|
|
28044
28571
|
let entries;
|
|
28045
28572
|
try {
|
|
28046
|
-
entries =
|
|
28573
|
+
entries = fs7.readdirSync(dir, { withFileTypes: true });
|
|
28047
28574
|
} catch {
|
|
28048
28575
|
return;
|
|
28049
28576
|
}
|
|
28050
28577
|
for (const ent of entries) {
|
|
28051
28578
|
if (!ent.isDirectory() || ent.name === ".git") continue;
|
|
28052
|
-
await walk(
|
|
28579
|
+
await walk(path5.join(dir, ent.name));
|
|
28053
28580
|
}
|
|
28054
28581
|
}
|
|
28055
28582
|
await walk(root);
|
|
@@ -28063,13 +28590,13 @@ async function discoverGitReposUnderRoot(rootAbs) {
|
|
|
28063
28590
|
}
|
|
28064
28591
|
|
|
28065
28592
|
// src/git/pre-turn-snapshot.ts
|
|
28066
|
-
var
|
|
28593
|
+
var execFileAsync5 = promisify6(execFile6);
|
|
28067
28594
|
function snapshotsDirForCwd(agentCwd) {
|
|
28068
|
-
return
|
|
28595
|
+
return path6.join(agentCwd, ".buildautomaton", "snapshots");
|
|
28069
28596
|
}
|
|
28070
28597
|
async function gitStashCreate(repoRoot, log2) {
|
|
28071
28598
|
try {
|
|
28072
|
-
const { stdout } = await
|
|
28599
|
+
const { stdout } = await execFileAsync5("git", ["stash", "create"], {
|
|
28073
28600
|
cwd: repoRoot,
|
|
28074
28601
|
maxBuffer: 10 * 1024 * 1024
|
|
28075
28602
|
});
|
|
@@ -28083,7 +28610,7 @@ async function gitStashCreate(repoRoot, log2) {
|
|
|
28083
28610
|
}
|
|
28084
28611
|
async function gitRun(repoRoot, args, log2, label) {
|
|
28085
28612
|
try {
|
|
28086
|
-
await
|
|
28613
|
+
await execFileAsync5("git", args, { cwd: repoRoot, maxBuffer: 10 * 1024 * 1024 });
|
|
28087
28614
|
return { ok: true };
|
|
28088
28615
|
} catch (e) {
|
|
28089
28616
|
const msg = e instanceof Error ? e.message : String(e);
|
|
@@ -28094,7 +28621,7 @@ async function gitRun(repoRoot, args, log2, label) {
|
|
|
28094
28621
|
async function resolveSnapshotRepoRoots(options) {
|
|
28095
28622
|
const { worktreePaths, fallbackCwd, log: log2 } = options;
|
|
28096
28623
|
if (worktreePaths?.length) {
|
|
28097
|
-
const uniq = [...new Set(worktreePaths.map((p) =>
|
|
28624
|
+
const uniq = [...new Set(worktreePaths.map((p) => path6.resolve(p)))];
|
|
28098
28625
|
return uniq;
|
|
28099
28626
|
}
|
|
28100
28627
|
try {
|
|
@@ -28117,7 +28644,7 @@ async function capturePreTurnSnapshot(options) {
|
|
|
28117
28644
|
}
|
|
28118
28645
|
const dir = snapshotsDirForCwd(agentCwd);
|
|
28119
28646
|
try {
|
|
28120
|
-
|
|
28647
|
+
fs8.mkdirSync(dir, { recursive: true });
|
|
28121
28648
|
} catch (e) {
|
|
28122
28649
|
return { ok: false, error: e instanceof Error ? e.message : String(e) };
|
|
28123
28650
|
}
|
|
@@ -28126,9 +28653,9 @@ async function capturePreTurnSnapshot(options) {
|
|
|
28126
28653
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
28127
28654
|
repos
|
|
28128
28655
|
};
|
|
28129
|
-
const filePath =
|
|
28656
|
+
const filePath = path6.join(dir, `${runId}.json`);
|
|
28130
28657
|
try {
|
|
28131
|
-
|
|
28658
|
+
fs8.writeFileSync(filePath, JSON.stringify(payload, null, 2), "utf8");
|
|
28132
28659
|
} catch (e) {
|
|
28133
28660
|
return { ok: false, error: e instanceof Error ? e.message : String(e) };
|
|
28134
28661
|
}
|
|
@@ -28141,7 +28668,7 @@ async function capturePreTurnSnapshot(options) {
|
|
|
28141
28668
|
async function applyPreTurnSnapshot(filePath, log2) {
|
|
28142
28669
|
let data;
|
|
28143
28670
|
try {
|
|
28144
|
-
const raw =
|
|
28671
|
+
const raw = fs8.readFileSync(filePath, "utf8");
|
|
28145
28672
|
data = JSON.parse(raw);
|
|
28146
28673
|
} catch (e) {
|
|
28147
28674
|
return { ok: false, error: e instanceof Error ? e.message : String(e) };
|
|
@@ -28164,11 +28691,11 @@ async function applyPreTurnSnapshot(filePath, log2) {
|
|
|
28164
28691
|
return { ok: true };
|
|
28165
28692
|
}
|
|
28166
28693
|
function snapshotFilePath(agentCwd, runId) {
|
|
28167
|
-
return
|
|
28694
|
+
return path6.join(snapshotsDirForCwd(agentCwd), `${runId}.json`);
|
|
28168
28695
|
}
|
|
28169
28696
|
|
|
28170
28697
|
// src/git/session-git-queue.ts
|
|
28171
|
-
var
|
|
28698
|
+
var execFileAsync6 = promisify7(execFile7);
|
|
28172
28699
|
var MAX_FULL_FILE_TEXT_BYTES = 512 * 1024;
|
|
28173
28700
|
async function readWorkspaceFileAsUtf8(absPath) {
|
|
28174
28701
|
try {
|
|
@@ -28201,7 +28728,7 @@ async function collectTurnGitDiffFromPreTurnSnapshot(options) {
|
|
|
28201
28728
|
if (!repo.stashSha) continue;
|
|
28202
28729
|
let namesRaw;
|
|
28203
28730
|
try {
|
|
28204
|
-
const { stdout } = await
|
|
28731
|
+
const { stdout } = await execFileAsync6("git", ["diff", "--name-only", repo.stashSha], {
|
|
28205
28732
|
cwd: repo.path,
|
|
28206
28733
|
maxBuffer: 10 * 1024 * 1024
|
|
28207
28734
|
});
|
|
@@ -28213,11 +28740,11 @@ async function collectTurnGitDiffFromPreTurnSnapshot(options) {
|
|
|
28213
28740
|
continue;
|
|
28214
28741
|
}
|
|
28215
28742
|
const lines = namesRaw.split("\n").map((l) => l.trim()).filter(Boolean);
|
|
28216
|
-
const slug =
|
|
28743
|
+
const slug = path7.basename(repo.path).replace(/[^\w.-]+/g, "_") || "repo";
|
|
28217
28744
|
for (const rel of lines) {
|
|
28218
28745
|
if (rel.includes("..")) continue;
|
|
28219
28746
|
try {
|
|
28220
|
-
const { stdout: patchContent } = await
|
|
28747
|
+
const { stdout: patchContent } = await execFileAsync6(
|
|
28221
28748
|
"git",
|
|
28222
28749
|
["diff", "--no-color", repo.stashSha, "--", rel],
|
|
28223
28750
|
{
|
|
@@ -28227,7 +28754,7 @@ async function collectTurnGitDiffFromPreTurnSnapshot(options) {
|
|
|
28227
28754
|
);
|
|
28228
28755
|
if (!patchContent.trim()) continue;
|
|
28229
28756
|
const displayPath = multiRepo ? `${slug}/${rel}` : rel;
|
|
28230
|
-
const absFile =
|
|
28757
|
+
const absFile = path7.join(repo.path, rel);
|
|
28231
28758
|
const newText = await readWorkspaceFileAsUtf8(absFile);
|
|
28232
28759
|
sendSessionUpdate({
|
|
28233
28760
|
type: "session_file_change",
|
|
@@ -28289,7 +28816,9 @@ async function sendPromptToAgent(options) {
|
|
|
28289
28816
|
...augmentAuthFields(errStr)
|
|
28290
28817
|
});
|
|
28291
28818
|
if (!result.success) {
|
|
28292
|
-
log2(
|
|
28819
|
+
log2(
|
|
28820
|
+
`[Agent] Prompt did not run successfully on the agent (no successful start/completion): ${result.error ?? "Unknown error"}`
|
|
28821
|
+
);
|
|
28293
28822
|
}
|
|
28294
28823
|
} catch (err) {
|
|
28295
28824
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
@@ -28307,8 +28836,8 @@ async function sendPromptToAgent(options) {
|
|
|
28307
28836
|
}
|
|
28308
28837
|
|
|
28309
28838
|
// src/agents/acp/ensure-acp-client.ts
|
|
28310
|
-
import * as
|
|
28311
|
-
import * as
|
|
28839
|
+
import * as fs9 from "node:fs";
|
|
28840
|
+
import * as path10 from "node:path";
|
|
28312
28841
|
|
|
28313
28842
|
// src/error-message.ts
|
|
28314
28843
|
function errorMessage(err) {
|
|
@@ -28328,16 +28857,16 @@ __export(claude_code_acp_client_exports, {
|
|
|
28328
28857
|
createClaudeCodeAcpClient: () => createClaudeCodeAcpClient,
|
|
28329
28858
|
detectLocalAgentPresence: () => detectLocalAgentPresence
|
|
28330
28859
|
});
|
|
28331
|
-
import { execFile as
|
|
28332
|
-
import { promisify as
|
|
28860
|
+
import { execFile as execFile9 } from "node:child_process";
|
|
28861
|
+
import { promisify as promisify9 } from "node:util";
|
|
28333
28862
|
|
|
28334
28863
|
// src/agents/acp/clients/detect-command-on-path.ts
|
|
28335
|
-
import { execFile as
|
|
28336
|
-
import { promisify as
|
|
28337
|
-
var
|
|
28864
|
+
import { execFile as execFile8 } from "node:child_process";
|
|
28865
|
+
import { promisify as promisify8 } from "node:util";
|
|
28866
|
+
var execFileAsync7 = promisify8(execFile8);
|
|
28338
28867
|
async function isCommandOnPath(command, timeoutMs = 4e3) {
|
|
28339
28868
|
try {
|
|
28340
|
-
await
|
|
28869
|
+
await execFileAsync7("which", [command], { timeout: timeoutMs });
|
|
28341
28870
|
return true;
|
|
28342
28871
|
} catch {
|
|
28343
28872
|
return false;
|
|
@@ -28345,12 +28874,12 @@ async function isCommandOnPath(command, timeoutMs = 4e3) {
|
|
|
28345
28874
|
}
|
|
28346
28875
|
|
|
28347
28876
|
// src/agents/acp/clients/claude-code-acp-client.ts
|
|
28348
|
-
var
|
|
28877
|
+
var execFileAsync8 = promisify9(execFile9);
|
|
28349
28878
|
var BACKEND_LOCAL_AGENT_TYPE = "claude-code";
|
|
28350
28879
|
async function detectLocalAgentPresence() {
|
|
28351
28880
|
if (await isCommandOnPath("claude")) return true;
|
|
28352
28881
|
try {
|
|
28353
|
-
await
|
|
28882
|
+
await execFileAsync8("npx", ["--yes", "@anthropic-ai/claude-code", "--version"], { timeout: 25e3 });
|
|
28354
28883
|
return true;
|
|
28355
28884
|
} catch {
|
|
28356
28885
|
return false;
|
|
@@ -28475,7 +29004,7 @@ async function createCursorAcpClient(options) {
|
|
|
28475
29004
|
});
|
|
28476
29005
|
const stderrCapture = createStderrCapture(child);
|
|
28477
29006
|
child.stderr?.on("data", (chunk) => stderrCapture.append(chunk));
|
|
28478
|
-
return new Promise((
|
|
29007
|
+
return new Promise((resolve15, reject) => {
|
|
28479
29008
|
child.on("error", (err) => {
|
|
28480
29009
|
child.kill();
|
|
28481
29010
|
reject(new Error(formatSpawnError2(err, command[0])));
|
|
@@ -28662,7 +29191,7 @@ async function createCursorAcpClient(options) {
|
|
|
28662
29191
|
const newResult = await send("session/new", { cwd, mcpServers: [] });
|
|
28663
29192
|
const sessionId = newResult?.sessionId ?? "";
|
|
28664
29193
|
if (!sessionId) throw new Error("Cursor ACP session/new did not return sessionId");
|
|
28665
|
-
|
|
29194
|
+
resolve15({
|
|
28666
29195
|
sessionId,
|
|
28667
29196
|
async sendPrompt(prompt, _options) {
|
|
28668
29197
|
promptOutputBuffer = "";
|
|
@@ -28848,48 +29377,48 @@ function resolveAgentCommand(preferredAgentType) {
|
|
|
28848
29377
|
}
|
|
28849
29378
|
|
|
28850
29379
|
// src/agents/acp/session-file-change-path-kind.ts
|
|
28851
|
-
import { execFileSync as
|
|
29380
|
+
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
28852
29381
|
import { existsSync, statSync } from "node:fs";
|
|
28853
29382
|
|
|
28854
29383
|
// src/git/get-git-repo-root-sync.ts
|
|
28855
|
-
import { execFileSync } from "node:child_process";
|
|
28856
|
-
import * as
|
|
29384
|
+
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
29385
|
+
import * as path8 from "node:path";
|
|
28857
29386
|
function getGitRepoRootSync(startDir) {
|
|
28858
29387
|
try {
|
|
28859
|
-
const out =
|
|
28860
|
-
cwd:
|
|
29388
|
+
const out = execFileSync2("git", ["rev-parse", "--show-toplevel"], {
|
|
29389
|
+
cwd: path8.resolve(startDir),
|
|
28861
29390
|
encoding: "utf8",
|
|
28862
29391
|
stdio: ["ignore", "pipe", "ignore"],
|
|
28863
29392
|
maxBuffer: 1024 * 1024
|
|
28864
29393
|
}).trim();
|
|
28865
|
-
return out ?
|
|
29394
|
+
return out ? path8.resolve(out) : null;
|
|
28866
29395
|
} catch {
|
|
28867
29396
|
return null;
|
|
28868
29397
|
}
|
|
28869
29398
|
}
|
|
28870
29399
|
|
|
28871
29400
|
// src/agents/acp/workspace-files.ts
|
|
28872
|
-
import { execFileSync as
|
|
29401
|
+
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
28873
29402
|
import { readFileSync as readFileSync4 } from "node:fs";
|
|
28874
|
-
import * as
|
|
29403
|
+
import * as path9 from "node:path";
|
|
28875
29404
|
function resolveWorkspaceFilePath(cwd, rawPath) {
|
|
28876
29405
|
const trimmed2 = rawPath.trim();
|
|
28877
29406
|
if (!trimmed2) return null;
|
|
28878
|
-
const normalizedCwd =
|
|
29407
|
+
const normalizedCwd = path9.resolve(cwd);
|
|
28879
29408
|
let abs = resolveSafePathUnderCwd(cwd, trimmed2);
|
|
28880
29409
|
if (!abs) {
|
|
28881
|
-
const candidate =
|
|
29410
|
+
const candidate = path9.isAbsolute(trimmed2) ? path9.normalize(trimmed2) : path9.normalize(path9.resolve(normalizedCwd, trimmed2));
|
|
28882
29411
|
const gitRoot2 = getGitRepoRootSync(cwd);
|
|
28883
29412
|
if (!gitRoot2) return null;
|
|
28884
|
-
const rel =
|
|
28885
|
-
if (rel.startsWith("..") ||
|
|
29413
|
+
const rel = path9.relative(gitRoot2, candidate);
|
|
29414
|
+
if (rel.startsWith("..") || path9.isAbsolute(rel)) return null;
|
|
28886
29415
|
abs = candidate;
|
|
28887
29416
|
}
|
|
28888
29417
|
const gitRoot = getGitRepoRootSync(cwd);
|
|
28889
29418
|
if (gitRoot) {
|
|
28890
|
-
const relFromRoot =
|
|
28891
|
-
if (!relFromRoot.startsWith("..") && !
|
|
28892
|
-
return { abs, display: relFromRoot.split(
|
|
29419
|
+
const relFromRoot = path9.relative(gitRoot, abs);
|
|
29420
|
+
if (!relFromRoot.startsWith("..") && !path9.isAbsolute(relFromRoot)) {
|
|
29421
|
+
return { abs, display: relFromRoot.split(path9.sep).join("/") };
|
|
28893
29422
|
}
|
|
28894
29423
|
}
|
|
28895
29424
|
return { abs, display: toDisplayPathRelativeToCwd(cwd, abs) };
|
|
@@ -28898,9 +29427,9 @@ function readUtf8WorkspaceFile(cwd, displayPath) {
|
|
|
28898
29427
|
if (!displayPath || displayPath.includes("..")) return "";
|
|
28899
29428
|
const gitRoot = getGitRepoRootSync(cwd);
|
|
28900
29429
|
if (gitRoot) {
|
|
28901
|
-
const abs2 =
|
|
28902
|
-
const rel =
|
|
28903
|
-
if (!rel.startsWith("..") && !
|
|
29430
|
+
const abs2 = path9.resolve(gitRoot, displayPath);
|
|
29431
|
+
const rel = path9.relative(gitRoot, abs2);
|
|
29432
|
+
if (!rel.startsWith("..") && !path9.isAbsolute(rel)) {
|
|
28904
29433
|
try {
|
|
28905
29434
|
return readFileSync4(abs2, "utf8");
|
|
28906
29435
|
} catch {
|
|
@@ -28919,9 +29448,9 @@ function tryWorkspaceDisplayToAbs(cwd, displayPath) {
|
|
|
28919
29448
|
if (!displayPath || displayPath.includes("..")) return null;
|
|
28920
29449
|
const gitRoot = getGitRepoRootSync(cwd);
|
|
28921
29450
|
if (gitRoot) {
|
|
28922
|
-
const abs =
|
|
28923
|
-
const rel =
|
|
28924
|
-
if (!rel.startsWith("..") && !
|
|
29451
|
+
const abs = path9.resolve(gitRoot, displayPath);
|
|
29452
|
+
const rel = path9.relative(gitRoot, abs);
|
|
29453
|
+
if (!rel.startsWith("..") && !path9.isAbsolute(rel)) return abs;
|
|
28925
29454
|
}
|
|
28926
29455
|
return resolveSafePathUnderCwd(cwd, displayPath);
|
|
28927
29456
|
}
|
|
@@ -28930,7 +29459,7 @@ function readGitHeadBlob(cwd, displayPath) {
|
|
|
28930
29459
|
const gitRoot = getGitRepoRootSync(cwd);
|
|
28931
29460
|
const execCwd = gitRoot ?? cwd;
|
|
28932
29461
|
try {
|
|
28933
|
-
return
|
|
29462
|
+
return execFileSync3("git", ["show", `HEAD:${displayPath}`], {
|
|
28934
29463
|
cwd: execCwd,
|
|
28935
29464
|
encoding: "utf8",
|
|
28936
29465
|
maxBuffer: 50 * 1024 * 1024
|
|
@@ -28946,7 +29475,7 @@ function gitHeadPathObjectType(cwd, displayPath) {
|
|
|
28946
29475
|
const gitRoot = getGitRepoRootSync(cwd);
|
|
28947
29476
|
if (!gitRoot) return null;
|
|
28948
29477
|
try {
|
|
28949
|
-
return
|
|
29478
|
+
return execFileSync4("git", ["cat-file", "-t", `HEAD:${displayPath}`], {
|
|
28950
29479
|
cwd: gitRoot,
|
|
28951
29480
|
encoding: "utf8"
|
|
28952
29481
|
}).trim();
|
|
@@ -29037,7 +29566,7 @@ function createBridgeOnRequest(opts) {
|
|
|
29037
29566
|
}
|
|
29038
29567
|
|
|
29039
29568
|
// src/agents/acp/hooks/extract-acp-file-diffs-from-update/paths-and-text.ts
|
|
29040
|
-
import { fileURLToPath } from "node:url";
|
|
29569
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
29041
29570
|
function readOptionalTextField(v) {
|
|
29042
29571
|
if (v === null || v === void 0) return "";
|
|
29043
29572
|
if (typeof v === "string") return v;
|
|
@@ -29047,7 +29576,7 @@ function normalizePathField(raw) {
|
|
|
29047
29576
|
const t = raw.trim();
|
|
29048
29577
|
if (t.startsWith("file://")) {
|
|
29049
29578
|
try {
|
|
29050
|
-
return
|
|
29579
|
+
return fileURLToPath2(t);
|
|
29051
29580
|
} catch {
|
|
29052
29581
|
return t;
|
|
29053
29582
|
}
|
|
@@ -29489,10 +30018,10 @@ function buildAcpSessionBridgeHooks(opts) {
|
|
|
29489
30018
|
// src/agents/acp/ensure-acp-client.ts
|
|
29490
30019
|
async function ensureAcpClient(options) {
|
|
29491
30020
|
const { state, preferredAgentType, mode, cwd, routing, sendSessionUpdate, sendRequest, log: log2 } = options;
|
|
29492
|
-
const targetCwd =
|
|
30021
|
+
const targetCwd = path10.resolve(
|
|
29493
30022
|
cwd != null && String(cwd).trim() !== "" ? String(cwd).trim() : getBridgeWorkspaceDirectory()
|
|
29494
30023
|
);
|
|
29495
|
-
if (state.acpHandle && state.lastAcpCwd != null &&
|
|
30024
|
+
if (state.acpHandle && state.lastAcpCwd != null && path10.resolve(state.lastAcpCwd) !== path10.resolve(targetCwd)) {
|
|
29496
30025
|
try {
|
|
29497
30026
|
state.acpHandle.disconnect();
|
|
29498
30027
|
} catch {
|
|
@@ -29524,7 +30053,7 @@ async function ensureAcpClient(options) {
|
|
|
29524
30053
|
if (!state.acpStartPromise) {
|
|
29525
30054
|
let statOk = false;
|
|
29526
30055
|
try {
|
|
29527
|
-
const st =
|
|
30056
|
+
const st = fs9.statSync(targetCwd);
|
|
29528
30057
|
statOk = st.isDirectory();
|
|
29529
30058
|
if (!statOk) {
|
|
29530
30059
|
state.lastAcpStartError = `Agent cwd is not a directory: ${targetCwd}`;
|
|
@@ -29720,12 +30249,12 @@ async function createAcpManager(options) {
|
|
|
29720
30249
|
}
|
|
29721
30250
|
|
|
29722
30251
|
// src/worktrees/session-worktree-manager.ts
|
|
29723
|
-
import * as
|
|
29724
|
-
import
|
|
30252
|
+
import * as path16 from "node:path";
|
|
30253
|
+
import os4 from "node:os";
|
|
29725
30254
|
|
|
29726
30255
|
// src/worktrees/prepare-new-session-worktrees.ts
|
|
29727
|
-
import * as
|
|
29728
|
-
import * as
|
|
30256
|
+
import * as fs11 from "node:fs";
|
|
30257
|
+
import * as path12 from "node:path";
|
|
29729
30258
|
|
|
29730
30259
|
// src/git/worktree-add.ts
|
|
29731
30260
|
async function gitWorktreeAddBranch(mainRepoPath, worktreePath, branch) {
|
|
@@ -29734,12 +30263,12 @@ async function gitWorktreeAddBranch(mainRepoPath, worktreePath, branch) {
|
|
|
29734
30263
|
}
|
|
29735
30264
|
|
|
29736
30265
|
// src/worktrees/worktree-layout-file.ts
|
|
29737
|
-
import * as
|
|
29738
|
-
import * as
|
|
29739
|
-
import
|
|
30266
|
+
import * as fs10 from "node:fs";
|
|
30267
|
+
import * as path11 from "node:path";
|
|
30268
|
+
import os3 from "node:os";
|
|
29740
30269
|
var LAYOUT_FILENAME = "worktree-launcher-layout.json";
|
|
29741
30270
|
function defaultWorktreeLayoutPath() {
|
|
29742
|
-
return
|
|
30271
|
+
return path11.join(os3.homedir(), ".buildautomaton", LAYOUT_FILENAME);
|
|
29743
30272
|
}
|
|
29744
30273
|
function normalizeLoadedLayout(raw) {
|
|
29745
30274
|
if (raw && typeof raw === "object" && "launcherCwds" in raw) {
|
|
@@ -29751,8 +30280,8 @@ function normalizeLoadedLayout(raw) {
|
|
|
29751
30280
|
function loadWorktreeLayout() {
|
|
29752
30281
|
try {
|
|
29753
30282
|
const p = defaultWorktreeLayoutPath();
|
|
29754
|
-
if (!
|
|
29755
|
-
const raw = JSON.parse(
|
|
30283
|
+
if (!fs10.existsSync(p)) return { launcherCwds: [] };
|
|
30284
|
+
const raw = JSON.parse(fs10.readFileSync(p, "utf8"));
|
|
29756
30285
|
return normalizeLoadedLayout(raw);
|
|
29757
30286
|
} catch {
|
|
29758
30287
|
return { launcherCwds: [] };
|
|
@@ -29760,18 +30289,18 @@ function loadWorktreeLayout() {
|
|
|
29760
30289
|
}
|
|
29761
30290
|
function saveWorktreeLayout(layout) {
|
|
29762
30291
|
try {
|
|
29763
|
-
const dir =
|
|
29764
|
-
|
|
29765
|
-
|
|
30292
|
+
const dir = path11.dirname(defaultWorktreeLayoutPath());
|
|
30293
|
+
fs10.mkdirSync(dir, { recursive: true });
|
|
30294
|
+
fs10.writeFileSync(defaultWorktreeLayoutPath(), JSON.stringify(layout, null, 2), "utf8");
|
|
29766
30295
|
} catch {
|
|
29767
30296
|
}
|
|
29768
30297
|
}
|
|
29769
30298
|
function baseNameSafe(abs) {
|
|
29770
|
-
return
|
|
30299
|
+
return path11.basename(abs).replace(/[^a-zA-Z0-9._-]+/g, "-") || "cwd";
|
|
29771
30300
|
}
|
|
29772
30301
|
function allocateDirNameForLauncherCwd(layout, launcherCwdAbs) {
|
|
29773
|
-
const norm =
|
|
29774
|
-
const existing = layout.launcherCwds.find((e) =>
|
|
30302
|
+
const norm = path11.resolve(launcherCwdAbs);
|
|
30303
|
+
const existing = layout.launcherCwds.find((e) => path11.resolve(e.absolutePath) === norm);
|
|
29775
30304
|
if (existing) return existing.dirName;
|
|
29776
30305
|
const base = baseNameSafe(norm);
|
|
29777
30306
|
const used = new Set(layout.launcherCwds.map((e) => e.dirName));
|
|
@@ -29789,9 +30318,9 @@ function allocateDirNameForLauncherCwd(layout, launcherCwdAbs) {
|
|
|
29789
30318
|
// src/worktrees/prepare-new-session-worktrees.ts
|
|
29790
30319
|
async function prepareNewSessionWorktrees(options) {
|
|
29791
30320
|
const { rootAbs, launcherCwd, sessionId, layout, log: log2 } = options;
|
|
29792
|
-
const launcherResolved =
|
|
30321
|
+
const launcherResolved = path12.resolve(launcherCwd);
|
|
29793
30322
|
const cwdKey = allocateDirNameForLauncherCwd(layout, launcherResolved);
|
|
29794
|
-
const agentMirrorRoot =
|
|
30323
|
+
const agentMirrorRoot = path12.join(rootAbs, cwdKey);
|
|
29795
30324
|
const repos = await discoverGitReposUnderRoot(launcherResolved);
|
|
29796
30325
|
if (repos.length === 0) {
|
|
29797
30326
|
log2("[worktrees] No Git repositories under launcher working directory; skipping worktree creation.");
|
|
@@ -29799,13 +30328,13 @@ async function prepareNewSessionWorktrees(options) {
|
|
|
29799
30328
|
}
|
|
29800
30329
|
const branch = `session-${sessionId}`;
|
|
29801
30330
|
const worktreePaths = [];
|
|
29802
|
-
|
|
30331
|
+
fs11.mkdirSync(agentMirrorRoot, { recursive: true });
|
|
29803
30332
|
for (const repo of repos) {
|
|
29804
|
-
let rel =
|
|
29805
|
-
if (rel.startsWith("..") ||
|
|
30333
|
+
let rel = path12.relative(launcherResolved, repo.absolutePath);
|
|
30334
|
+
if (rel.startsWith("..") || path12.isAbsolute(rel)) continue;
|
|
29806
30335
|
const relNorm = rel === "" ? "." : rel;
|
|
29807
|
-
const wtPath =
|
|
29808
|
-
|
|
30336
|
+
const wtPath = path12.join(agentMirrorRoot, relNorm, sessionId);
|
|
30337
|
+
fs11.mkdirSync(path12.dirname(wtPath), { recursive: true });
|
|
29809
30338
|
try {
|
|
29810
30339
|
await gitWorktreeAddBranch(repo.absolutePath, wtPath, branch);
|
|
29811
30340
|
log2(`[worktrees] Added worktree ${wtPath} (branch ${branch}).`);
|
|
@@ -29842,23 +30371,23 @@ async function renameSessionWorktreeBranches(paths, newBranch, log2) {
|
|
|
29842
30371
|
}
|
|
29843
30372
|
|
|
29844
30373
|
// src/worktrees/remove-session-worktrees.ts
|
|
29845
|
-
import * as
|
|
30374
|
+
import * as fs14 from "node:fs";
|
|
29846
30375
|
|
|
29847
30376
|
// src/git/worktree-remove.ts
|
|
29848
|
-
import * as
|
|
30377
|
+
import * as fs13 from "node:fs";
|
|
29849
30378
|
|
|
29850
30379
|
// src/git/resolve-main-repo-from-git-file.ts
|
|
29851
|
-
import * as
|
|
29852
|
-
import * as
|
|
30380
|
+
import * as fs12 from "node:fs";
|
|
30381
|
+
import * as path13 from "node:path";
|
|
29853
30382
|
function resolveMainRepoFromWorktreeGitFile(wt) {
|
|
29854
|
-
const gitDirFile =
|
|
29855
|
-
if (!
|
|
29856
|
-
const first2 =
|
|
30383
|
+
const gitDirFile = path13.join(wt, ".git");
|
|
30384
|
+
if (!fs12.existsSync(gitDirFile) || !fs12.statSync(gitDirFile).isFile()) return "";
|
|
30385
|
+
const first2 = fs12.readFileSync(gitDirFile, "utf8").trim();
|
|
29857
30386
|
const m = first2.match(/^gitdir:\s*(.+)$/im);
|
|
29858
30387
|
if (!m) return "";
|
|
29859
|
-
const gitWorktreePath =
|
|
29860
|
-
const gitDir =
|
|
29861
|
-
return
|
|
30388
|
+
const gitWorktreePath = path13.resolve(wt, m[1].trim());
|
|
30389
|
+
const gitDir = path13.dirname(path13.dirname(gitWorktreePath));
|
|
30390
|
+
return path13.dirname(gitDir);
|
|
29862
30391
|
}
|
|
29863
30392
|
|
|
29864
30393
|
// src/git/worktree-remove.ts
|
|
@@ -29867,7 +30396,7 @@ async function gitWorktreeRemoveForce(worktreePath) {
|
|
|
29867
30396
|
if (mainRepo) {
|
|
29868
30397
|
await simpleGit(mainRepo).raw(["worktree", "remove", "--force", worktreePath]);
|
|
29869
30398
|
} else {
|
|
29870
|
-
|
|
30399
|
+
fs13.rmSync(worktreePath, { recursive: true, force: true });
|
|
29871
30400
|
}
|
|
29872
30401
|
}
|
|
29873
30402
|
|
|
@@ -29880,14 +30409,14 @@ async function removeSessionWorktrees(paths, log2) {
|
|
|
29880
30409
|
} catch (e) {
|
|
29881
30410
|
log2(`[worktrees] Remove failed for ${wt}: ${e instanceof Error ? e.message : String(e)}`);
|
|
29882
30411
|
try {
|
|
29883
|
-
|
|
30412
|
+
fs14.rmSync(wt, { recursive: true, force: true });
|
|
29884
30413
|
} catch {
|
|
29885
30414
|
}
|
|
29886
30415
|
}
|
|
29887
30416
|
}
|
|
29888
30417
|
}
|
|
29889
30418
|
|
|
29890
|
-
// src/git/working-tree-status.ts
|
|
30419
|
+
// src/git/working-directory/status/working-tree-status.ts
|
|
29891
30420
|
async function tryConfigGet(g, key) {
|
|
29892
30421
|
try {
|
|
29893
30422
|
const out = await g.raw(["config", "--get", key]);
|
|
@@ -29897,11 +30426,24 @@ async function tryConfigGet(g, key) {
|
|
|
29897
30426
|
return null;
|
|
29898
30427
|
}
|
|
29899
30428
|
}
|
|
30429
|
+
async function revParseSafe(g, ref) {
|
|
30430
|
+
try {
|
|
30431
|
+
const v = (await g.raw(["rev-parse", ref])).trim();
|
|
30432
|
+
return v || null;
|
|
30433
|
+
} catch {
|
|
30434
|
+
return null;
|
|
30435
|
+
}
|
|
30436
|
+
}
|
|
29900
30437
|
async function resolveRemoteTrackingRefForAhead(g) {
|
|
29901
30438
|
try {
|
|
29902
|
-
await g.raw(["rev-parse", "--verify", "@{
|
|
29903
|
-
return "@{
|
|
30439
|
+
await g.raw(["rev-parse", "--verify", "HEAD@{upstream}"]);
|
|
30440
|
+
return "HEAD@{upstream}";
|
|
29904
30441
|
} catch {
|
|
30442
|
+
try {
|
|
30443
|
+
await g.raw(["rev-parse", "--verify", "@{u}"]);
|
|
30444
|
+
return "@{u}";
|
|
30445
|
+
} catch {
|
|
30446
|
+
}
|
|
29905
30447
|
}
|
|
29906
30448
|
const branch = (await g.raw(["rev-parse", "--abbrev-ref", "HEAD"])).trim();
|
|
29907
30449
|
if (!branch || branch === "HEAD") return null;
|
|
@@ -29924,16 +30466,76 @@ async function resolveRemoteTrackingRefForAhead(g) {
|
|
|
29924
30466
|
return null;
|
|
29925
30467
|
}
|
|
29926
30468
|
}
|
|
30469
|
+
async function remoteForCurrentBranch(g) {
|
|
30470
|
+
const branch = (await g.raw(["rev-parse", "--abbrev-ref", "HEAD"])).trim();
|
|
30471
|
+
if (!branch || branch === "HEAD") return "origin";
|
|
30472
|
+
return await tryConfigGet(g, `branch.${branch}.remote`) ?? "origin";
|
|
30473
|
+
}
|
|
30474
|
+
async function resolveDefaultRemoteBranchRef(g, remote) {
|
|
30475
|
+
const headSym = `refs/remotes/${remote}/HEAD`;
|
|
30476
|
+
try {
|
|
30477
|
+
const resolved = (await g.raw(["symbolic-ref", "-q", "--verify", headSym])).trim();
|
|
30478
|
+
if (resolved.startsWith("refs/remotes/")) return resolved;
|
|
30479
|
+
} catch {
|
|
30480
|
+
}
|
|
30481
|
+
for (const name of ["main", "master", "trunk", "develop"]) {
|
|
30482
|
+
const r = `refs/remotes/${remote}/${name}`;
|
|
30483
|
+
try {
|
|
30484
|
+
await g.raw(["rev-parse", "--verify", r]);
|
|
30485
|
+
return r;
|
|
30486
|
+
} catch {
|
|
30487
|
+
}
|
|
30488
|
+
}
|
|
30489
|
+
return null;
|
|
30490
|
+
}
|
|
30491
|
+
async function resolveBaseShaForUnpushedCommits(g) {
|
|
30492
|
+
const trackingRef = await resolveRemoteTrackingRefForAhead(g);
|
|
30493
|
+
if (trackingRef) {
|
|
30494
|
+
const sha = await revParseSafe(g, trackingRef);
|
|
30495
|
+
if (sha) return sha;
|
|
30496
|
+
}
|
|
30497
|
+
const remote = await remoteForCurrentBranch(g);
|
|
30498
|
+
const defaultRef = await resolveDefaultRemoteBranchRef(g, remote);
|
|
30499
|
+
if (!defaultRef) return null;
|
|
30500
|
+
return revParseSafe(g, defaultRef);
|
|
30501
|
+
}
|
|
30502
|
+
function parseLogShaDateSubjectLines(raw) {
|
|
30503
|
+
const out = [];
|
|
30504
|
+
for (const line of String(raw).split("\n")) {
|
|
30505
|
+
const l = line.trimEnd();
|
|
30506
|
+
if (!l.trim()) continue;
|
|
30507
|
+
const parts = l.split(" ");
|
|
30508
|
+
if (parts.length < 3) continue;
|
|
30509
|
+
const sha = parts[0].trim();
|
|
30510
|
+
const committedAt = parts[1].trim();
|
|
30511
|
+
const subject = parts.slice(2).join(" ").trim();
|
|
30512
|
+
if (!/^[0-9a-f]{7,40}$/i.test(sha)) continue;
|
|
30513
|
+
out.push({ sha, shortSha: sha.slice(0, 7), subject, committedAt });
|
|
30514
|
+
}
|
|
30515
|
+
return out;
|
|
30516
|
+
}
|
|
30517
|
+
async function gitLogNotReachableFromBase(g, baseSha, headSha) {
|
|
30518
|
+
if (baseSha === headSha) return [];
|
|
30519
|
+
try {
|
|
30520
|
+
const logOut = await g.raw(["log", "--format=%H %cI %s", `${baseSha}..${headSha}`]);
|
|
30521
|
+
return parseLogShaDateSubjectLines(logOut);
|
|
30522
|
+
} catch {
|
|
30523
|
+
return [];
|
|
30524
|
+
}
|
|
30525
|
+
}
|
|
29927
30526
|
async function commitsAheadOfRemoteTracking(repoDir) {
|
|
29928
30527
|
const g = simpleGit(repoDir);
|
|
29929
|
-
const
|
|
29930
|
-
if (!
|
|
29931
|
-
const
|
|
29932
|
-
|
|
29933
|
-
|
|
29934
|
-
|
|
29935
|
-
|
|
29936
|
-
|
|
30528
|
+
const headSha = await revParseSafe(g, "HEAD");
|
|
30529
|
+
if (!headSha) return 0;
|
|
30530
|
+
const baseSha = await resolveBaseShaForUnpushedCommits(g);
|
|
30531
|
+
if (!baseSha || baseSha === headSha) return 0;
|
|
30532
|
+
try {
|
|
30533
|
+
const out = await g.raw(["rev-list", "--count", `${baseSha}..${headSha}`]);
|
|
30534
|
+
const n = parseInt(String(out).trim(), 10);
|
|
30535
|
+
return Number.isNaN(n) ? 0 : n;
|
|
30536
|
+
} catch {
|
|
30537
|
+
return 0;
|
|
30538
|
+
}
|
|
29937
30539
|
}
|
|
29938
30540
|
async function getRepoWorkingTreeStatus(repoDir) {
|
|
29939
30541
|
const g = simpleGit(repoDir);
|
|
@@ -29942,6 +30544,14 @@ async function getRepoWorkingTreeStatus(repoDir) {
|
|
|
29942
30544
|
const ahead = await commitsAheadOfRemoteTracking(repoDir);
|
|
29943
30545
|
return { hasUncommittedChanges, hasUnpushedCommits: ahead > 0 };
|
|
29944
30546
|
}
|
|
30547
|
+
async function listUnpushedCommits(repoDir) {
|
|
30548
|
+
const g = simpleGit(repoDir);
|
|
30549
|
+
const headSha = await revParseSafe(g, "HEAD");
|
|
30550
|
+
if (!headSha) return [];
|
|
30551
|
+
const baseSha = await resolveBaseShaForUnpushedCommits(g);
|
|
30552
|
+
if (!baseSha) return [];
|
|
30553
|
+
return gitLogNotReachableFromBase(g, baseSha, headSha);
|
|
30554
|
+
}
|
|
29945
30555
|
async function aggregateSessionPathsWorkingTreeStatus(paths) {
|
|
29946
30556
|
let hasUncommittedChanges = false;
|
|
29947
30557
|
let hasUnpushedCommits = false;
|
|
@@ -29961,6 +30571,477 @@ async function pushAheadOfUpstreamForPaths(paths) {
|
|
|
29961
30571
|
}
|
|
29962
30572
|
}
|
|
29963
30573
|
|
|
30574
|
+
// src/git/working-directory/changes/types.ts
|
|
30575
|
+
var MAX_PATCH_CHARS = 35e4;
|
|
30576
|
+
|
|
30577
|
+
// src/git/working-directory/changes/repo-format.ts
|
|
30578
|
+
function posixJoinDirFile(dir, file2) {
|
|
30579
|
+
const d = dir === "." || dir === "" ? "" : dir.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
30580
|
+
const f = file2.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
30581
|
+
return d ? `${d}/${f}` : f;
|
|
30582
|
+
}
|
|
30583
|
+
function formatRepoShortTitle(remoteUrl, repoRelPath) {
|
|
30584
|
+
const u = remoteUrl.trim();
|
|
30585
|
+
if (u) {
|
|
30586
|
+
try {
|
|
30587
|
+
if (u.startsWith("git@")) {
|
|
30588
|
+
const colon = u.indexOf(":");
|
|
30589
|
+
if (colon > 0) {
|
|
30590
|
+
const pathPart = u.slice(colon + 1).replace(/\.git$/i, "").replace(/\/+$/, "");
|
|
30591
|
+
if (pathPart.includes("/")) return pathPart;
|
|
30592
|
+
}
|
|
30593
|
+
} else {
|
|
30594
|
+
const parsed = new URL(u);
|
|
30595
|
+
const p = parsed.pathname.replace(/^\//, "").replace(/\.git$/i, "");
|
|
30596
|
+
const parts = p.split("/").filter(Boolean);
|
|
30597
|
+
if (parts.length >= 2) {
|
|
30598
|
+
return `${parts[parts.length - 2]}/${parts[parts.length - 1]}`;
|
|
30599
|
+
}
|
|
30600
|
+
if (parts.length === 1) return parts[0];
|
|
30601
|
+
}
|
|
30602
|
+
} catch {
|
|
30603
|
+
}
|
|
30604
|
+
}
|
|
30605
|
+
if (repoRelPath && repoRelPath !== ".") {
|
|
30606
|
+
const segments = repoRelPath.split("/").filter(Boolean);
|
|
30607
|
+
const last2 = segments[segments.length - 1];
|
|
30608
|
+
if (last2) return last2;
|
|
30609
|
+
}
|
|
30610
|
+
return "Repository";
|
|
30611
|
+
}
|
|
30612
|
+
function formatRemoteDisplayLabel(remoteUrl) {
|
|
30613
|
+
const u = remoteUrl.trim();
|
|
30614
|
+
if (!u) return "";
|
|
30615
|
+
let hostPath = u;
|
|
30616
|
+
try {
|
|
30617
|
+
if (u.startsWith("git@")) {
|
|
30618
|
+
const rest = u.slice("git@".length);
|
|
30619
|
+
const slash = rest.indexOf(":");
|
|
30620
|
+
if (slash > 0) hostPath = `${rest.slice(0, slash)}/${rest.slice(slash + 1)}`;
|
|
30621
|
+
} else {
|
|
30622
|
+
const parsed = new URL(u);
|
|
30623
|
+
hostPath = `${parsed.hostname}${parsed.pathname}`.replace(/\/\.git$/i, "").replace(/\.git$/i, "");
|
|
30624
|
+
}
|
|
30625
|
+
} catch {
|
|
30626
|
+
hostPath = u.replace(/^https?:\/\//i, "").replace(/\.git$/i, "");
|
|
30627
|
+
}
|
|
30628
|
+
return `origin \xB7 ${hostPath}`;
|
|
30629
|
+
}
|
|
30630
|
+
|
|
30631
|
+
// src/git/working-directory/changes/get-working-tree-change-repo-details.ts
|
|
30632
|
+
import * as path15 from "node:path";
|
|
30633
|
+
|
|
30634
|
+
// src/git/working-directory/changes/parse-git-status.ts
|
|
30635
|
+
function parseNameStatusLines(lines) {
|
|
30636
|
+
const m = /* @__PURE__ */ new Map();
|
|
30637
|
+
for (const line of lines) {
|
|
30638
|
+
if (!line.trim()) continue;
|
|
30639
|
+
const tabParts = line.split(" ");
|
|
30640
|
+
if (tabParts.length < 2) continue;
|
|
30641
|
+
const status = tabParts[0].trim();
|
|
30642
|
+
const code = status[0];
|
|
30643
|
+
if (code === "A") {
|
|
30644
|
+
m.set(tabParts[tabParts.length - 1], "added");
|
|
30645
|
+
} else if (code === "D") {
|
|
30646
|
+
m.set(tabParts[tabParts.length - 1], "removed");
|
|
30647
|
+
} else if (code === "R" || code === "C") {
|
|
30648
|
+
if (tabParts.length >= 3) m.set(tabParts[tabParts.length - 1], "modified");
|
|
30649
|
+
} else if (code === "M" || code === "U" || code === "T") {
|
|
30650
|
+
m.set(tabParts[tabParts.length - 1], "modified");
|
|
30651
|
+
}
|
|
30652
|
+
}
|
|
30653
|
+
return m;
|
|
30654
|
+
}
|
|
30655
|
+
function parseNumstatFirstLine(line) {
|
|
30656
|
+
const parts = line.split(" ");
|
|
30657
|
+
if (parts.length < 3) return null;
|
|
30658
|
+
const [a, d] = parts;
|
|
30659
|
+
const additions = a === "-" ? 0 : parseInt(String(a), 10) || 0;
|
|
30660
|
+
const deletions = d === "-" ? 0 : parseInt(String(d), 10) || 0;
|
|
30661
|
+
return { additions, deletions };
|
|
30662
|
+
}
|
|
30663
|
+
function parseNumstat(lines) {
|
|
30664
|
+
const m = /* @__PURE__ */ new Map();
|
|
30665
|
+
for (const line of lines) {
|
|
30666
|
+
if (!line.trim()) continue;
|
|
30667
|
+
const parts = line.split(" ");
|
|
30668
|
+
if (parts.length < 3) continue;
|
|
30669
|
+
const [a, d, p] = parts;
|
|
30670
|
+
const additions = a === "-" ? 0 : parseInt(String(a), 10) || 0;
|
|
30671
|
+
const deletions = d === "-" ? 0 : parseInt(String(d), 10) || 0;
|
|
30672
|
+
m.set(p, { additions, deletions });
|
|
30673
|
+
}
|
|
30674
|
+
return m;
|
|
30675
|
+
}
|
|
30676
|
+
async function numstatFromGitNoIndex(g, pathInRepo) {
|
|
30677
|
+
const devNull = process.platform === "win32" ? "NUL" : "/dev/null";
|
|
30678
|
+
try {
|
|
30679
|
+
const out = await g.raw(["diff", "--numstat", "--no-index", "--", devNull, pathInRepo]);
|
|
30680
|
+
const first2 = String(out).split("\n").find((l) => l.trim()) ?? "";
|
|
30681
|
+
return parseNumstatFirstLine(first2);
|
|
30682
|
+
} catch {
|
|
30683
|
+
return null;
|
|
30684
|
+
}
|
|
30685
|
+
}
|
|
30686
|
+
|
|
30687
|
+
// src/git/working-directory/changes/patch-truncate.ts
|
|
30688
|
+
function truncatePatch(s) {
|
|
30689
|
+
if (s.length <= MAX_PATCH_CHARS) return s;
|
|
30690
|
+
return `${s.slice(0, MAX_PATCH_CHARS)}
|
|
30691
|
+
|
|
30692
|
+
\u2026 (diff truncated)`;
|
|
30693
|
+
}
|
|
30694
|
+
|
|
30695
|
+
// src/git/working-directory/changes/list-changed-files-for-commit.ts
|
|
30696
|
+
var EMPTY_TREE = "4b825dc642cb6eb9a060e54bf8d69288fbee4904";
|
|
30697
|
+
async function parentForCommitDiff(g, sha) {
|
|
30698
|
+
try {
|
|
30699
|
+
return (await g.raw(["rev-parse", `${sha}^1`])).trim();
|
|
30700
|
+
} catch {
|
|
30701
|
+
try {
|
|
30702
|
+
return (await g.raw(["rev-parse", `${sha}^`])).trim();
|
|
30703
|
+
} catch {
|
|
30704
|
+
return EMPTY_TREE;
|
|
30705
|
+
}
|
|
30706
|
+
}
|
|
30707
|
+
}
|
|
30708
|
+
async function listChangedFilesForCommit(repoGitCwd, repoRelPath, commitSha) {
|
|
30709
|
+
const g = simpleGit(repoGitCwd);
|
|
30710
|
+
const parent = await parentForCommitDiff(g, commitSha);
|
|
30711
|
+
const range = `${parent}..${commitSha}`;
|
|
30712
|
+
const [nameStatusRaw, numstatRaw] = await Promise.all([
|
|
30713
|
+
g.raw(["diff", "--name-status", range]).catch(() => ""),
|
|
30714
|
+
g.raw(["diff", "--numstat", range]).catch(() => "")
|
|
30715
|
+
]);
|
|
30716
|
+
const kindByPath = parseNameStatusLines(String(nameStatusRaw).split("\n"));
|
|
30717
|
+
const numByPath = parseNumstat(String(numstatRaw).split("\n"));
|
|
30718
|
+
const paths = new Set([...kindByPath.keys(), ...numByPath.keys()].filter(Boolean));
|
|
30719
|
+
const rows = [];
|
|
30720
|
+
const normRel = repoRelPath === "." || repoRelPath === "" ? "." : repoRelPath;
|
|
30721
|
+
for (const pathInRepo of paths) {
|
|
30722
|
+
const relLauncher = posixJoinDirFile(normRel, pathInRepo.replace(/\\/g, "/"));
|
|
30723
|
+
const nums = numByPath.get(pathInRepo);
|
|
30724
|
+
let additions = nums?.additions ?? 0;
|
|
30725
|
+
let deletions = nums?.deletions ?? 0;
|
|
30726
|
+
let change = kindByPath.get(pathInRepo) ?? "modified";
|
|
30727
|
+
if (!kindByPath.has(pathInRepo) && nums) {
|
|
30728
|
+
if (additions > 0 && deletions === 0) change = "added";
|
|
30729
|
+
else if (deletions > 0 && additions === 0) change = "removed";
|
|
30730
|
+
else change = "modified";
|
|
30731
|
+
}
|
|
30732
|
+
rows.push({ pathRelLauncher: relLauncher, additions, deletions, change });
|
|
30733
|
+
}
|
|
30734
|
+
for (const row of rows) {
|
|
30735
|
+
let pathInRepo;
|
|
30736
|
+
if (normRel === ".") {
|
|
30737
|
+
pathInRepo = row.pathRelLauncher;
|
|
30738
|
+
} else if (row.pathRelLauncher.startsWith(`${normRel}/`)) {
|
|
30739
|
+
pathInRepo = row.pathRelLauncher.slice(normRel.length + 1);
|
|
30740
|
+
} else {
|
|
30741
|
+
pathInRepo = row.pathRelLauncher;
|
|
30742
|
+
}
|
|
30743
|
+
const raw = await g.raw(["diff", "-U20000", range, "--", pathInRepo]).catch(() => "");
|
|
30744
|
+
const t = String(raw).trim();
|
|
30745
|
+
row.patchContent = t ? truncatePatch(t) : void 0;
|
|
30746
|
+
}
|
|
30747
|
+
rows.sort((a, b) => a.pathRelLauncher.localeCompare(b.pathRelLauncher));
|
|
30748
|
+
return rows;
|
|
30749
|
+
}
|
|
30750
|
+
|
|
30751
|
+
// src/git/working-directory/changes/list-changed-files-for-repo.ts
|
|
30752
|
+
import * as fs16 from "node:fs";
|
|
30753
|
+
import * as path14 from "node:path";
|
|
30754
|
+
|
|
30755
|
+
// src/git/working-directory/changes/count-lines.ts
|
|
30756
|
+
import { createReadStream } from "node:fs";
|
|
30757
|
+
import * as readline2 from "node:readline";
|
|
30758
|
+
async function countTextFileLines(absFile) {
|
|
30759
|
+
let bytes = 0;
|
|
30760
|
+
const maxBytes = 512e3;
|
|
30761
|
+
let lines = 0;
|
|
30762
|
+
const stream = createReadStream(absFile, { encoding: "utf8" });
|
|
30763
|
+
const rl = readline2.createInterface({ input: stream, crlfDelay: Infinity });
|
|
30764
|
+
for await (const _line of rl) {
|
|
30765
|
+
lines += 1;
|
|
30766
|
+
bytes += Buffer.byteLength(String(_line), "utf8") + 1;
|
|
30767
|
+
if (bytes > maxBytes) {
|
|
30768
|
+
rl.close();
|
|
30769
|
+
stream.destroy();
|
|
30770
|
+
return lines;
|
|
30771
|
+
}
|
|
30772
|
+
}
|
|
30773
|
+
return lines;
|
|
30774
|
+
}
|
|
30775
|
+
|
|
30776
|
+
// src/git/working-directory/changes/hydrate-patch.ts
|
|
30777
|
+
import * as fs15 from "node:fs";
|
|
30778
|
+
var UNIFIED_HUNK_HEADER_RE = /^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/;
|
|
30779
|
+
var MAX_HYDRATE_LINES_PER_GAP = 8e3;
|
|
30780
|
+
var MAX_HYDRATE_LINES_PER_FILE = 8e4;
|
|
30781
|
+
async function readGitBlobLines(repoCwd, pathInRepo) {
|
|
30782
|
+
try {
|
|
30783
|
+
const rel = pathInRepo.replace(/\\/g, "/");
|
|
30784
|
+
const raw = await simpleGit(repoCwd).show([`HEAD:${rel}`]);
|
|
30785
|
+
return String(raw).split(/\r?\n/);
|
|
30786
|
+
} catch {
|
|
30787
|
+
return null;
|
|
30788
|
+
}
|
|
30789
|
+
}
|
|
30790
|
+
async function readWorktreeFileLines(abs) {
|
|
30791
|
+
try {
|
|
30792
|
+
const raw = await fs15.promises.readFile(abs, "utf8");
|
|
30793
|
+
return raw.split(/\r?\n/);
|
|
30794
|
+
} catch {
|
|
30795
|
+
return null;
|
|
30796
|
+
}
|
|
30797
|
+
}
|
|
30798
|
+
async function hydrateUnifiedPatchWithFileContext(patch, absFile, repoGitCwd, pathInRepo, change) {
|
|
30799
|
+
if (!patch.trim() || patch.includes("Binary files")) return patch;
|
|
30800
|
+
const all = patch.split("\n");
|
|
30801
|
+
const out = [];
|
|
30802
|
+
let prevOldEnd = 0;
|
|
30803
|
+
let prevNewEnd = 0;
|
|
30804
|
+
let injectedTotal = 0;
|
|
30805
|
+
let i = 0;
|
|
30806
|
+
let blobCache;
|
|
30807
|
+
let diskCache;
|
|
30808
|
+
const blobLines = async () => {
|
|
30809
|
+
if (blobCache !== void 0) return blobCache;
|
|
30810
|
+
blobCache = await readGitBlobLines(repoGitCwd, pathInRepo);
|
|
30811
|
+
return blobCache;
|
|
30812
|
+
};
|
|
30813
|
+
const diskLines = async () => {
|
|
30814
|
+
if (diskCache !== void 0) return diskCache;
|
|
30815
|
+
diskCache = await readWorktreeFileLines(absFile);
|
|
30816
|
+
return diskCache;
|
|
30817
|
+
};
|
|
30818
|
+
while (i < all.length) {
|
|
30819
|
+
const line = all[i];
|
|
30820
|
+
const hm = line.match(UNIFIED_HUNK_HEADER_RE);
|
|
30821
|
+
if (!hm) {
|
|
30822
|
+
out.push(line);
|
|
30823
|
+
i++;
|
|
30824
|
+
continue;
|
|
30825
|
+
}
|
|
30826
|
+
const oldStart = parseInt(hm[1], 10) || 0;
|
|
30827
|
+
const newStart = parseInt(hm[3], 10) || 0;
|
|
30828
|
+
const gapOldStart = prevOldEnd + 1;
|
|
30829
|
+
const gapOldEnd = oldStart - 1;
|
|
30830
|
+
const gapNewStart = prevNewEnd + 1;
|
|
30831
|
+
const gapNewEnd = newStart - 1;
|
|
30832
|
+
if (injectedTotal < MAX_HYDRATE_LINES_PER_FILE) {
|
|
30833
|
+
let inject = null;
|
|
30834
|
+
if (gapNewEnd >= gapNewStart && change !== "removed") {
|
|
30835
|
+
const nNew = gapNewEnd - gapNewStart + 1;
|
|
30836
|
+
if (gapOldEnd < gapOldStart || gapOldEnd - gapOldStart + 1 === nNew) {
|
|
30837
|
+
const cap = Math.min(nNew, MAX_HYDRATE_LINES_PER_GAP, MAX_HYDRATE_LINES_PER_FILE - injectedTotal);
|
|
30838
|
+
const dl = await diskLines();
|
|
30839
|
+
if (dl && cap > 0) {
|
|
30840
|
+
inject = dl.slice(gapNewStart - 1, gapNewStart - 1 + cap);
|
|
30841
|
+
}
|
|
30842
|
+
}
|
|
30843
|
+
} else if (gapOldEnd >= gapOldStart && change === "removed") {
|
|
30844
|
+
const nOld = gapOldEnd - gapOldStart + 1;
|
|
30845
|
+
const cap = Math.min(nOld, MAX_HYDRATE_LINES_PER_GAP, MAX_HYDRATE_LINES_PER_FILE - injectedTotal);
|
|
30846
|
+
const bl = await blobLines();
|
|
30847
|
+
if (bl && cap > 0) {
|
|
30848
|
+
inject = bl.slice(gapOldStart - 1, gapOldStart - 1 + cap);
|
|
30849
|
+
}
|
|
30850
|
+
}
|
|
30851
|
+
if (inject && inject.length > 0) {
|
|
30852
|
+
for (const t of inject) {
|
|
30853
|
+
out.push(` ${t}`);
|
|
30854
|
+
injectedTotal++;
|
|
30855
|
+
}
|
|
30856
|
+
}
|
|
30857
|
+
}
|
|
30858
|
+
out.push(line);
|
|
30859
|
+
i++;
|
|
30860
|
+
let oldConsumed = 0;
|
|
30861
|
+
let newConsumed = 0;
|
|
30862
|
+
while (i < all.length) {
|
|
30863
|
+
const bl = all[i];
|
|
30864
|
+
if (UNIFIED_HUNK_HEADER_RE.test(bl)) break;
|
|
30865
|
+
out.push(bl);
|
|
30866
|
+
i++;
|
|
30867
|
+
if (bl.startsWith("\\")) continue;
|
|
30868
|
+
const ch = bl[0];
|
|
30869
|
+
if (ch === " ") {
|
|
30870
|
+
oldConsumed++;
|
|
30871
|
+
newConsumed++;
|
|
30872
|
+
} else if (ch === "-") {
|
|
30873
|
+
oldConsumed++;
|
|
30874
|
+
} else if (ch === "+") {
|
|
30875
|
+
newConsumed++;
|
|
30876
|
+
}
|
|
30877
|
+
}
|
|
30878
|
+
if (oldStart > 0) {
|
|
30879
|
+
prevOldEnd = oldStart + oldConsumed - 1;
|
|
30880
|
+
} else {
|
|
30881
|
+
prevOldEnd = 0;
|
|
30882
|
+
}
|
|
30883
|
+
if (newStart > 0) {
|
|
30884
|
+
prevNewEnd = newStart + newConsumed - 1;
|
|
30885
|
+
} else {
|
|
30886
|
+
prevNewEnd = 0;
|
|
30887
|
+
}
|
|
30888
|
+
}
|
|
30889
|
+
return truncatePatch(out.join("\n"));
|
|
30890
|
+
}
|
|
30891
|
+
|
|
30892
|
+
// src/git/working-directory/changes/unified-diff-for-file.ts
|
|
30893
|
+
async function unifiedDiffForFile(repoCwd, pathInRepo, change) {
|
|
30894
|
+
const g = simpleGit(repoCwd);
|
|
30895
|
+
try {
|
|
30896
|
+
let raw;
|
|
30897
|
+
if (change === "added") {
|
|
30898
|
+
const devNull = process.platform === "win32" ? "NUL" : "/dev/null";
|
|
30899
|
+
raw = await g.raw(["diff", "--no-index", "--", devNull, pathInRepo]);
|
|
30900
|
+
} else {
|
|
30901
|
+
raw = await g.raw(["diff", "HEAD", "--", pathInRepo]);
|
|
30902
|
+
}
|
|
30903
|
+
const t = String(raw).trim();
|
|
30904
|
+
if (!t) return void 0;
|
|
30905
|
+
return truncatePatch(t);
|
|
30906
|
+
} catch {
|
|
30907
|
+
return void 0;
|
|
30908
|
+
}
|
|
30909
|
+
}
|
|
30910
|
+
|
|
30911
|
+
// src/git/working-directory/changes/list-changed-files-for-repo.ts
|
|
30912
|
+
async function listChangedFilesForRepo(repoGitCwd, repoRelPath) {
|
|
30913
|
+
const g = simpleGit(repoGitCwd);
|
|
30914
|
+
const [nameStatusRaw, numstatRaw, untrackedRaw] = await Promise.all([
|
|
30915
|
+
g.raw(["diff", "--name-status", "HEAD"]).catch(() => ""),
|
|
30916
|
+
g.raw(["diff", "HEAD", "--numstat"]).catch(() => ""),
|
|
30917
|
+
g.raw(["ls-files", "--others", "--exclude-standard"]).catch(() => "")
|
|
30918
|
+
]);
|
|
30919
|
+
const kindByPath = parseNameStatusLines(String(nameStatusRaw).split("\n"));
|
|
30920
|
+
const numByPath = parseNumstat(String(numstatRaw).split("\n"));
|
|
30921
|
+
const paths = /* @__PURE__ */ new Set([...kindByPath.keys(), ...numByPath.keys()]);
|
|
30922
|
+
const untracked = String(untrackedRaw).split("\n").map((s) => s.trim()).filter(Boolean);
|
|
30923
|
+
for (const p of untracked) paths.add(p);
|
|
30924
|
+
const rows = [];
|
|
30925
|
+
for (const pathInRepo of paths) {
|
|
30926
|
+
const relLauncher = posixJoinDirFile(repoRelPath, pathInRepo.replace(/\\/g, "/"));
|
|
30927
|
+
const abs = path14.join(repoGitCwd, pathInRepo);
|
|
30928
|
+
const nums = numByPath.get(pathInRepo);
|
|
30929
|
+
let additions = nums?.additions ?? 0;
|
|
30930
|
+
let deletions = nums?.deletions ?? 0;
|
|
30931
|
+
let change = kindByPath.get(pathInRepo) ?? "modified";
|
|
30932
|
+
if (untracked.includes(pathInRepo) && !kindByPath.has(pathInRepo)) {
|
|
30933
|
+
change = "added";
|
|
30934
|
+
const fromGit = await numstatFromGitNoIndex(g, pathInRepo);
|
|
30935
|
+
if (fromGit) {
|
|
30936
|
+
additions = fromGit.additions;
|
|
30937
|
+
deletions = fromGit.deletions;
|
|
30938
|
+
} else {
|
|
30939
|
+
try {
|
|
30940
|
+
const st = await fs16.promises.stat(abs);
|
|
30941
|
+
if (st.isFile()) additions = await countTextFileLines(abs);
|
|
30942
|
+
else additions = 0;
|
|
30943
|
+
} catch {
|
|
30944
|
+
additions = 0;
|
|
30945
|
+
}
|
|
30946
|
+
deletions = 0;
|
|
30947
|
+
}
|
|
30948
|
+
}
|
|
30949
|
+
if (!kindByPath.has(pathInRepo) && nums) {
|
|
30950
|
+
if (additions > 0 && deletions === 0) change = "added";
|
|
30951
|
+
else if (deletions > 0 && additions === 0) change = "removed";
|
|
30952
|
+
else change = "modified";
|
|
30953
|
+
}
|
|
30954
|
+
rows.push({ pathRelLauncher: relLauncher, additions, deletions, change });
|
|
30955
|
+
}
|
|
30956
|
+
const normRel = repoRelPath === "." || repoRelPath === "" ? "." : repoRelPath;
|
|
30957
|
+
for (const row of rows) {
|
|
30958
|
+
let pathInRepo;
|
|
30959
|
+
if (normRel === ".") {
|
|
30960
|
+
pathInRepo = row.pathRelLauncher;
|
|
30961
|
+
} else if (row.pathRelLauncher.startsWith(`${normRel}/`)) {
|
|
30962
|
+
pathInRepo = row.pathRelLauncher.slice(normRel.length + 1);
|
|
30963
|
+
} else {
|
|
30964
|
+
pathInRepo = row.pathRelLauncher;
|
|
30965
|
+
}
|
|
30966
|
+
const absFile = path14.join(repoGitCwd, pathInRepo);
|
|
30967
|
+
let patch = await unifiedDiffForFile(repoGitCwd, pathInRepo, row.change);
|
|
30968
|
+
if (patch) {
|
|
30969
|
+
patch = await hydrateUnifiedPatchWithFileContext(patch, absFile, repoGitCwd, pathInRepo, row.change);
|
|
30970
|
+
}
|
|
30971
|
+
row.patchContent = patch;
|
|
30972
|
+
}
|
|
30973
|
+
return rows;
|
|
30974
|
+
}
|
|
30975
|
+
|
|
30976
|
+
// src/git/working-directory/changes/get-working-tree-change-repo-details.ts
|
|
30977
|
+
function normRepoRel(p) {
|
|
30978
|
+
const x = p.replace(/\\/g, "/").trim();
|
|
30979
|
+
return x === "" ? "." : x;
|
|
30980
|
+
}
|
|
30981
|
+
async function getWorkingTreeChangeRepoDetails(options) {
|
|
30982
|
+
const launcher = path15.resolve(getBridgeWorkspaceDirectory());
|
|
30983
|
+
const mirror = options.agentMirrorRootAbs ? path15.resolve(options.agentMirrorRootAbs) : null;
|
|
30984
|
+
const out = [];
|
|
30985
|
+
const filter = options.repoFilterRelPath != null ? normRepoRel(options.repoFilterRelPath) : null;
|
|
30986
|
+
const basisInput = options.basis ?? { kind: "working" };
|
|
30987
|
+
if (basisInput.kind === "commit" && !filter) {
|
|
30988
|
+
throw new Error("repoFilterRelPath is required for commit changes");
|
|
30989
|
+
}
|
|
30990
|
+
if (basisInput.kind === "commit" && !basisInput.sha.trim()) {
|
|
30991
|
+
throw new Error("commit sha is required for commit changes");
|
|
30992
|
+
}
|
|
30993
|
+
const basis = filter == null && basisInput.kind === "commit" ? { kind: "working" } : basisInput;
|
|
30994
|
+
for (const target of options.commitTargetAbsDirs) {
|
|
30995
|
+
const t = path15.resolve(target);
|
|
30996
|
+
if (!await isGitRepoDirectory(t)) continue;
|
|
30997
|
+
const g = simpleGit(t);
|
|
30998
|
+
let branch = "HEAD";
|
|
30999
|
+
try {
|
|
31000
|
+
branch = (await g.raw(["rev-parse", "--abbrev-ref", "HEAD"])).trim() || "HEAD";
|
|
31001
|
+
} catch {
|
|
31002
|
+
branch = "HEAD";
|
|
31003
|
+
}
|
|
31004
|
+
const remoteUrl = await getRemoteOriginUrl(t);
|
|
31005
|
+
const remoteDisplay = formatRemoteDisplayLabel(remoteUrl);
|
|
31006
|
+
let repoRelPath;
|
|
31007
|
+
if (mirror) {
|
|
31008
|
+
const relNorm = path15.relative(mirror, path15.dirname(t));
|
|
31009
|
+
repoRelPath = relNorm === "" ? "." : relNorm.replace(/\\/g, "/");
|
|
31010
|
+
} else {
|
|
31011
|
+
let top = t;
|
|
31012
|
+
try {
|
|
31013
|
+
top = (await g.raw(["rev-parse", "--show-toplevel"])).trim();
|
|
31014
|
+
} catch {
|
|
31015
|
+
top = t;
|
|
31016
|
+
}
|
|
31017
|
+
const rel = path15.relative(launcher, path15.resolve(top)).replace(/\\/g, "/") || ".";
|
|
31018
|
+
repoRelPath = rel.startsWith("..") ? path15.basename(path15.resolve(top)) : rel;
|
|
31019
|
+
}
|
|
31020
|
+
const norm = normRepoRel(repoRelPath === "" ? "." : repoRelPath);
|
|
31021
|
+
if (filter && norm !== filter) continue;
|
|
31022
|
+
const repoDisplayName = formatRepoShortTitle(remoteUrl, norm === "." ? "." : norm);
|
|
31023
|
+
const relForList = norm === "." ? "." : norm;
|
|
31024
|
+
const files = basis.kind === "commit" ? await listChangedFilesForCommit(t, relForList, basis.sha.trim()) : await listChangedFilesForRepo(t, relForList);
|
|
31025
|
+
const st = await g.status();
|
|
31026
|
+
const hasUncommittedChanges = (st.files?.length ?? 0) > 0;
|
|
31027
|
+
const unpushedCommits = await listUnpushedCommits(t);
|
|
31028
|
+
out.push({
|
|
31029
|
+
repoRelPath: norm,
|
|
31030
|
+
repoDisplayName,
|
|
31031
|
+
branch,
|
|
31032
|
+
remoteUrl,
|
|
31033
|
+
remoteDisplay,
|
|
31034
|
+
files,
|
|
31035
|
+
hasUncommittedChanges,
|
|
31036
|
+
unpushedCommits,
|
|
31037
|
+
changesView: basis.kind === "commit" ? "commit" : "working",
|
|
31038
|
+
changesCommitSha: basis.kind === "commit" ? basis.sha.trim() : null
|
|
31039
|
+
});
|
|
31040
|
+
if (filter) return out;
|
|
31041
|
+
}
|
|
31042
|
+
return out;
|
|
31043
|
+
}
|
|
31044
|
+
|
|
29964
31045
|
// src/git/commit-and-push.ts
|
|
29965
31046
|
async function gitCommitAllIfDirty(repoDir, message, options) {
|
|
29966
31047
|
const g = simpleGit(repoDir);
|
|
@@ -30026,7 +31107,7 @@ var SessionWorktreeManager = class {
|
|
|
30026
31107
|
}
|
|
30027
31108
|
if (!opts.isNewSession) {
|
|
30028
31109
|
const agentCwd = this.sessionAgentCwd.get(sessionId);
|
|
30029
|
-
if (agentCwd) return
|
|
31110
|
+
if (agentCwd) return path16.resolve(agentCwd);
|
|
30030
31111
|
return void 0;
|
|
30031
31112
|
}
|
|
30032
31113
|
const prep = await prepareNewSessionWorktrees({
|
|
@@ -30039,7 +31120,7 @@ var SessionWorktreeManager = class {
|
|
|
30039
31120
|
if (!prep) return void 0;
|
|
30040
31121
|
this.sessionPaths.set(sessionId, prep.worktreePaths);
|
|
30041
31122
|
this.sessionAgentCwd.set(sessionId, prep.agentCwd);
|
|
30042
|
-
return
|
|
31123
|
+
return path16.resolve(prep.agentCwd);
|
|
30043
31124
|
}
|
|
30044
31125
|
async renameSessionBranch(sessionId, newBranch) {
|
|
30045
31126
|
const paths = this.sessionPaths.get(sessionId);
|
|
@@ -30060,7 +31141,7 @@ var SessionWorktreeManager = class {
|
|
|
30060
31141
|
getAgentCwdForSession(sessionId) {
|
|
30061
31142
|
if (!sessionId) return null;
|
|
30062
31143
|
const c = this.sessionAgentCwd.get(sessionId);
|
|
30063
|
-
return c ?
|
|
31144
|
+
return c ? path16.resolve(c) : null;
|
|
30064
31145
|
}
|
|
30065
31146
|
async removeSessionWorktrees(sessionId) {
|
|
30066
31147
|
const paths = this.sessionPaths.get(sessionId);
|
|
@@ -30086,6 +31167,17 @@ var SessionWorktreeManager = class {
|
|
|
30086
31167
|
async getSessionWorkingTreeStatus(sessionId) {
|
|
30087
31168
|
return aggregateSessionPathsWorkingTreeStatus(this.resolveCommitTargets(sessionId));
|
|
30088
31169
|
}
|
|
31170
|
+
/** Per-repo changed files vs HEAD (or a single commit vs parent) for the same git roots used for commit/push. */
|
|
31171
|
+
async getSessionWorkingTreeChangeDetails(sessionId, opts) {
|
|
31172
|
+
const targets = this.resolveCommitTargets(sessionId);
|
|
31173
|
+
const mirror = this.getAgentCwdForSession(sessionId);
|
|
31174
|
+
return getWorkingTreeChangeRepoDetails({
|
|
31175
|
+
commitTargetAbsDirs: targets,
|
|
31176
|
+
agentMirrorRootAbs: mirror,
|
|
31177
|
+
repoFilterRelPath: opts?.repoRelPath?.trim() ? opts.repoRelPath.trim() : null,
|
|
31178
|
+
basis: opts?.basis
|
|
31179
|
+
});
|
|
31180
|
+
}
|
|
30089
31181
|
async pushSessionUpstream(sessionId) {
|
|
30090
31182
|
try {
|
|
30091
31183
|
await pushAheadOfUpstreamForPaths(this.resolveCommitTargets(sessionId));
|
|
@@ -30097,30 +31189,30 @@ var SessionWorktreeManager = class {
|
|
|
30097
31189
|
}
|
|
30098
31190
|
};
|
|
30099
31191
|
function defaultWorktreesRootAbs() {
|
|
30100
|
-
return
|
|
31192
|
+
return path16.join(os4.homedir(), ".buildautomaton", "worktrees");
|
|
30101
31193
|
}
|
|
30102
31194
|
|
|
30103
31195
|
// src/files/watch-file-index.ts
|
|
30104
31196
|
import { watch } from "node:fs";
|
|
30105
|
-
import
|
|
31197
|
+
import path23 from "node:path";
|
|
30106
31198
|
|
|
30107
31199
|
// src/files/index/build-file-index.ts
|
|
30108
|
-
import
|
|
31200
|
+
import path20 from "node:path";
|
|
30109
31201
|
|
|
30110
31202
|
// src/runtime/yield-to-event-loop.ts
|
|
30111
31203
|
function yieldToEventLoop() {
|
|
30112
|
-
return new Promise((
|
|
31204
|
+
return new Promise((resolve15) => setImmediate(resolve15));
|
|
30113
31205
|
}
|
|
30114
31206
|
|
|
30115
31207
|
// src/files/index/walk-workspace-tree.ts
|
|
30116
|
-
import
|
|
30117
|
-
import
|
|
31208
|
+
import fs17 from "node:fs";
|
|
31209
|
+
import path18 from "node:path";
|
|
30118
31210
|
|
|
30119
31211
|
// src/files/index/constants.ts
|
|
30120
|
-
import
|
|
30121
|
-
import
|
|
31212
|
+
import path17 from "node:path";
|
|
31213
|
+
import os5 from "node:os";
|
|
30122
31214
|
var INDEX_WORK_YIELD_EVERY = 256;
|
|
30123
|
-
var INDEX_DIR =
|
|
31215
|
+
var INDEX_DIR = path17.join(os5.homedir(), ".buildautomaton");
|
|
30124
31216
|
var INDEX_HASH_LEN = 16;
|
|
30125
31217
|
var INDEX_VERSION = 2;
|
|
30126
31218
|
var INDEX_LOG_PREFIX = "[file-index]";
|
|
@@ -30129,31 +31221,31 @@ var INDEX_LOG_PREFIX = "[file-index]";
|
|
|
30129
31221
|
function walkWorkspaceTreeSync(dir, baseDir, out) {
|
|
30130
31222
|
let names;
|
|
30131
31223
|
try {
|
|
30132
|
-
names =
|
|
31224
|
+
names = fs17.readdirSync(dir);
|
|
30133
31225
|
} catch {
|
|
30134
31226
|
return;
|
|
30135
31227
|
}
|
|
30136
31228
|
for (const name of names) {
|
|
30137
31229
|
if (name.startsWith(".")) continue;
|
|
30138
|
-
const full =
|
|
31230
|
+
const full = path18.join(dir, name);
|
|
30139
31231
|
let stat2;
|
|
30140
31232
|
try {
|
|
30141
|
-
stat2 =
|
|
31233
|
+
stat2 = fs17.statSync(full);
|
|
30142
31234
|
} catch {
|
|
30143
31235
|
continue;
|
|
30144
31236
|
}
|
|
30145
|
-
const
|
|
31237
|
+
const relative5 = path18.relative(baseDir, full).replace(/\\/g, "/");
|
|
30146
31238
|
if (stat2.isDirectory()) {
|
|
30147
31239
|
walkWorkspaceTreeSync(full, baseDir, out);
|
|
30148
31240
|
} else if (stat2.isFile()) {
|
|
30149
|
-
out.push(
|
|
31241
|
+
out.push(relative5);
|
|
30150
31242
|
}
|
|
30151
31243
|
}
|
|
30152
31244
|
}
|
|
30153
31245
|
async function walkWorkspaceTreeAsync(dir, baseDir, out, state) {
|
|
30154
31246
|
let names;
|
|
30155
31247
|
try {
|
|
30156
|
-
names = await
|
|
31248
|
+
names = await fs17.promises.readdir(dir);
|
|
30157
31249
|
} catch {
|
|
30158
31250
|
return;
|
|
30159
31251
|
}
|
|
@@ -30163,18 +31255,18 @@ async function walkWorkspaceTreeAsync(dir, baseDir, out, state) {
|
|
|
30163
31255
|
await yieldToEventLoop();
|
|
30164
31256
|
}
|
|
30165
31257
|
state.n++;
|
|
30166
|
-
const full =
|
|
31258
|
+
const full = path18.join(dir, name);
|
|
30167
31259
|
let stat2;
|
|
30168
31260
|
try {
|
|
30169
|
-
stat2 = await
|
|
31261
|
+
stat2 = await fs17.promises.stat(full);
|
|
30170
31262
|
} catch {
|
|
30171
31263
|
continue;
|
|
30172
31264
|
}
|
|
30173
|
-
const
|
|
31265
|
+
const relative5 = path18.relative(baseDir, full).replace(/\\/g, "/");
|
|
30174
31266
|
if (stat2.isDirectory()) {
|
|
30175
31267
|
await walkWorkspaceTreeAsync(full, baseDir, out, state);
|
|
30176
31268
|
} else if (stat2.isFile()) {
|
|
30177
|
-
out.push(
|
|
31269
|
+
out.push(relative5);
|
|
30178
31270
|
}
|
|
30179
31271
|
}
|
|
30180
31272
|
}
|
|
@@ -30251,22 +31343,22 @@ async function buildTrigramMapForPathsAsync(paths) {
|
|
|
30251
31343
|
}
|
|
30252
31344
|
|
|
30253
31345
|
// src/files/index/write-index-file.ts
|
|
30254
|
-
import
|
|
31346
|
+
import fs18 from "node:fs";
|
|
30255
31347
|
|
|
30256
31348
|
// src/files/index/paths.ts
|
|
30257
|
-
import
|
|
31349
|
+
import path19 from "node:path";
|
|
30258
31350
|
import crypto2 from "node:crypto";
|
|
30259
31351
|
function getIndexPathForCwd(resolvedCwd) {
|
|
30260
31352
|
const hash = crypto2.createHash("sha256").update(resolvedCwd).digest("hex").slice(0, INDEX_HASH_LEN);
|
|
30261
|
-
return
|
|
31353
|
+
return path19.join(INDEX_DIR, `.file-index-${hash}.json`);
|
|
30262
31354
|
}
|
|
30263
31355
|
|
|
30264
31356
|
// src/files/index/write-index-file.ts
|
|
30265
31357
|
function writeIndexFileSync(resolvedCwd, data) {
|
|
30266
31358
|
const indexPath = getIndexPathForCwd(resolvedCwd);
|
|
30267
31359
|
try {
|
|
30268
|
-
if (!
|
|
30269
|
-
|
|
31360
|
+
if (!fs18.existsSync(INDEX_DIR)) fs18.mkdirSync(INDEX_DIR, { recursive: true });
|
|
31361
|
+
fs18.writeFileSync(indexPath, JSON.stringify(data), "utf8");
|
|
30270
31362
|
} catch (e) {
|
|
30271
31363
|
console.error(`${INDEX_LOG_PREFIX} Failed to write index:`, e);
|
|
30272
31364
|
}
|
|
@@ -30274,8 +31366,8 @@ function writeIndexFileSync(resolvedCwd, data) {
|
|
|
30274
31366
|
async function writeIndexFileAsync(resolvedCwd, data) {
|
|
30275
31367
|
const indexPath = getIndexPathForCwd(resolvedCwd);
|
|
30276
31368
|
try {
|
|
30277
|
-
await
|
|
30278
|
-
await
|
|
31369
|
+
await fs18.promises.mkdir(INDEX_DIR, { recursive: true });
|
|
31370
|
+
await fs18.promises.writeFile(indexPath, JSON.stringify(data), "utf8");
|
|
30279
31371
|
} catch (e) {
|
|
30280
31372
|
console.error(`${INDEX_LOG_PREFIX} Failed to write index:`, e);
|
|
30281
31373
|
}
|
|
@@ -30289,7 +31381,7 @@ function sortPaths(paths) {
|
|
|
30289
31381
|
paths.sort((a, b) => a.localeCompare(b, void 0, { sensitivity: "base" }));
|
|
30290
31382
|
}
|
|
30291
31383
|
function buildFileIndex(cwd) {
|
|
30292
|
-
const resolved =
|
|
31384
|
+
const resolved = path20.resolve(cwd);
|
|
30293
31385
|
const paths = [];
|
|
30294
31386
|
walkWorkspaceTreeSync(resolved, resolved, paths);
|
|
30295
31387
|
sortPaths(paths);
|
|
@@ -30299,7 +31391,7 @@ function buildFileIndex(cwd) {
|
|
|
30299
31391
|
return data;
|
|
30300
31392
|
}
|
|
30301
31393
|
async function buildFileIndexAsync(cwd) {
|
|
30302
|
-
const resolved =
|
|
31394
|
+
const resolved = path20.resolve(cwd);
|
|
30303
31395
|
const paths = [];
|
|
30304
31396
|
await walkWorkspaceTreeAsync(resolved, resolved, paths, createWalkYieldState());
|
|
30305
31397
|
await yieldToEventLoop();
|
|
@@ -30311,13 +31403,13 @@ async function buildFileIndexAsync(cwd) {
|
|
|
30311
31403
|
}
|
|
30312
31404
|
|
|
30313
31405
|
// src/files/index/load-file-index.ts
|
|
30314
|
-
import
|
|
30315
|
-
import
|
|
31406
|
+
import fs19 from "node:fs";
|
|
31407
|
+
import path21 from "node:path";
|
|
30316
31408
|
function loadFileIndex(cwd) {
|
|
30317
|
-
const resolved =
|
|
31409
|
+
const resolved = path21.resolve(cwd);
|
|
30318
31410
|
const indexPath = getIndexPathForCwd(resolved);
|
|
30319
31411
|
try {
|
|
30320
|
-
const raw =
|
|
31412
|
+
const raw = fs19.readFileSync(indexPath, "utf8");
|
|
30321
31413
|
const parsed = JSON.parse(raw);
|
|
30322
31414
|
if (parsed !== null && typeof parsed === "object" && Array.isArray(parsed.paths)) {
|
|
30323
31415
|
const obj = parsed;
|
|
@@ -30336,9 +31428,9 @@ function loadFileIndex(cwd) {
|
|
|
30336
31428
|
}
|
|
30337
31429
|
|
|
30338
31430
|
// src/files/index/ensure-file-index.ts
|
|
30339
|
-
import
|
|
31431
|
+
import path22 from "node:path";
|
|
30340
31432
|
async function ensureFileIndexAsync(cwd) {
|
|
30341
|
-
const resolved =
|
|
31433
|
+
const resolved = path22.resolve(cwd);
|
|
30342
31434
|
const cached2 = loadFileIndex(resolved);
|
|
30343
31435
|
if (cached2 !== null) return { data: cached2, fromCache: true };
|
|
30344
31436
|
const data = await buildFileIndexAsync(resolved);
|
|
@@ -30421,7 +31513,7 @@ function createFsWatcher(resolved, schedule) {
|
|
|
30421
31513
|
}
|
|
30422
31514
|
}
|
|
30423
31515
|
function startFileIndexWatcher(cwd = getBridgeWorkspaceDirectory()) {
|
|
30424
|
-
const resolved =
|
|
31516
|
+
const resolved = path23.resolve(cwd);
|
|
30425
31517
|
void buildFileIndexAsync(resolved).catch((e) => {
|
|
30426
31518
|
console.error("[file-index] Initial index build failed:", e);
|
|
30427
31519
|
});
|
|
@@ -30468,15 +31560,15 @@ function sendDevServerStatus(getWs, serverId, status, options) {
|
|
|
30468
31560
|
|
|
30469
31561
|
// src/dev-servers/process/terminate-child-process.ts
|
|
30470
31562
|
async function sigtermAndWaitForExit(proc, graceMs, log2, shortId) {
|
|
30471
|
-
const exited = new Promise((
|
|
30472
|
-
proc.once("exit", () =>
|
|
31563
|
+
const exited = new Promise((resolve15) => {
|
|
31564
|
+
proc.once("exit", () => resolve15());
|
|
30473
31565
|
});
|
|
30474
31566
|
log2(`[dev-server] Sending SIGTERM to ${shortId} (pid=${proc.pid ?? "?"}).`);
|
|
30475
31567
|
try {
|
|
30476
31568
|
proc.kill("SIGTERM");
|
|
30477
31569
|
} catch {
|
|
30478
31570
|
}
|
|
30479
|
-
await Promise.race([exited, new Promise((
|
|
31571
|
+
await Promise.race([exited, new Promise((resolve15) => setTimeout(resolve15, graceMs))]);
|
|
30480
31572
|
}
|
|
30481
31573
|
function forceKillChild(proc, log2, shortId, graceMs) {
|
|
30482
31574
|
log2(
|
|
@@ -30490,7 +31582,7 @@ function forceKillChild(proc, log2, shortId, graceMs) {
|
|
|
30490
31582
|
}
|
|
30491
31583
|
|
|
30492
31584
|
// src/dev-servers/process/wire-dev-server-child-process.ts
|
|
30493
|
-
import
|
|
31585
|
+
import fs20 from "node:fs";
|
|
30494
31586
|
|
|
30495
31587
|
// src/dev-servers/manager/forward-pipe.ts
|
|
30496
31588
|
function forwardChildPipe(childReadable, terminal, onData) {
|
|
@@ -30526,7 +31618,7 @@ function wireDevServerChildProcess(d) {
|
|
|
30526
31618
|
d.setPollInterval(void 0);
|
|
30527
31619
|
return;
|
|
30528
31620
|
}
|
|
30529
|
-
|
|
31621
|
+
fs20.readFile(d.mergedLogPath, (err, buf) => {
|
|
30530
31622
|
if (err || (d.getSpawnGeneration() ?? 0) !== d.scheduledGen) return;
|
|
30531
31623
|
if (buf.length <= d.mergedReadPos.value) return;
|
|
30532
31624
|
const chunk = Buffer.from(buf.subarray(d.mergedReadPos.value));
|
|
@@ -30564,7 +31656,7 @@ ${errTail}` : ""}`);
|
|
|
30564
31656
|
d.sendStatus(code === 0 || code == null ? "stopped" : "error", detail, tails);
|
|
30565
31657
|
};
|
|
30566
31658
|
if (mergedPath) {
|
|
30567
|
-
|
|
31659
|
+
fs20.readFile(mergedPath, (err, buf) => {
|
|
30568
31660
|
if (!err && buf.length > d.mergedReadPos.value) {
|
|
30569
31661
|
const chunk = Buffer.from(buf.subarray(d.mergedReadPos.value));
|
|
30570
31662
|
if (chunk.length > 0) {
|
|
@@ -30666,13 +31758,13 @@ function parseDevServerDefs(servers) {
|
|
|
30666
31758
|
}
|
|
30667
31759
|
|
|
30668
31760
|
// src/dev-servers/manager/shell-spawn/utils.ts
|
|
30669
|
-
import
|
|
31761
|
+
import fs21 from "node:fs";
|
|
30670
31762
|
function isSpawnEbadf(e) {
|
|
30671
31763
|
return typeof e === "object" && e !== null && "code" in e && e.code === "EBADF";
|
|
30672
31764
|
}
|
|
30673
31765
|
function rmDirQuiet(dir) {
|
|
30674
31766
|
try {
|
|
30675
|
-
|
|
31767
|
+
fs21.rmSync(dir, { recursive: true, force: true });
|
|
30676
31768
|
} catch {
|
|
30677
31769
|
}
|
|
30678
31770
|
}
|
|
@@ -30680,7 +31772,7 @@ var cachedDevNullReadFd;
|
|
|
30680
31772
|
function devNullReadFd() {
|
|
30681
31773
|
if (cachedDevNullReadFd === void 0) {
|
|
30682
31774
|
const devPath = process.platform === "win32" ? "nul" : "/dev/null";
|
|
30683
|
-
cachedDevNullReadFd =
|
|
31775
|
+
cachedDevNullReadFd = fs21.openSync(devPath, "r");
|
|
30684
31776
|
}
|
|
30685
31777
|
return cachedDevNullReadFd;
|
|
30686
31778
|
}
|
|
@@ -30754,15 +31846,15 @@ function trySpawnShellTruePiped(command, env, cwd, devNullFd, signal) {
|
|
|
30754
31846
|
|
|
30755
31847
|
// src/dev-servers/manager/shell-spawn/try-spawn-merged-log-file.ts
|
|
30756
31848
|
import { spawn as spawn7 } from "node:child_process";
|
|
30757
|
-
import
|
|
31849
|
+
import fs22 from "node:fs";
|
|
30758
31850
|
import { tmpdir } from "node:os";
|
|
30759
|
-
import
|
|
31851
|
+
import path24 from "node:path";
|
|
30760
31852
|
function trySpawnMergedLogFile(command, env, cwd, signal) {
|
|
30761
|
-
const tmpRoot =
|
|
30762
|
-
const logPath =
|
|
31853
|
+
const tmpRoot = fs22.mkdtempSync(path24.join(tmpdir(), "ba-devsrv-log-"));
|
|
31854
|
+
const logPath = path24.join(tmpRoot, "combined.log");
|
|
30763
31855
|
let logFd;
|
|
30764
31856
|
try {
|
|
30765
|
-
logFd =
|
|
31857
|
+
logFd = fs22.openSync(logPath, "a");
|
|
30766
31858
|
} catch {
|
|
30767
31859
|
rmDirQuiet(tmpRoot);
|
|
30768
31860
|
return null;
|
|
@@ -30781,7 +31873,7 @@ function trySpawnMergedLogFile(command, env, cwd, signal) {
|
|
|
30781
31873
|
} else {
|
|
30782
31874
|
proc = spawn7("/bin/sh", ["-c", command], { env, cwd, stdio, ...signal ? { signal } : {} });
|
|
30783
31875
|
}
|
|
30784
|
-
|
|
31876
|
+
fs22.closeSync(logFd);
|
|
30785
31877
|
return {
|
|
30786
31878
|
proc,
|
|
30787
31879
|
pipedStdoutStderr: true,
|
|
@@ -30790,7 +31882,7 @@ function trySpawnMergedLogFile(command, env, cwd, signal) {
|
|
|
30790
31882
|
};
|
|
30791
31883
|
} catch (e) {
|
|
30792
31884
|
try {
|
|
30793
|
-
|
|
31885
|
+
fs22.closeSync(logFd);
|
|
30794
31886
|
} catch {
|
|
30795
31887
|
}
|
|
30796
31888
|
rmDirQuiet(tmpRoot);
|
|
@@ -30801,22 +31893,22 @@ function trySpawnMergedLogFile(command, env, cwd, signal) {
|
|
|
30801
31893
|
|
|
30802
31894
|
// src/dev-servers/manager/shell-spawn/try-spawn-shell-script-log-redirect.ts
|
|
30803
31895
|
import { spawn as spawn8 } from "node:child_process";
|
|
30804
|
-
import
|
|
31896
|
+
import fs23 from "node:fs";
|
|
30805
31897
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
30806
|
-
import
|
|
31898
|
+
import path25 from "node:path";
|
|
30807
31899
|
function shSingleQuote(s) {
|
|
30808
31900
|
return `'${s.replace(/'/g, `'\\''`)}'`;
|
|
30809
31901
|
}
|
|
30810
31902
|
function trySpawnShellScriptLogRedirectUnix(command, env, cwd, signal) {
|
|
30811
|
-
const tmpRoot =
|
|
30812
|
-
const logPath =
|
|
30813
|
-
const innerPath =
|
|
30814
|
-
const runnerPath =
|
|
31903
|
+
const tmpRoot = fs23.mkdtempSync(path25.join(tmpdir2(), "ba-devsrv-sh-"));
|
|
31904
|
+
const logPath = path25.join(tmpRoot, "combined.log");
|
|
31905
|
+
const innerPath = path25.join(tmpRoot, "_cmd.sh");
|
|
31906
|
+
const runnerPath = path25.join(tmpRoot, "_run.sh");
|
|
30815
31907
|
try {
|
|
30816
|
-
|
|
31908
|
+
fs23.writeFileSync(innerPath, `#!/bin/sh
|
|
30817
31909
|
${command}
|
|
30818
31910
|
`);
|
|
30819
|
-
|
|
31911
|
+
fs23.writeFileSync(
|
|
30820
31912
|
runnerPath,
|
|
30821
31913
|
`#!/bin/sh
|
|
30822
31914
|
cd ${shSingleQuote(cwd)}
|
|
@@ -30842,13 +31934,13 @@ cd ${shSingleQuote(cwd)}
|
|
|
30842
31934
|
}
|
|
30843
31935
|
}
|
|
30844
31936
|
function trySpawnShellScriptLogRedirectWin(command, env, cwd, signal) {
|
|
30845
|
-
const tmpRoot =
|
|
30846
|
-
const logPath =
|
|
30847
|
-
const runnerPath =
|
|
31937
|
+
const tmpRoot = fs23.mkdtempSync(path25.join(tmpdir2(), "ba-devsrv-sh-"));
|
|
31938
|
+
const logPath = path25.join(tmpRoot, "combined.log");
|
|
31939
|
+
const runnerPath = path25.join(tmpRoot, "_run.bat");
|
|
30848
31940
|
const q = (p) => `"${p.replace(/"/g, '""')}"`;
|
|
30849
31941
|
const com = process.env.ComSpec || "cmd.exe";
|
|
30850
31942
|
try {
|
|
30851
|
-
|
|
31943
|
+
fs23.writeFileSync(
|
|
30852
31944
|
runnerPath,
|
|
30853
31945
|
`@ECHO OFF\r
|
|
30854
31946
|
CD /D ${q(cwd)}\r
|
|
@@ -31530,30 +32622,30 @@ function createOnBridgeIdentified(opts) {
|
|
|
31530
32622
|
}
|
|
31531
32623
|
|
|
31532
32624
|
// src/skills/discover-local-agent-skills.ts
|
|
31533
|
-
import
|
|
31534
|
-
import
|
|
32625
|
+
import fs24 from "node:fs";
|
|
32626
|
+
import path26 from "node:path";
|
|
31535
32627
|
var SKILL_DISCOVERY_ROOTS = [".agents/skills", ".claude/skills", ".cursor/skills", "skills"];
|
|
31536
32628
|
function discoverLocalSkills(cwd) {
|
|
31537
32629
|
const out = [];
|
|
31538
32630
|
const seenKeys = /* @__PURE__ */ new Set();
|
|
31539
32631
|
for (const rel of SKILL_DISCOVERY_ROOTS) {
|
|
31540
|
-
const base =
|
|
31541
|
-
if (!
|
|
32632
|
+
const base = path26.join(cwd, rel);
|
|
32633
|
+
if (!fs24.existsSync(base) || !fs24.statSync(base).isDirectory()) continue;
|
|
31542
32634
|
let entries = [];
|
|
31543
32635
|
try {
|
|
31544
|
-
entries =
|
|
32636
|
+
entries = fs24.readdirSync(base);
|
|
31545
32637
|
} catch {
|
|
31546
32638
|
continue;
|
|
31547
32639
|
}
|
|
31548
32640
|
for (const name of entries) {
|
|
31549
|
-
const dir =
|
|
32641
|
+
const dir = path26.join(base, name);
|
|
31550
32642
|
try {
|
|
31551
|
-
if (!
|
|
32643
|
+
if (!fs24.statSync(dir).isDirectory()) continue;
|
|
31552
32644
|
} catch {
|
|
31553
32645
|
continue;
|
|
31554
32646
|
}
|
|
31555
|
-
const skillMd =
|
|
31556
|
-
if (!
|
|
32647
|
+
const skillMd = path26.join(dir, "SKILL.md");
|
|
32648
|
+
if (!fs24.existsSync(skillMd)) continue;
|
|
31557
32649
|
const key = `${rel}/${name}`;
|
|
31558
32650
|
if (seenKeys.has(key)) continue;
|
|
31559
32651
|
seenKeys.add(key);
|
|
@@ -31565,23 +32657,23 @@ function discoverLocalSkills(cwd) {
|
|
|
31565
32657
|
function discoverSkillLayoutRoots(cwd) {
|
|
31566
32658
|
const roots = [];
|
|
31567
32659
|
for (const rel of SKILL_DISCOVERY_ROOTS) {
|
|
31568
|
-
const base =
|
|
31569
|
-
if (!
|
|
32660
|
+
const base = path26.join(cwd, rel);
|
|
32661
|
+
if (!fs24.existsSync(base) || !fs24.statSync(base).isDirectory()) continue;
|
|
31570
32662
|
let entries = [];
|
|
31571
32663
|
try {
|
|
31572
|
-
entries =
|
|
32664
|
+
entries = fs24.readdirSync(base);
|
|
31573
32665
|
} catch {
|
|
31574
32666
|
continue;
|
|
31575
32667
|
}
|
|
31576
32668
|
const skills2 = [];
|
|
31577
32669
|
for (const name of entries) {
|
|
31578
|
-
const dir =
|
|
32670
|
+
const dir = path26.join(base, name);
|
|
31579
32671
|
try {
|
|
31580
|
-
if (!
|
|
32672
|
+
if (!fs24.statSync(dir).isDirectory()) continue;
|
|
31581
32673
|
} catch {
|
|
31582
32674
|
continue;
|
|
31583
32675
|
}
|
|
31584
|
-
if (!
|
|
32676
|
+
if (!fs24.existsSync(path26.join(dir, "SKILL.md"))) continue;
|
|
31585
32677
|
const relPath = `${rel}/${name}`.replace(/\\/g, "/");
|
|
31586
32678
|
skills2.push({ name, relPath });
|
|
31587
32679
|
}
|
|
@@ -31726,12 +32818,12 @@ var handleAgentConfigMessage = (msg, deps) => {
|
|
|
31726
32818
|
};
|
|
31727
32819
|
|
|
31728
32820
|
// src/agents/acp/from-bridge/handle-bridge-prompt.ts
|
|
31729
|
-
import * as
|
|
31730
|
-
import { execFile as
|
|
31731
|
-
import { promisify as
|
|
32821
|
+
import * as path28 from "node:path";
|
|
32822
|
+
import { execFile as execFile10 } from "node:child_process";
|
|
32823
|
+
import { promisify as promisify10 } from "node:util";
|
|
31732
32824
|
|
|
31733
32825
|
// src/git/bridge-queue-key.ts
|
|
31734
|
-
import * as
|
|
32826
|
+
import * as path27 from "node:path";
|
|
31735
32827
|
import { createHash } from "node:crypto";
|
|
31736
32828
|
function normalizeCanonicalGitUrl(url2) {
|
|
31737
32829
|
let s = url2.trim();
|
|
@@ -31759,11 +32851,11 @@ function canonicalUrlToRepoIdSync(url2) {
|
|
|
31759
32851
|
return createHash("sha256").update(normalized).digest("hex").slice(0, 32);
|
|
31760
32852
|
}
|
|
31761
32853
|
function fallbackRepoIdFromPath(absPath) {
|
|
31762
|
-
return createHash("sha256").update(
|
|
32854
|
+
return createHash("sha256").update(path27.resolve(absPath)).digest("hex").slice(0, 32);
|
|
31763
32855
|
}
|
|
31764
32856
|
async function resolveBridgeQueueBindFields(options) {
|
|
31765
32857
|
const { effectiveCwd, worktreePaths, primaryRepoRoots, log: log2 } = options;
|
|
31766
|
-
const cwdAbs = worktreePaths.length > 0 ?
|
|
32858
|
+
const cwdAbs = worktreePaths.length > 0 ? path27.resolve(worktreePaths[0]) : path27.resolve(effectiveCwd);
|
|
31767
32859
|
if (!primaryRepoRoots.length) {
|
|
31768
32860
|
log2("[Bridge service] Prompt queue bind skipped: no Git repository roots under the working directory.");
|
|
31769
32861
|
return null;
|
|
@@ -31786,10 +32878,10 @@ async function resolveBridgeQueueBindFields(options) {
|
|
|
31786
32878
|
}
|
|
31787
32879
|
|
|
31788
32880
|
// src/agents/acp/from-bridge/handle-bridge-prompt.ts
|
|
31789
|
-
var
|
|
32881
|
+
var execFileAsync9 = promisify10(execFile10);
|
|
31790
32882
|
async function readGitBranch(cwd) {
|
|
31791
32883
|
try {
|
|
31792
|
-
const { stdout } = await
|
|
32884
|
+
const { stdout } = await execFileAsync9("git", ["branch", "--show-current"], { cwd, maxBuffer: 64 * 1024 });
|
|
31793
32885
|
const b = stdout.trim();
|
|
31794
32886
|
return b || null;
|
|
31795
32887
|
} catch {
|
|
@@ -31800,17 +32892,29 @@ function handleBridgePrompt(msg, deps) {
|
|
|
31800
32892
|
const { getWs, log: log2, acpManager, sessionWorktreeManager } = deps;
|
|
31801
32893
|
const rawPrompt = msg.prompt;
|
|
31802
32894
|
const promptText = typeof rawPrompt === "string" ? rawPrompt : rawPrompt != null ? String(rawPrompt) : "";
|
|
32895
|
+
const sessionId = msg.sessionId;
|
|
32896
|
+
const runId = typeof msg.runId === "string" ? msg.runId : void 0;
|
|
32897
|
+
const promptId = typeof msg.id === "string" ? msg.id : void 0;
|
|
31803
32898
|
if (!promptText.trim()) {
|
|
31804
32899
|
log2(
|
|
31805
32900
|
`[Bridge service] Prompt ignored: empty or missing prompt text (session ${typeof msg.sessionId === "string" ? msg.sessionId.slice(0, 8) : "\u2014"}\u2026, run ${typeof msg.runId === "string" ? msg.runId.slice(0, 8) : "\u2014"}\u2026).`
|
|
31806
32901
|
);
|
|
32902
|
+
const s = getWs();
|
|
32903
|
+
if (s) {
|
|
32904
|
+
sendWsMessage(s, {
|
|
32905
|
+
type: "prompt_result",
|
|
32906
|
+
...promptId ? { id: promptId } : {},
|
|
32907
|
+
...sessionId ? { sessionId } : {},
|
|
32908
|
+
...runId ? { runId } : {},
|
|
32909
|
+
success: false,
|
|
32910
|
+
error: "Empty or missing prompt text from the bridge; this turn was not sent to the agent."
|
|
32911
|
+
});
|
|
32912
|
+
}
|
|
31807
32913
|
return;
|
|
31808
32914
|
}
|
|
31809
|
-
const sessionId = msg.sessionId;
|
|
31810
32915
|
const isNewSession = msg.isNewSession === true;
|
|
31811
32916
|
const sessionWorktreesEnabled = msg.sessionWorktreesEnabled === true;
|
|
31812
32917
|
const agentType = typeof msg.agentType === "string" && msg.agentType.trim() ? msg.agentType.trim() : void 0;
|
|
31813
|
-
const runId = typeof msg.runId === "string" ? msg.runId : void 0;
|
|
31814
32918
|
const mode = typeof msg.mode === "string" && msg.mode.trim() ? msg.mode.trim() : void 0;
|
|
31815
32919
|
acpManager.logPromptReceivedFromBridge({ agentType, mode });
|
|
31816
32920
|
const sendResult2 = (result) => {
|
|
@@ -31828,7 +32932,7 @@ function handleBridgePrompt(msg, deps) {
|
|
|
31828
32932
|
};
|
|
31829
32933
|
async function preambleAndPrompt(resolvedCwd) {
|
|
31830
32934
|
const s = getWs();
|
|
31831
|
-
const effectiveCwd =
|
|
32935
|
+
const effectiveCwd = path28.resolve(resolvedCwd ?? getBridgeWorkspaceDirectory());
|
|
31832
32936
|
const worktreePaths = sessionWorktreeManager.getWorktreePathsForSession(sessionId) ?? [];
|
|
31833
32937
|
const repoRoots = await resolveSnapshotRepoRoots({
|
|
31834
32938
|
worktreePaths,
|
|
@@ -31953,15 +33057,15 @@ var handleSkillCallMessage = (msg, { getWs, log: log2 }) => {
|
|
|
31953
33057
|
};
|
|
31954
33058
|
|
|
31955
33059
|
// src/files/list-dir.ts
|
|
31956
|
-
import
|
|
31957
|
-
import
|
|
33060
|
+
import fs25 from "node:fs";
|
|
33061
|
+
import path30 from "node:path";
|
|
31958
33062
|
|
|
31959
33063
|
// src/files/ensure-under-cwd.ts
|
|
31960
|
-
import
|
|
33064
|
+
import path29 from "node:path";
|
|
31961
33065
|
function ensureUnderCwd(relativePath, cwd = getBridgeWorkspaceDirectory()) {
|
|
31962
|
-
const normalized =
|
|
31963
|
-
const resolved =
|
|
31964
|
-
if (!resolved.startsWith(cwd +
|
|
33066
|
+
const normalized = path29.normalize(relativePath).replace(/^(\.\/)+/, "");
|
|
33067
|
+
const resolved = path29.resolve(cwd, normalized);
|
|
33068
|
+
if (!resolved.startsWith(cwd + path29.sep) && resolved !== cwd) {
|
|
31965
33069
|
return null;
|
|
31966
33070
|
}
|
|
31967
33071
|
return resolved;
|
|
@@ -31975,7 +33079,7 @@ async function listDirAsync(relativePath) {
|
|
|
31975
33079
|
return { error: "Path is outside working directory" };
|
|
31976
33080
|
}
|
|
31977
33081
|
try {
|
|
31978
|
-
const names = await
|
|
33082
|
+
const names = await fs25.promises.readdir(resolved, { withFileTypes: true });
|
|
31979
33083
|
const visible = names.filter((d) => !d.name.startsWith("."));
|
|
31980
33084
|
const entries = [];
|
|
31981
33085
|
for (let i = 0; i < visible.length; i++) {
|
|
@@ -31983,12 +33087,12 @@ async function listDirAsync(relativePath) {
|
|
|
31983
33087
|
await yieldToEventLoop();
|
|
31984
33088
|
}
|
|
31985
33089
|
const d = visible[i];
|
|
31986
|
-
const entryPath =
|
|
31987
|
-
const fullPath =
|
|
33090
|
+
const entryPath = path30.join(relativePath || ".", d.name).replace(/\\/g, "/");
|
|
33091
|
+
const fullPath = path30.join(resolved, d.name);
|
|
31988
33092
|
let isDir = d.isDirectory();
|
|
31989
33093
|
if (d.isSymbolicLink()) {
|
|
31990
33094
|
try {
|
|
31991
|
-
const targetStat = await
|
|
33095
|
+
const targetStat = await fs25.promises.stat(fullPath);
|
|
31992
33096
|
isDir = targetStat.isDirectory();
|
|
31993
33097
|
} catch {
|
|
31994
33098
|
isDir = false;
|
|
@@ -32013,25 +33117,25 @@ async function listDirAsync(relativePath) {
|
|
|
32013
33117
|
}
|
|
32014
33118
|
|
|
32015
33119
|
// src/files/read-file.ts
|
|
32016
|
-
import
|
|
33120
|
+
import fs26 from "node:fs";
|
|
32017
33121
|
import { StringDecoder } from "node:string_decoder";
|
|
32018
33122
|
function resolveFilePath(relativePath) {
|
|
32019
33123
|
const resolved = ensureUnderCwd(relativePath, getBridgeWorkspaceDirectory());
|
|
32020
33124
|
if (!resolved) return { error: "Path is outside working directory" };
|
|
32021
33125
|
let real;
|
|
32022
33126
|
try {
|
|
32023
|
-
real =
|
|
33127
|
+
real = fs26.realpathSync(resolved);
|
|
32024
33128
|
} catch {
|
|
32025
33129
|
real = resolved;
|
|
32026
33130
|
}
|
|
32027
|
-
const stat2 =
|
|
33131
|
+
const stat2 = fs26.statSync(real);
|
|
32028
33132
|
if (!stat2.isFile()) return { error: "Not a file" };
|
|
32029
33133
|
return real;
|
|
32030
33134
|
}
|
|
32031
33135
|
var LINE_CHUNK_SIZE = 64 * 1024;
|
|
32032
33136
|
function readFileRange(filePath, startLine, endLine, lineOffsetIn, lineChunkSize = LINE_CHUNK_SIZE) {
|
|
32033
|
-
const fileSize =
|
|
32034
|
-
const fd =
|
|
33137
|
+
const fileSize = fs26.statSync(filePath).size;
|
|
33138
|
+
const fd = fs26.openSync(filePath, "r");
|
|
32035
33139
|
const bufSize = 64 * 1024;
|
|
32036
33140
|
const buf = Buffer.alloc(bufSize);
|
|
32037
33141
|
const decoder = new StringDecoder("utf8");
|
|
@@ -32044,7 +33148,7 @@ function readFileRange(filePath, startLine, endLine, lineOffsetIn, lineChunkSize
|
|
|
32044
33148
|
let line0Accum = "";
|
|
32045
33149
|
try {
|
|
32046
33150
|
let bytesRead;
|
|
32047
|
-
while (!done && (bytesRead =
|
|
33151
|
+
while (!done && (bytesRead = fs26.readSync(fd, buf, 0, bufSize, null)) > 0) {
|
|
32048
33152
|
const text = partial2 + decoder.write(buf.subarray(0, bytesRead));
|
|
32049
33153
|
partial2 = "";
|
|
32050
33154
|
let lineStart = 0;
|
|
@@ -32179,7 +33283,7 @@ function readFileRange(filePath, startLine, endLine, lineOffsetIn, lineChunkSize
|
|
|
32179
33283
|
}
|
|
32180
33284
|
return { content: resultLines.join("\n"), size: fileSize };
|
|
32181
33285
|
} finally {
|
|
32182
|
-
|
|
33286
|
+
fs26.closeSync(fd);
|
|
32183
33287
|
}
|
|
32184
33288
|
}
|
|
32185
33289
|
function readFile2(relativePath, startLine, endLine, lineOffset, lineChunkSize = LINE_CHUNK_SIZE) {
|
|
@@ -32190,8 +33294,8 @@ function readFile2(relativePath, startLine, endLine, lineOffset, lineChunkSize =
|
|
|
32190
33294
|
if (hasRange) {
|
|
32191
33295
|
return readFileRange(result, startLine, endLine, lineOffset, lineChunkSize);
|
|
32192
33296
|
}
|
|
32193
|
-
const stat2 =
|
|
32194
|
-
const raw =
|
|
33297
|
+
const stat2 = fs26.statSync(result);
|
|
33298
|
+
const raw = fs26.readFileSync(result, "utf8");
|
|
32195
33299
|
const lines = raw.split(/\r?\n/);
|
|
32196
33300
|
return { content: raw, totalLines: lines.length, size: stat2.size };
|
|
32197
33301
|
} catch (err) {
|
|
@@ -32301,10 +33405,10 @@ function handleSkillLayoutRequest(msg, deps) {
|
|
|
32301
33405
|
}
|
|
32302
33406
|
|
|
32303
33407
|
// src/skills/install-remote-skills.ts
|
|
32304
|
-
import
|
|
32305
|
-
import
|
|
33408
|
+
import fs27 from "node:fs";
|
|
33409
|
+
import path31 from "node:path";
|
|
32306
33410
|
function installRemoteSkills(cwd, targetDir, items) {
|
|
32307
|
-
const
|
|
33411
|
+
const installed2 = [];
|
|
32308
33412
|
if (!Array.isArray(items)) {
|
|
32309
33413
|
return { success: false, error: "Invalid items" };
|
|
32310
33414
|
}
|
|
@@ -32313,24 +33417,24 @@ function installRemoteSkills(cwd, targetDir, items) {
|
|
|
32313
33417
|
if (typeof item.sourceId !== "string" || typeof item.skillName !== "string" || typeof item.versionHash !== "string" || !Array.isArray(item.files)) {
|
|
32314
33418
|
continue;
|
|
32315
33419
|
}
|
|
32316
|
-
const skillDir =
|
|
33420
|
+
const skillDir = path31.join(cwd, targetDir, item.skillName);
|
|
32317
33421
|
for (const f of item.files) {
|
|
32318
33422
|
if (typeof f.path !== "string" || !f.text && !f.base64) continue;
|
|
32319
|
-
const dest =
|
|
32320
|
-
|
|
33423
|
+
const dest = path31.join(skillDir, f.path);
|
|
33424
|
+
fs27.mkdirSync(path31.dirname(dest), { recursive: true });
|
|
32321
33425
|
if (f.text !== void 0) {
|
|
32322
|
-
|
|
33426
|
+
fs27.writeFileSync(dest, f.text, "utf8");
|
|
32323
33427
|
} else if (f.base64) {
|
|
32324
|
-
|
|
33428
|
+
fs27.writeFileSync(dest, Buffer.from(f.base64, "base64"));
|
|
32325
33429
|
}
|
|
32326
33430
|
}
|
|
32327
|
-
|
|
33431
|
+
installed2.push({
|
|
32328
33432
|
sourceId: item.sourceId,
|
|
32329
33433
|
skillName: item.skillName,
|
|
32330
33434
|
versionHash: item.versionHash
|
|
32331
33435
|
});
|
|
32332
33436
|
}
|
|
32333
|
-
return { success: true, installed };
|
|
33437
|
+
return { success: true, installed: installed2 };
|
|
32334
33438
|
} catch (e) {
|
|
32335
33439
|
return { success: false, error: e instanceof Error ? e.message : String(e) };
|
|
32336
33440
|
}
|
|
@@ -32367,7 +33471,8 @@ var handleSessionGitRequestMessage = (msg, deps) => {
|
|
|
32367
33471
|
if (typeof msg.id !== "string") return;
|
|
32368
33472
|
const sessionId = typeof msg.sessionId === "string" ? msg.sessionId : "";
|
|
32369
33473
|
const action = msg.action;
|
|
32370
|
-
if (!sessionId || action !== "status" && action !== "push" && action !== "commit")
|
|
33474
|
+
if (!sessionId || action !== "status" && action !== "push" && action !== "commit" && action !== "list_changes")
|
|
33475
|
+
return;
|
|
32371
33476
|
void (async () => {
|
|
32372
33477
|
const ws = deps.getWs();
|
|
32373
33478
|
const reply = (payload) => sendResult(ws, msg.id, payload);
|
|
@@ -32381,6 +33486,24 @@ var handleSessionGitRequestMessage = (msg, deps) => {
|
|
|
32381
33486
|
});
|
|
32382
33487
|
return;
|
|
32383
33488
|
}
|
|
33489
|
+
if (action === "list_changes") {
|
|
33490
|
+
const repoRel = typeof msg.changesRepoRelPath === "string" ? msg.changesRepoRelPath.trim() : "";
|
|
33491
|
+
const view = msg.changesView === "commit" ? "commit" : "working";
|
|
33492
|
+
const commitSha = typeof msg.changesCommitSha === "string" ? msg.changesCommitSha.trim() : "";
|
|
33493
|
+
if (view === "commit") {
|
|
33494
|
+
if (!repoRel || !commitSha) {
|
|
33495
|
+
reply({ ok: false, error: "changesRepoRelPath and changesCommitSha are required for commit view" });
|
|
33496
|
+
return;
|
|
33497
|
+
}
|
|
33498
|
+
}
|
|
33499
|
+
const opts = repoRel && view === "commit" && commitSha ? { repoRelPath: repoRel, basis: { kind: "commit", sha: commitSha } } : repoRel ? { repoRelPath: repoRel, basis: { kind: "working" } } : void 0;
|
|
33500
|
+
const repos = await deps.sessionWorktreeManager.getSessionWorkingTreeChangeDetails(sessionId, opts);
|
|
33501
|
+
reply({
|
|
33502
|
+
ok: true,
|
|
33503
|
+
repos
|
|
33504
|
+
});
|
|
33505
|
+
return;
|
|
33506
|
+
}
|
|
32384
33507
|
if (action === "push") {
|
|
32385
33508
|
const pushRes = await deps.sessionWorktreeManager.pushSessionUpstream(sessionId);
|
|
32386
33509
|
if (!pushRes.ok) {
|
|
@@ -32447,7 +33570,7 @@ var handleSessionDiscardedMessage = (msg, deps) => {
|
|
|
32447
33570
|
};
|
|
32448
33571
|
|
|
32449
33572
|
// src/bridge/routing/handlers/revert-turn-snapshot.ts
|
|
32450
|
-
import * as
|
|
33573
|
+
import * as fs28 from "node:fs";
|
|
32451
33574
|
var handleRevertTurnSnapshotMessage = (msg, deps) => {
|
|
32452
33575
|
const id = typeof msg.id === "string" ? msg.id : "";
|
|
32453
33576
|
const sessionId = typeof msg.sessionId === "string" ? msg.sessionId : "";
|
|
@@ -32459,7 +33582,7 @@ var handleRevertTurnSnapshotMessage = (msg, deps) => {
|
|
|
32459
33582
|
if (!s) return;
|
|
32460
33583
|
const agentBase = sessionWorktreeManager.getAgentCwdForSession(sessionId) ?? getBridgeWorkspaceDirectory();
|
|
32461
33584
|
const file2 = snapshotFilePath(agentBase, turnId);
|
|
32462
|
-
if (!
|
|
33585
|
+
if (!fs28.existsSync(file2)) {
|
|
32463
33586
|
sendWsMessage(s, {
|
|
32464
33587
|
type: "revert_turn_snapshot_result",
|
|
32465
33588
|
id,
|
|
@@ -32788,6 +33911,7 @@ async function createBridgeConnection(options) {
|
|
|
32788
33911
|
|
|
32789
33912
|
// src/run-bridge.ts
|
|
32790
33913
|
async function runBridge(options) {
|
|
33914
|
+
installBridgeProcessResilience();
|
|
32791
33915
|
const { apiUrl, workspaceId, authToken, refreshToken, bridgeName, justAuthenticated, worktreesRootAbs } = options;
|
|
32792
33916
|
const firehoseServerUrl = options.firehoseServerUrl ?? options.proxyServerUrl;
|
|
32793
33917
|
const hasAuth = workspaceId && authToken;
|