@buildautomaton/cli 0.1.14 → 0.1.16
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/README.md +4 -4
- package/dist/cli.js +1590 -590
- package/dist/cli.js.map +4 -4
- package/dist/index.js +1240 -442
- package/dist/index.js.map +4 -4
- package/package.json +4 -2
package/dist/index.js
CHANGED
|
@@ -2240,7 +2240,7 @@ var require_websocket = __commonJS({
|
|
|
2240
2240
|
var http = __require("http");
|
|
2241
2241
|
var net = __require("net");
|
|
2242
2242
|
var tls = __require("tls");
|
|
2243
|
-
var { randomBytes, createHash: createHash2 } = __require("crypto");
|
|
2243
|
+
var { randomBytes: randomBytes2, createHash: createHash2 } = __require("crypto");
|
|
2244
2244
|
var { Duplex, Readable: Readable2 } = __require("stream");
|
|
2245
2245
|
var { URL: URL2 } = __require("url");
|
|
2246
2246
|
var PerMessageDeflate = require_permessage_deflate();
|
|
@@ -2770,7 +2770,7 @@ var require_websocket = __commonJS({
|
|
|
2770
2770
|
}
|
|
2771
2771
|
}
|
|
2772
2772
|
const defaultPort = isSecure ? 443 : 80;
|
|
2773
|
-
const key =
|
|
2773
|
+
const key = randomBytes2(16).toString("base64");
|
|
2774
2774
|
const request = isSecure ? https2.request : http.request;
|
|
2775
2775
|
const protocolSet = /* @__PURE__ */ new Set();
|
|
2776
2776
|
let perMessageDeflate;
|
|
@@ -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,10 +7993,10 @@ 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);
|
|
@@ -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")
|
|
@@ -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;
|
|
@@ -22787,8 +22787,8 @@ var PREVIEW_API_BASE_PATH = "/__preview";
|
|
|
22787
22787
|
var PREVIEW_SECRET_HEADER = "X-Preview-Secret";
|
|
22788
22788
|
var DEFAULT_PORT = 3e3;
|
|
22789
22789
|
var DEFAULT_COMMAND = "npm run preview";
|
|
22790
|
-
var PREVIEW_COMMAND_ENV = "
|
|
22791
|
-
var PREVIEW_PORT_ENV = "
|
|
22790
|
+
var PREVIEW_COMMAND_ENV = "BUILDAUTOMATON_PREVIEW_COMMAND";
|
|
22791
|
+
var PREVIEW_PORT_ENV = "BUILDAUTOMATON_PREVIEW_PORT";
|
|
22792
22792
|
var previewProcess = null;
|
|
22793
22793
|
var previewPort = DEFAULT_PORT;
|
|
22794
22794
|
var previewSecret = "";
|
|
@@ -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, path31, 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
|
}
|
|
@@ -22841,7 +22841,7 @@ var OPERATIONS = [
|
|
|
22841
22841
|
var previewSkill = {
|
|
22842
22842
|
id: "preview",
|
|
22843
22843
|
name: "Preview",
|
|
22844
|
-
description: "Start and manage a local preview server that implements the BuildAutomaton Preview Server API. Configure the command with
|
|
22844
|
+
description: "Start and manage a local preview server that implements the BuildAutomaton Preview Server API. Configure the command with BUILDAUTOMATON_PREVIEW_COMMAND (default: npm run preview). The server receives PORT and PREVIEW_SECRET and must expose /__preview/status and /__preview/stop.",
|
|
22845
22845
|
operations: OPERATIONS,
|
|
22846
22846
|
async execute(operationId, params) {
|
|
22847
22847
|
const command = getPreviewCommand();
|
|
@@ -23040,8 +23040,521 @@ function installBridgeProcessResilience() {
|
|
|
23040
23040
|
});
|
|
23041
23041
|
}
|
|
23042
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
|
+
|
|
23043
23557
|
// src/auth/open-browser.ts
|
|
23044
|
-
import { execSync } from "node:child_process";
|
|
23045
23558
|
function isLocalApiUrl(apiUrl) {
|
|
23046
23559
|
try {
|
|
23047
23560
|
const u = new URL(apiUrl);
|
|
@@ -23051,8 +23564,11 @@ function isLocalApiUrl(apiUrl) {
|
|
|
23051
23564
|
return false;
|
|
23052
23565
|
}
|
|
23053
23566
|
}
|
|
23054
|
-
function
|
|
23055
|
-
|
|
23567
|
+
function appUrlForApiUrl(apiUrl) {
|
|
23568
|
+
return apiUrl && isLocalApiUrl(apiUrl) ? process.env.BUILDAUTOMATON_APP_URL ?? "http://localhost:3000" : process.env.BUILDAUTOMATON_APP_URL ?? "https://app.buildautomaton.com";
|
|
23569
|
+
}
|
|
23570
|
+
async function openBrowser(connectionId, initialWorkspaceId, preferredBridgeName, apiUrl, logFn = log) {
|
|
23571
|
+
const appUrl = appUrlForApiUrl(apiUrl);
|
|
23056
23572
|
let connectCliUrl = `${appUrl.replace(/\/$/, "")}/bridges/connect?connectionId=${connectionId}`;
|
|
23057
23573
|
if (initialWorkspaceId) {
|
|
23058
23574
|
try {
|
|
@@ -23065,10 +23581,11 @@ function openBrowser(connectionId, initialWorkspaceId, preferredBridgeName, apiU
|
|
|
23065
23581
|
connectCliUrl += `&bridgeName=${encodeURIComponent(preferredBridgeName.trim())}`;
|
|
23066
23582
|
}
|
|
23067
23583
|
logFn("Opening browser to link this CLI\u2026");
|
|
23068
|
-
logFn(
|
|
23584
|
+
logFn(
|
|
23585
|
+
"If you\u2019re already signed in with one workspace, the CLI will connect automatically. Otherwise sign in and link to a workspace."
|
|
23586
|
+
);
|
|
23069
23587
|
try {
|
|
23070
|
-
|
|
23071
|
-
execSync(`${cmd} "${connectCliUrl}"`, { stdio: "ignore" });
|
|
23588
|
+
await open_default(connectCliUrl, { wait: false });
|
|
23072
23589
|
} catch {
|
|
23073
23590
|
logFn("Could not open browser. Open this URL manually:");
|
|
23074
23591
|
logFn(connectCliUrl);
|
|
@@ -23323,7 +23840,7 @@ function runPendingAuth(options) {
|
|
|
23323
23840
|
}
|
|
23324
23841
|
if (!hasOpenedBrowser) {
|
|
23325
23842
|
hasOpenedBrowser = true;
|
|
23326
|
-
openBrowser(connectionId, initialWorkspaceId, preferredBridgeName, apiUrl, logFn);
|
|
23843
|
+
void openBrowser(connectionId, initialWorkspaceId, preferredBridgeName, apiUrl, logFn);
|
|
23327
23844
|
}
|
|
23328
23845
|
},
|
|
23329
23846
|
onClose: (code, reason) => {
|
|
@@ -23365,7 +23882,7 @@ function runPendingAuth(options) {
|
|
|
23365
23882
|
browserFallback = null;
|
|
23366
23883
|
if (!hasOpenedBrowser) {
|
|
23367
23884
|
hasOpenedBrowser = true;
|
|
23368
|
-
openBrowser(connectionId, initialWorkspaceId, preferredBridgeName, apiUrl, logFn);
|
|
23885
|
+
void openBrowser(connectionId, initialWorkspaceId, preferredBridgeName, apiUrl, logFn);
|
|
23369
23886
|
}
|
|
23370
23887
|
}, BROWSER_OPEN_FALLBACK_MS);
|
|
23371
23888
|
connect();
|
|
@@ -23425,27 +23942,27 @@ async function closeBridgeConnection(state, acpManager, devServerManager, log2)
|
|
|
23425
23942
|
}
|
|
23426
23943
|
|
|
23427
23944
|
// src/git/session-git-queue.ts
|
|
23428
|
-
import { execFile as
|
|
23945
|
+
import { execFile as execFile7 } from "node:child_process";
|
|
23429
23946
|
import { readFile, stat } from "node:fs/promises";
|
|
23430
|
-
import { promisify as
|
|
23431
|
-
import * as
|
|
23947
|
+
import { promisify as promisify7 } from "node:util";
|
|
23948
|
+
import * as path7 from "node:path";
|
|
23432
23949
|
|
|
23433
23950
|
// src/git/pre-turn-snapshot.ts
|
|
23434
|
-
import * as
|
|
23435
|
-
import * as
|
|
23436
|
-
import { execFile } from "node:child_process";
|
|
23437
|
-
import { promisify } from "node:util";
|
|
23951
|
+
import * as fs8 from "node:fs";
|
|
23952
|
+
import * as path6 from "node:path";
|
|
23953
|
+
import { execFile as execFile6 } from "node:child_process";
|
|
23954
|
+
import { promisify as promisify6 } from "node:util";
|
|
23438
23955
|
|
|
23439
23956
|
// src/git/discover-repos.ts
|
|
23440
|
-
import * as
|
|
23441
|
-
import * as
|
|
23957
|
+
import * as fs7 from "node:fs";
|
|
23958
|
+
import * as path5 from "node:path";
|
|
23442
23959
|
|
|
23443
23960
|
// ../../node_modules/.pnpm/simple-git@3.32.3/node_modules/simple-git/dist/esm/index.js
|
|
23444
23961
|
var import_file_exists = __toESM(require_dist(), 1);
|
|
23445
23962
|
var import_debug = __toESM(require_src(), 1);
|
|
23446
23963
|
var import_promise_deferred = __toESM(require_dist2(), 1);
|
|
23447
23964
|
var import_promise_deferred2 = __toESM(require_dist2(), 1);
|
|
23448
|
-
import { Buffer as
|
|
23965
|
+
import { Buffer as Buffer22 } from "node:buffer";
|
|
23449
23966
|
import { spawn as spawn3 } from "child_process";
|
|
23450
23967
|
import { normalize as normalize2 } from "node:path";
|
|
23451
23968
|
import { EventEmitter } from "node:events";
|
|
@@ -23477,8 +23994,8 @@ function pathspec(...paths) {
|
|
|
23477
23994
|
cache.set(key, paths);
|
|
23478
23995
|
return key;
|
|
23479
23996
|
}
|
|
23480
|
-
function isPathSpec(
|
|
23481
|
-
return
|
|
23997
|
+
function isPathSpec(path32) {
|
|
23998
|
+
return path32 instanceof String && cache.has(path32);
|
|
23482
23999
|
}
|
|
23483
24000
|
function toPaths(pathSpec) {
|
|
23484
24001
|
return cache.get(pathSpec) || [];
|
|
@@ -23567,8 +24084,8 @@ function toLinesWithContent(input = "", trimmed2 = true, separator = "\n") {
|
|
|
23567
24084
|
function forEachLineWithContent(input, callback) {
|
|
23568
24085
|
return toLinesWithContent(input, true).map((line) => callback(line));
|
|
23569
24086
|
}
|
|
23570
|
-
function folderExists(
|
|
23571
|
-
return (0, import_file_exists.exists)(
|
|
24087
|
+
function folderExists(path32) {
|
|
24088
|
+
return (0, import_file_exists.exists)(path32, import_file_exists.FOLDER);
|
|
23572
24089
|
}
|
|
23573
24090
|
function append(target, item) {
|
|
23574
24091
|
if (Array.isArray(target)) {
|
|
@@ -23625,7 +24142,7 @@ function prefixedArray(input, prefix) {
|
|
|
23625
24142
|
return output;
|
|
23626
24143
|
}
|
|
23627
24144
|
function bufferToString(input) {
|
|
23628
|
-
return (Array.isArray(input) ?
|
|
24145
|
+
return (Array.isArray(input) ? Buffer22.concat(input) : input).toString("utf-8");
|
|
23629
24146
|
}
|
|
23630
24147
|
function pick2(source, properties) {
|
|
23631
24148
|
const out = {};
|
|
@@ -23972,8 +24489,8 @@ function checkIsRepoRootTask() {
|
|
|
23972
24489
|
commands,
|
|
23973
24490
|
format: "utf-8",
|
|
23974
24491
|
onError,
|
|
23975
|
-
parser(
|
|
23976
|
-
return /^\.(git)?$/.test(
|
|
24492
|
+
parser(path32) {
|
|
24493
|
+
return /^\.(git)?$/.test(path32.trim());
|
|
23977
24494
|
}
|
|
23978
24495
|
};
|
|
23979
24496
|
}
|
|
@@ -24407,11 +24924,11 @@ function parseGrep(grep) {
|
|
|
24407
24924
|
const paths = /* @__PURE__ */ new Set();
|
|
24408
24925
|
const results = {};
|
|
24409
24926
|
forEachLineWithContent(grep, (input) => {
|
|
24410
|
-
const [
|
|
24411
|
-
paths.add(
|
|
24412
|
-
(results[
|
|
24927
|
+
const [path32, line, preview] = input.split(NULL);
|
|
24928
|
+
paths.add(path32);
|
|
24929
|
+
(results[path32] = results[path32] || []).push({
|
|
24413
24930
|
line: asNumber(line),
|
|
24414
|
-
path:
|
|
24931
|
+
path: path32,
|
|
24415
24932
|
preview
|
|
24416
24933
|
});
|
|
24417
24934
|
});
|
|
@@ -25176,14 +25693,14 @@ var init_hash_object = __esm2({
|
|
|
25176
25693
|
init_task();
|
|
25177
25694
|
}
|
|
25178
25695
|
});
|
|
25179
|
-
function parseInit(bare,
|
|
25696
|
+
function parseInit(bare, path32, text) {
|
|
25180
25697
|
const response = String(text).trim();
|
|
25181
25698
|
let result;
|
|
25182
25699
|
if (result = initResponseRegex.exec(response)) {
|
|
25183
|
-
return new InitSummary(bare,
|
|
25700
|
+
return new InitSummary(bare, path32, false, result[1]);
|
|
25184
25701
|
}
|
|
25185
25702
|
if (result = reInitResponseRegex.exec(response)) {
|
|
25186
|
-
return new InitSummary(bare,
|
|
25703
|
+
return new InitSummary(bare, path32, true, result[1]);
|
|
25187
25704
|
}
|
|
25188
25705
|
let gitDir = "";
|
|
25189
25706
|
const tokens = response.split(" ");
|
|
@@ -25194,7 +25711,7 @@ function parseInit(bare, path31, text) {
|
|
|
25194
25711
|
break;
|
|
25195
25712
|
}
|
|
25196
25713
|
}
|
|
25197
|
-
return new InitSummary(bare,
|
|
25714
|
+
return new InitSummary(bare, path32, /^re/i.test(response), gitDir);
|
|
25198
25715
|
}
|
|
25199
25716
|
var InitSummary;
|
|
25200
25717
|
var initResponseRegex;
|
|
@@ -25203,9 +25720,9 @@ var init_InitSummary = __esm2({
|
|
|
25203
25720
|
"src/lib/responses/InitSummary.ts"() {
|
|
25204
25721
|
"use strict";
|
|
25205
25722
|
InitSummary = class {
|
|
25206
|
-
constructor(bare,
|
|
25723
|
+
constructor(bare, path32, existing, gitDir) {
|
|
25207
25724
|
this.bare = bare;
|
|
25208
|
-
this.path =
|
|
25725
|
+
this.path = path32;
|
|
25209
25726
|
this.existing = existing;
|
|
25210
25727
|
this.gitDir = gitDir;
|
|
25211
25728
|
}
|
|
@@ -25217,7 +25734,7 @@ var init_InitSummary = __esm2({
|
|
|
25217
25734
|
function hasBareCommand(command) {
|
|
25218
25735
|
return command.includes(bareCommand);
|
|
25219
25736
|
}
|
|
25220
|
-
function initTask(bare = false,
|
|
25737
|
+
function initTask(bare = false, path32, customArgs) {
|
|
25221
25738
|
const commands = ["init", ...customArgs];
|
|
25222
25739
|
if (bare && !hasBareCommand(commands)) {
|
|
25223
25740
|
commands.splice(1, 0, bareCommand);
|
|
@@ -25226,7 +25743,7 @@ function initTask(bare = false, path31, customArgs) {
|
|
|
25226
25743
|
commands,
|
|
25227
25744
|
format: "utf-8",
|
|
25228
25745
|
parser(text) {
|
|
25229
|
-
return parseInit(commands.includes("--bare"),
|
|
25746
|
+
return parseInit(commands.includes("--bare"), path32, text);
|
|
25230
25747
|
}
|
|
25231
25748
|
};
|
|
25232
25749
|
}
|
|
@@ -26042,12 +26559,12 @@ var init_FileStatusSummary = __esm2({
|
|
|
26042
26559
|
"use strict";
|
|
26043
26560
|
fromPathRegex = /^(.+)\0(.+)$/;
|
|
26044
26561
|
FileStatusSummary = class {
|
|
26045
|
-
constructor(
|
|
26046
|
-
this.path =
|
|
26562
|
+
constructor(path32, index, working_dir) {
|
|
26563
|
+
this.path = path32;
|
|
26047
26564
|
this.index = index;
|
|
26048
26565
|
this.working_dir = working_dir;
|
|
26049
26566
|
if (index === "R" || working_dir === "R") {
|
|
26050
|
-
const detail = fromPathRegex.exec(
|
|
26567
|
+
const detail = fromPathRegex.exec(path32) || [null, path32, path32];
|
|
26051
26568
|
this.from = detail[2] || "";
|
|
26052
26569
|
this.path = detail[1] || "";
|
|
26053
26570
|
}
|
|
@@ -26078,14 +26595,14 @@ function splitLine(result, lineStr) {
|
|
|
26078
26595
|
default:
|
|
26079
26596
|
return;
|
|
26080
26597
|
}
|
|
26081
|
-
function data(index, workingDir,
|
|
26598
|
+
function data(index, workingDir, path32) {
|
|
26082
26599
|
const raw = `${index}${workingDir}`;
|
|
26083
26600
|
const handler = parsers6.get(raw);
|
|
26084
26601
|
if (handler) {
|
|
26085
|
-
handler(result,
|
|
26602
|
+
handler(result, path32);
|
|
26086
26603
|
}
|
|
26087
26604
|
if (raw !== "##" && raw !== "!!") {
|
|
26088
|
-
result.files.push(new FileStatusSummary(
|
|
26605
|
+
result.files.push(new FileStatusSummary(path32, index, workingDir));
|
|
26089
26606
|
}
|
|
26090
26607
|
}
|
|
26091
26608
|
}
|
|
@@ -26394,9 +26911,9 @@ var init_simple_git_api = __esm2({
|
|
|
26394
26911
|
next
|
|
26395
26912
|
);
|
|
26396
26913
|
}
|
|
26397
|
-
hashObject(
|
|
26914
|
+
hashObject(path32, write) {
|
|
26398
26915
|
return this._runTask(
|
|
26399
|
-
hashObjectTask(
|
|
26916
|
+
hashObjectTask(path32, write === true),
|
|
26400
26917
|
trailingFunctionArgument(arguments)
|
|
26401
26918
|
);
|
|
26402
26919
|
}
|
|
@@ -26749,8 +27266,8 @@ var init_branch = __esm2({
|
|
|
26749
27266
|
}
|
|
26750
27267
|
});
|
|
26751
27268
|
function toPath(input) {
|
|
26752
|
-
const
|
|
26753
|
-
return
|
|
27269
|
+
const path32 = input.trim().replace(/^["']|["']$/g, "");
|
|
27270
|
+
return path32 && normalize2(path32);
|
|
26754
27271
|
}
|
|
26755
27272
|
var parseCheckIgnore;
|
|
26756
27273
|
var init_CheckIgnore = __esm2({
|
|
@@ -27064,8 +27581,8 @@ __export2(sub_module_exports, {
|
|
|
27064
27581
|
subModuleTask: () => subModuleTask,
|
|
27065
27582
|
updateSubModuleTask: () => updateSubModuleTask
|
|
27066
27583
|
});
|
|
27067
|
-
function addSubModuleTask(repo,
|
|
27068
|
-
return subModuleTask(["add", repo,
|
|
27584
|
+
function addSubModuleTask(repo, path32) {
|
|
27585
|
+
return subModuleTask(["add", repo, path32]);
|
|
27069
27586
|
}
|
|
27070
27587
|
function initSubModuleTask(customArgs) {
|
|
27071
27588
|
return subModuleTask(["init", ...customArgs]);
|
|
@@ -27398,8 +27915,8 @@ var require_git = __commonJS2({
|
|
|
27398
27915
|
}
|
|
27399
27916
|
return this._runTask(straightThroughStringTask2(command, this._trimmed), next);
|
|
27400
27917
|
};
|
|
27401
|
-
Git2.prototype.submoduleAdd = function(repo,
|
|
27402
|
-
return this._runTask(addSubModuleTask2(repo,
|
|
27918
|
+
Git2.prototype.submoduleAdd = function(repo, path32, then) {
|
|
27919
|
+
return this._runTask(addSubModuleTask2(repo, path32), trailingFunctionArgument2(arguments));
|
|
27403
27920
|
};
|
|
27404
27921
|
Git2.prototype.submoduleUpdate = function(args, then) {
|
|
27405
27922
|
return this._runTask(
|
|
@@ -28025,20 +28542,20 @@ async function isGitRepoDirectory(dirPath) {
|
|
|
28025
28542
|
// src/git/discover-repos.ts
|
|
28026
28543
|
async function discoverGitRepos(cwd = getBridgeWorkspaceDirectory()) {
|
|
28027
28544
|
const result = [];
|
|
28028
|
-
const cwdResolved =
|
|
28545
|
+
const cwdResolved = path5.resolve(cwd);
|
|
28029
28546
|
if (await isGitRepoDirectory(cwdResolved)) {
|
|
28030
28547
|
const remoteUrl = await getRemoteOriginUrl(cwdResolved);
|
|
28031
28548
|
result.push({ absolutePath: cwdResolved, remoteUrl });
|
|
28032
28549
|
}
|
|
28033
28550
|
let entries;
|
|
28034
28551
|
try {
|
|
28035
|
-
entries =
|
|
28552
|
+
entries = fs7.readdirSync(cwdResolved, { withFileTypes: true });
|
|
28036
28553
|
} catch {
|
|
28037
28554
|
return result;
|
|
28038
28555
|
}
|
|
28039
28556
|
for (const ent of entries) {
|
|
28040
28557
|
if (!ent.isDirectory()) continue;
|
|
28041
|
-
const childPath =
|
|
28558
|
+
const childPath = path5.join(cwdResolved, ent.name);
|
|
28042
28559
|
if (await isGitRepoDirectory(childPath)) {
|
|
28043
28560
|
const remoteUrl = await getRemoteOriginUrl(childPath);
|
|
28044
28561
|
result.push({ absolutePath: childPath, remoteUrl });
|
|
@@ -28047,22 +28564,22 @@ async function discoverGitRepos(cwd = getBridgeWorkspaceDirectory()) {
|
|
|
28047
28564
|
return result;
|
|
28048
28565
|
}
|
|
28049
28566
|
async function discoverGitReposUnderRoot(rootAbs) {
|
|
28050
|
-
const root =
|
|
28567
|
+
const root = path5.resolve(rootAbs);
|
|
28051
28568
|
const roots = [];
|
|
28052
28569
|
async function walk(dir) {
|
|
28053
28570
|
if (await isGitRepoDirectory(dir)) {
|
|
28054
|
-
roots.push(
|
|
28571
|
+
roots.push(path5.resolve(dir));
|
|
28055
28572
|
return;
|
|
28056
28573
|
}
|
|
28057
28574
|
let entries;
|
|
28058
28575
|
try {
|
|
28059
|
-
entries =
|
|
28576
|
+
entries = fs7.readdirSync(dir, { withFileTypes: true });
|
|
28060
28577
|
} catch {
|
|
28061
28578
|
return;
|
|
28062
28579
|
}
|
|
28063
28580
|
for (const ent of entries) {
|
|
28064
28581
|
if (!ent.isDirectory() || ent.name === ".git") continue;
|
|
28065
|
-
await walk(
|
|
28582
|
+
await walk(path5.join(dir, ent.name));
|
|
28066
28583
|
}
|
|
28067
28584
|
}
|
|
28068
28585
|
await walk(root);
|
|
@@ -28076,13 +28593,13 @@ async function discoverGitReposUnderRoot(rootAbs) {
|
|
|
28076
28593
|
}
|
|
28077
28594
|
|
|
28078
28595
|
// src/git/pre-turn-snapshot.ts
|
|
28079
|
-
var
|
|
28596
|
+
var execFileAsync5 = promisify6(execFile6);
|
|
28080
28597
|
function snapshotsDirForCwd(agentCwd) {
|
|
28081
|
-
return
|
|
28598
|
+
return path6.join(agentCwd, ".buildautomaton", "snapshots");
|
|
28082
28599
|
}
|
|
28083
28600
|
async function gitStashCreate(repoRoot, log2) {
|
|
28084
28601
|
try {
|
|
28085
|
-
const { stdout } = await
|
|
28602
|
+
const { stdout } = await execFileAsync5("git", ["stash", "create"], {
|
|
28086
28603
|
cwd: repoRoot,
|
|
28087
28604
|
maxBuffer: 10 * 1024 * 1024
|
|
28088
28605
|
});
|
|
@@ -28096,7 +28613,7 @@ async function gitStashCreate(repoRoot, log2) {
|
|
|
28096
28613
|
}
|
|
28097
28614
|
async function gitRun(repoRoot, args, log2, label) {
|
|
28098
28615
|
try {
|
|
28099
|
-
await
|
|
28616
|
+
await execFileAsync5("git", args, { cwd: repoRoot, maxBuffer: 10 * 1024 * 1024 });
|
|
28100
28617
|
return { ok: true };
|
|
28101
28618
|
} catch (e) {
|
|
28102
28619
|
const msg = e instanceof Error ? e.message : String(e);
|
|
@@ -28107,7 +28624,7 @@ async function gitRun(repoRoot, args, log2, label) {
|
|
|
28107
28624
|
async function resolveSnapshotRepoRoots(options) {
|
|
28108
28625
|
const { worktreePaths, fallbackCwd, log: log2 } = options;
|
|
28109
28626
|
if (worktreePaths?.length) {
|
|
28110
|
-
const uniq = [...new Set(worktreePaths.map((p) =>
|
|
28627
|
+
const uniq = [...new Set(worktreePaths.map((p) => path6.resolve(p)))];
|
|
28111
28628
|
return uniq;
|
|
28112
28629
|
}
|
|
28113
28630
|
try {
|
|
@@ -28130,7 +28647,7 @@ async function capturePreTurnSnapshot(options) {
|
|
|
28130
28647
|
}
|
|
28131
28648
|
const dir = snapshotsDirForCwd(agentCwd);
|
|
28132
28649
|
try {
|
|
28133
|
-
|
|
28650
|
+
fs8.mkdirSync(dir, { recursive: true });
|
|
28134
28651
|
} catch (e) {
|
|
28135
28652
|
return { ok: false, error: e instanceof Error ? e.message : String(e) };
|
|
28136
28653
|
}
|
|
@@ -28139,9 +28656,9 @@ async function capturePreTurnSnapshot(options) {
|
|
|
28139
28656
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
28140
28657
|
repos
|
|
28141
28658
|
};
|
|
28142
|
-
const filePath =
|
|
28659
|
+
const filePath = path6.join(dir, `${runId}.json`);
|
|
28143
28660
|
try {
|
|
28144
|
-
|
|
28661
|
+
fs8.writeFileSync(filePath, JSON.stringify(payload, null, 2), "utf8");
|
|
28145
28662
|
} catch (e) {
|
|
28146
28663
|
return { ok: false, error: e instanceof Error ? e.message : String(e) };
|
|
28147
28664
|
}
|
|
@@ -28154,7 +28671,7 @@ async function capturePreTurnSnapshot(options) {
|
|
|
28154
28671
|
async function applyPreTurnSnapshot(filePath, log2) {
|
|
28155
28672
|
let data;
|
|
28156
28673
|
try {
|
|
28157
|
-
const raw =
|
|
28674
|
+
const raw = fs8.readFileSync(filePath, "utf8");
|
|
28158
28675
|
data = JSON.parse(raw);
|
|
28159
28676
|
} catch (e) {
|
|
28160
28677
|
return { ok: false, error: e instanceof Error ? e.message : String(e) };
|
|
@@ -28177,11 +28694,11 @@ async function applyPreTurnSnapshot(filePath, log2) {
|
|
|
28177
28694
|
return { ok: true };
|
|
28178
28695
|
}
|
|
28179
28696
|
function snapshotFilePath(agentCwd, runId) {
|
|
28180
|
-
return
|
|
28697
|
+
return path6.join(snapshotsDirForCwd(agentCwd), `${runId}.json`);
|
|
28181
28698
|
}
|
|
28182
28699
|
|
|
28183
28700
|
// src/git/session-git-queue.ts
|
|
28184
|
-
var
|
|
28701
|
+
var execFileAsync6 = promisify7(execFile7);
|
|
28185
28702
|
var MAX_FULL_FILE_TEXT_BYTES = 512 * 1024;
|
|
28186
28703
|
async function readWorkspaceFileAsUtf8(absPath) {
|
|
28187
28704
|
try {
|
|
@@ -28214,7 +28731,7 @@ async function collectTurnGitDiffFromPreTurnSnapshot(options) {
|
|
|
28214
28731
|
if (!repo.stashSha) continue;
|
|
28215
28732
|
let namesRaw;
|
|
28216
28733
|
try {
|
|
28217
|
-
const { stdout } = await
|
|
28734
|
+
const { stdout } = await execFileAsync6("git", ["diff", "--name-only", repo.stashSha], {
|
|
28218
28735
|
cwd: repo.path,
|
|
28219
28736
|
maxBuffer: 10 * 1024 * 1024
|
|
28220
28737
|
});
|
|
@@ -28226,11 +28743,11 @@ async function collectTurnGitDiffFromPreTurnSnapshot(options) {
|
|
|
28226
28743
|
continue;
|
|
28227
28744
|
}
|
|
28228
28745
|
const lines = namesRaw.split("\n").map((l) => l.trim()).filter(Boolean);
|
|
28229
|
-
const slug =
|
|
28746
|
+
const slug = path7.basename(repo.path).replace(/[^\w.-]+/g, "_") || "repo";
|
|
28230
28747
|
for (const rel of lines) {
|
|
28231
28748
|
if (rel.includes("..")) continue;
|
|
28232
28749
|
try {
|
|
28233
|
-
const { stdout: patchContent } = await
|
|
28750
|
+
const { stdout: patchContent } = await execFileAsync6(
|
|
28234
28751
|
"git",
|
|
28235
28752
|
["diff", "--no-color", repo.stashSha, "--", rel],
|
|
28236
28753
|
{
|
|
@@ -28240,7 +28757,7 @@ async function collectTurnGitDiffFromPreTurnSnapshot(options) {
|
|
|
28240
28757
|
);
|
|
28241
28758
|
if (!patchContent.trim()) continue;
|
|
28242
28759
|
const displayPath = multiRepo ? `${slug}/${rel}` : rel;
|
|
28243
|
-
const absFile =
|
|
28760
|
+
const absFile = path7.join(repo.path, rel);
|
|
28244
28761
|
const newText = await readWorkspaceFileAsUtf8(absFile);
|
|
28245
28762
|
sendSessionUpdate({
|
|
28246
28763
|
type: "session_file_change",
|
|
@@ -28302,7 +28819,9 @@ async function sendPromptToAgent(options) {
|
|
|
28302
28819
|
...augmentAuthFields(errStr)
|
|
28303
28820
|
});
|
|
28304
28821
|
if (!result.success) {
|
|
28305
|
-
log2(
|
|
28822
|
+
log2(
|
|
28823
|
+
`[Agent] Prompt did not run successfully on the agent (no successful start/completion): ${result.error ?? "Unknown error"}`
|
|
28824
|
+
);
|
|
28306
28825
|
}
|
|
28307
28826
|
} catch (err) {
|
|
28308
28827
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
@@ -28320,8 +28839,8 @@ async function sendPromptToAgent(options) {
|
|
|
28320
28839
|
}
|
|
28321
28840
|
|
|
28322
28841
|
// src/agents/acp/ensure-acp-client.ts
|
|
28323
|
-
import * as
|
|
28324
|
-
import * as
|
|
28842
|
+
import * as fs9 from "node:fs";
|
|
28843
|
+
import * as path10 from "node:path";
|
|
28325
28844
|
|
|
28326
28845
|
// src/error-message.ts
|
|
28327
28846
|
function errorMessage(err) {
|
|
@@ -28341,16 +28860,16 @@ __export(claude_code_acp_client_exports, {
|
|
|
28341
28860
|
createClaudeCodeAcpClient: () => createClaudeCodeAcpClient,
|
|
28342
28861
|
detectLocalAgentPresence: () => detectLocalAgentPresence
|
|
28343
28862
|
});
|
|
28344
|
-
import { execFile as
|
|
28345
|
-
import { promisify as
|
|
28863
|
+
import { execFile as execFile9 } from "node:child_process";
|
|
28864
|
+
import { promisify as promisify9 } from "node:util";
|
|
28346
28865
|
|
|
28347
28866
|
// src/agents/acp/clients/detect-command-on-path.ts
|
|
28348
|
-
import { execFile as
|
|
28349
|
-
import { promisify as
|
|
28350
|
-
var
|
|
28867
|
+
import { execFile as execFile8 } from "node:child_process";
|
|
28868
|
+
import { promisify as promisify8 } from "node:util";
|
|
28869
|
+
var execFileAsync7 = promisify8(execFile8);
|
|
28351
28870
|
async function isCommandOnPath(command, timeoutMs = 4e3) {
|
|
28352
28871
|
try {
|
|
28353
|
-
await
|
|
28872
|
+
await execFileAsync7("which", [command], { timeout: timeoutMs });
|
|
28354
28873
|
return true;
|
|
28355
28874
|
} catch {
|
|
28356
28875
|
return false;
|
|
@@ -28358,12 +28877,12 @@ async function isCommandOnPath(command, timeoutMs = 4e3) {
|
|
|
28358
28877
|
}
|
|
28359
28878
|
|
|
28360
28879
|
// src/agents/acp/clients/claude-code-acp-client.ts
|
|
28361
|
-
var
|
|
28880
|
+
var execFileAsync8 = promisify9(execFile9);
|
|
28362
28881
|
var BACKEND_LOCAL_AGENT_TYPE = "claude-code";
|
|
28363
28882
|
async function detectLocalAgentPresence() {
|
|
28364
28883
|
if (await isCommandOnPath("claude")) return true;
|
|
28365
28884
|
try {
|
|
28366
|
-
await
|
|
28885
|
+
await execFileAsync8("npx", ["--yes", "@anthropic-ai/claude-code", "--version"], { timeout: 25e3 });
|
|
28367
28886
|
return true;
|
|
28368
28887
|
} catch {
|
|
28369
28888
|
return false;
|
|
@@ -28478,7 +28997,7 @@ async function createCursorAcpClient(options) {
|
|
|
28478
28997
|
onRequest,
|
|
28479
28998
|
onFileChange
|
|
28480
28999
|
} = options;
|
|
28481
|
-
const dbgFs = process.env.
|
|
29000
|
+
const dbgFs = process.env.BUILDAUTOMATON_DEBUG_ACP_FS === "1";
|
|
28482
29001
|
const isWindows = process.platform === "win32";
|
|
28483
29002
|
const child = spawn4(command[0], command.slice(1), {
|
|
28484
29003
|
cwd,
|
|
@@ -28861,48 +29380,48 @@ function resolveAgentCommand(preferredAgentType) {
|
|
|
28861
29380
|
}
|
|
28862
29381
|
|
|
28863
29382
|
// src/agents/acp/session-file-change-path-kind.ts
|
|
28864
|
-
import { execFileSync as
|
|
29383
|
+
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
28865
29384
|
import { existsSync, statSync } from "node:fs";
|
|
28866
29385
|
|
|
28867
29386
|
// src/git/get-git-repo-root-sync.ts
|
|
28868
|
-
import { execFileSync } from "node:child_process";
|
|
28869
|
-
import * as
|
|
29387
|
+
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
29388
|
+
import * as path8 from "node:path";
|
|
28870
29389
|
function getGitRepoRootSync(startDir) {
|
|
28871
29390
|
try {
|
|
28872
|
-
const out =
|
|
28873
|
-
cwd:
|
|
29391
|
+
const out = execFileSync2("git", ["rev-parse", "--show-toplevel"], {
|
|
29392
|
+
cwd: path8.resolve(startDir),
|
|
28874
29393
|
encoding: "utf8",
|
|
28875
29394
|
stdio: ["ignore", "pipe", "ignore"],
|
|
28876
29395
|
maxBuffer: 1024 * 1024
|
|
28877
29396
|
}).trim();
|
|
28878
|
-
return out ?
|
|
29397
|
+
return out ? path8.resolve(out) : null;
|
|
28879
29398
|
} catch {
|
|
28880
29399
|
return null;
|
|
28881
29400
|
}
|
|
28882
29401
|
}
|
|
28883
29402
|
|
|
28884
29403
|
// src/agents/acp/workspace-files.ts
|
|
28885
|
-
import { execFileSync as
|
|
29404
|
+
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
28886
29405
|
import { readFileSync as readFileSync4 } from "node:fs";
|
|
28887
|
-
import * as
|
|
29406
|
+
import * as path9 from "node:path";
|
|
28888
29407
|
function resolveWorkspaceFilePath(cwd, rawPath) {
|
|
28889
29408
|
const trimmed2 = rawPath.trim();
|
|
28890
29409
|
if (!trimmed2) return null;
|
|
28891
|
-
const normalizedCwd =
|
|
29410
|
+
const normalizedCwd = path9.resolve(cwd);
|
|
28892
29411
|
let abs = resolveSafePathUnderCwd(cwd, trimmed2);
|
|
28893
29412
|
if (!abs) {
|
|
28894
|
-
const candidate =
|
|
29413
|
+
const candidate = path9.isAbsolute(trimmed2) ? path9.normalize(trimmed2) : path9.normalize(path9.resolve(normalizedCwd, trimmed2));
|
|
28895
29414
|
const gitRoot2 = getGitRepoRootSync(cwd);
|
|
28896
29415
|
if (!gitRoot2) return null;
|
|
28897
|
-
const rel =
|
|
28898
|
-
if (rel.startsWith("..") ||
|
|
29416
|
+
const rel = path9.relative(gitRoot2, candidate);
|
|
29417
|
+
if (rel.startsWith("..") || path9.isAbsolute(rel)) return null;
|
|
28899
29418
|
abs = candidate;
|
|
28900
29419
|
}
|
|
28901
29420
|
const gitRoot = getGitRepoRootSync(cwd);
|
|
28902
29421
|
if (gitRoot) {
|
|
28903
|
-
const relFromRoot =
|
|
28904
|
-
if (!relFromRoot.startsWith("..") && !
|
|
28905
|
-
return { abs, display: relFromRoot.split(
|
|
29422
|
+
const relFromRoot = path9.relative(gitRoot, abs);
|
|
29423
|
+
if (!relFromRoot.startsWith("..") && !path9.isAbsolute(relFromRoot)) {
|
|
29424
|
+
return { abs, display: relFromRoot.split(path9.sep).join("/") };
|
|
28906
29425
|
}
|
|
28907
29426
|
}
|
|
28908
29427
|
return { abs, display: toDisplayPathRelativeToCwd(cwd, abs) };
|
|
@@ -28911,9 +29430,9 @@ function readUtf8WorkspaceFile(cwd, displayPath) {
|
|
|
28911
29430
|
if (!displayPath || displayPath.includes("..")) return "";
|
|
28912
29431
|
const gitRoot = getGitRepoRootSync(cwd);
|
|
28913
29432
|
if (gitRoot) {
|
|
28914
|
-
const abs2 =
|
|
28915
|
-
const rel =
|
|
28916
|
-
if (!rel.startsWith("..") && !
|
|
29433
|
+
const abs2 = path9.resolve(gitRoot, displayPath);
|
|
29434
|
+
const rel = path9.relative(gitRoot, abs2);
|
|
29435
|
+
if (!rel.startsWith("..") && !path9.isAbsolute(rel)) {
|
|
28917
29436
|
try {
|
|
28918
29437
|
return readFileSync4(abs2, "utf8");
|
|
28919
29438
|
} catch {
|
|
@@ -28932,9 +29451,9 @@ function tryWorkspaceDisplayToAbs(cwd, displayPath) {
|
|
|
28932
29451
|
if (!displayPath || displayPath.includes("..")) return null;
|
|
28933
29452
|
const gitRoot = getGitRepoRootSync(cwd);
|
|
28934
29453
|
if (gitRoot) {
|
|
28935
|
-
const abs =
|
|
28936
|
-
const rel =
|
|
28937
|
-
if (!rel.startsWith("..") && !
|
|
29454
|
+
const abs = path9.resolve(gitRoot, displayPath);
|
|
29455
|
+
const rel = path9.relative(gitRoot, abs);
|
|
29456
|
+
if (!rel.startsWith("..") && !path9.isAbsolute(rel)) return abs;
|
|
28938
29457
|
}
|
|
28939
29458
|
return resolveSafePathUnderCwd(cwd, displayPath);
|
|
28940
29459
|
}
|
|
@@ -28943,7 +29462,7 @@ function readGitHeadBlob(cwd, displayPath) {
|
|
|
28943
29462
|
const gitRoot = getGitRepoRootSync(cwd);
|
|
28944
29463
|
const execCwd = gitRoot ?? cwd;
|
|
28945
29464
|
try {
|
|
28946
|
-
return
|
|
29465
|
+
return execFileSync3("git", ["show", `HEAD:${displayPath}`], {
|
|
28947
29466
|
cwd: execCwd,
|
|
28948
29467
|
encoding: "utf8",
|
|
28949
29468
|
maxBuffer: 50 * 1024 * 1024
|
|
@@ -28959,7 +29478,7 @@ function gitHeadPathObjectType(cwd, displayPath) {
|
|
|
28959
29478
|
const gitRoot = getGitRepoRootSync(cwd);
|
|
28960
29479
|
if (!gitRoot) return null;
|
|
28961
29480
|
try {
|
|
28962
|
-
return
|
|
29481
|
+
return execFileSync4("git", ["cat-file", "-t", `HEAD:${displayPath}`], {
|
|
28963
29482
|
cwd: gitRoot,
|
|
28964
29483
|
encoding: "utf8"
|
|
28965
29484
|
}).trim();
|
|
@@ -29050,7 +29569,7 @@ function createBridgeOnRequest(opts) {
|
|
|
29050
29569
|
}
|
|
29051
29570
|
|
|
29052
29571
|
// src/agents/acp/hooks/extract-acp-file-diffs-from-update/paths-and-text.ts
|
|
29053
|
-
import { fileURLToPath } from "node:url";
|
|
29572
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
29054
29573
|
function readOptionalTextField(v) {
|
|
29055
29574
|
if (v === null || v === void 0) return "";
|
|
29056
29575
|
if (typeof v === "string") return v;
|
|
@@ -29060,7 +29579,7 @@ function normalizePathField(raw) {
|
|
|
29060
29579
|
const t = raw.trim();
|
|
29061
29580
|
if (t.startsWith("file://")) {
|
|
29062
29581
|
try {
|
|
29063
|
-
return
|
|
29582
|
+
return fileURLToPath2(t);
|
|
29064
29583
|
} catch {
|
|
29065
29584
|
return t;
|
|
29066
29585
|
}
|
|
@@ -29502,10 +30021,10 @@ function buildAcpSessionBridgeHooks(opts) {
|
|
|
29502
30021
|
// src/agents/acp/ensure-acp-client.ts
|
|
29503
30022
|
async function ensureAcpClient(options) {
|
|
29504
30023
|
const { state, preferredAgentType, mode, cwd, routing, sendSessionUpdate, sendRequest, log: log2 } = options;
|
|
29505
|
-
const targetCwd =
|
|
30024
|
+
const targetCwd = path10.resolve(
|
|
29506
30025
|
cwd != null && String(cwd).trim() !== "" ? String(cwd).trim() : getBridgeWorkspaceDirectory()
|
|
29507
30026
|
);
|
|
29508
|
-
if (state.acpHandle && state.lastAcpCwd != null &&
|
|
30027
|
+
if (state.acpHandle && state.lastAcpCwd != null && path10.resolve(state.lastAcpCwd) !== path10.resolve(targetCwd)) {
|
|
29509
30028
|
try {
|
|
29510
30029
|
state.acpHandle.disconnect();
|
|
29511
30030
|
} catch {
|
|
@@ -29537,7 +30056,7 @@ async function ensureAcpClient(options) {
|
|
|
29537
30056
|
if (!state.acpStartPromise) {
|
|
29538
30057
|
let statOk = false;
|
|
29539
30058
|
try {
|
|
29540
|
-
const st =
|
|
30059
|
+
const st = fs9.statSync(targetCwd);
|
|
29541
30060
|
statOk = st.isDirectory();
|
|
29542
30061
|
if (!statOk) {
|
|
29543
30062
|
state.lastAcpStartError = `Agent cwd is not a directory: ${targetCwd}`;
|
|
@@ -29733,12 +30252,12 @@ async function createAcpManager(options) {
|
|
|
29733
30252
|
}
|
|
29734
30253
|
|
|
29735
30254
|
// src/worktrees/session-worktree-manager.ts
|
|
29736
|
-
import * as
|
|
29737
|
-
import
|
|
30255
|
+
import * as path16 from "node:path";
|
|
30256
|
+
import os4 from "node:os";
|
|
29738
30257
|
|
|
29739
30258
|
// src/worktrees/prepare-new-session-worktrees.ts
|
|
29740
|
-
import * as
|
|
29741
|
-
import * as
|
|
30259
|
+
import * as fs11 from "node:fs";
|
|
30260
|
+
import * as path12 from "node:path";
|
|
29742
30261
|
|
|
29743
30262
|
// src/git/worktree-add.ts
|
|
29744
30263
|
async function gitWorktreeAddBranch(mainRepoPath, worktreePath, branch) {
|
|
@@ -29747,12 +30266,12 @@ async function gitWorktreeAddBranch(mainRepoPath, worktreePath, branch) {
|
|
|
29747
30266
|
}
|
|
29748
30267
|
|
|
29749
30268
|
// src/worktrees/worktree-layout-file.ts
|
|
29750
|
-
import * as
|
|
29751
|
-
import * as
|
|
29752
|
-
import
|
|
30269
|
+
import * as fs10 from "node:fs";
|
|
30270
|
+
import * as path11 from "node:path";
|
|
30271
|
+
import os3 from "node:os";
|
|
29753
30272
|
var LAYOUT_FILENAME = "worktree-launcher-layout.json";
|
|
29754
30273
|
function defaultWorktreeLayoutPath() {
|
|
29755
|
-
return
|
|
30274
|
+
return path11.join(os3.homedir(), ".buildautomaton", LAYOUT_FILENAME);
|
|
29756
30275
|
}
|
|
29757
30276
|
function normalizeLoadedLayout(raw) {
|
|
29758
30277
|
if (raw && typeof raw === "object" && "launcherCwds" in raw) {
|
|
@@ -29764,8 +30283,8 @@ function normalizeLoadedLayout(raw) {
|
|
|
29764
30283
|
function loadWorktreeLayout() {
|
|
29765
30284
|
try {
|
|
29766
30285
|
const p = defaultWorktreeLayoutPath();
|
|
29767
|
-
if (!
|
|
29768
|
-
const raw = JSON.parse(
|
|
30286
|
+
if (!fs10.existsSync(p)) return { launcherCwds: [] };
|
|
30287
|
+
const raw = JSON.parse(fs10.readFileSync(p, "utf8"));
|
|
29769
30288
|
return normalizeLoadedLayout(raw);
|
|
29770
30289
|
} catch {
|
|
29771
30290
|
return { launcherCwds: [] };
|
|
@@ -29773,18 +30292,18 @@ function loadWorktreeLayout() {
|
|
|
29773
30292
|
}
|
|
29774
30293
|
function saveWorktreeLayout(layout) {
|
|
29775
30294
|
try {
|
|
29776
|
-
const dir =
|
|
29777
|
-
|
|
29778
|
-
|
|
30295
|
+
const dir = path11.dirname(defaultWorktreeLayoutPath());
|
|
30296
|
+
fs10.mkdirSync(dir, { recursive: true });
|
|
30297
|
+
fs10.writeFileSync(defaultWorktreeLayoutPath(), JSON.stringify(layout, null, 2), "utf8");
|
|
29779
30298
|
} catch {
|
|
29780
30299
|
}
|
|
29781
30300
|
}
|
|
29782
30301
|
function baseNameSafe(abs) {
|
|
29783
|
-
return
|
|
30302
|
+
return path11.basename(abs).replace(/[^a-zA-Z0-9._-]+/g, "-") || "cwd";
|
|
29784
30303
|
}
|
|
29785
30304
|
function allocateDirNameForLauncherCwd(layout, launcherCwdAbs) {
|
|
29786
|
-
const norm =
|
|
29787
|
-
const existing = layout.launcherCwds.find((e) =>
|
|
30305
|
+
const norm = path11.resolve(launcherCwdAbs);
|
|
30306
|
+
const existing = layout.launcherCwds.find((e) => path11.resolve(e.absolutePath) === norm);
|
|
29788
30307
|
if (existing) return existing.dirName;
|
|
29789
30308
|
const base = baseNameSafe(norm);
|
|
29790
30309
|
const used = new Set(layout.launcherCwds.map((e) => e.dirName));
|
|
@@ -29802,9 +30321,9 @@ function allocateDirNameForLauncherCwd(layout, launcherCwdAbs) {
|
|
|
29802
30321
|
// src/worktrees/prepare-new-session-worktrees.ts
|
|
29803
30322
|
async function prepareNewSessionWorktrees(options) {
|
|
29804
30323
|
const { rootAbs, launcherCwd, sessionId, layout, log: log2 } = options;
|
|
29805
|
-
const launcherResolved =
|
|
30324
|
+
const launcherResolved = path12.resolve(launcherCwd);
|
|
29806
30325
|
const cwdKey = allocateDirNameForLauncherCwd(layout, launcherResolved);
|
|
29807
|
-
const agentMirrorRoot =
|
|
30326
|
+
const agentMirrorRoot = path12.join(rootAbs, cwdKey);
|
|
29808
30327
|
const repos = await discoverGitReposUnderRoot(launcherResolved);
|
|
29809
30328
|
if (repos.length === 0) {
|
|
29810
30329
|
log2("[worktrees] No Git repositories under launcher working directory; skipping worktree creation.");
|
|
@@ -29812,13 +30331,13 @@ async function prepareNewSessionWorktrees(options) {
|
|
|
29812
30331
|
}
|
|
29813
30332
|
const branch = `session-${sessionId}`;
|
|
29814
30333
|
const worktreePaths = [];
|
|
29815
|
-
|
|
30334
|
+
fs11.mkdirSync(agentMirrorRoot, { recursive: true });
|
|
29816
30335
|
for (const repo of repos) {
|
|
29817
|
-
let rel =
|
|
29818
|
-
if (rel.startsWith("..") ||
|
|
30336
|
+
let rel = path12.relative(launcherResolved, repo.absolutePath);
|
|
30337
|
+
if (rel.startsWith("..") || path12.isAbsolute(rel)) continue;
|
|
29819
30338
|
const relNorm = rel === "" ? "." : rel;
|
|
29820
|
-
const wtPath =
|
|
29821
|
-
|
|
30339
|
+
const wtPath = path12.join(agentMirrorRoot, relNorm, sessionId);
|
|
30340
|
+
fs11.mkdirSync(path12.dirname(wtPath), { recursive: true });
|
|
29822
30341
|
try {
|
|
29823
30342
|
await gitWorktreeAddBranch(repo.absolutePath, wtPath, branch);
|
|
29824
30343
|
log2(`[worktrees] Added worktree ${wtPath} (branch ${branch}).`);
|
|
@@ -29855,23 +30374,23 @@ async function renameSessionWorktreeBranches(paths, newBranch, log2) {
|
|
|
29855
30374
|
}
|
|
29856
30375
|
|
|
29857
30376
|
// src/worktrees/remove-session-worktrees.ts
|
|
29858
|
-
import * as
|
|
30377
|
+
import * as fs14 from "node:fs";
|
|
29859
30378
|
|
|
29860
30379
|
// src/git/worktree-remove.ts
|
|
29861
|
-
import * as
|
|
30380
|
+
import * as fs13 from "node:fs";
|
|
29862
30381
|
|
|
29863
30382
|
// src/git/resolve-main-repo-from-git-file.ts
|
|
29864
|
-
import * as
|
|
29865
|
-
import * as
|
|
30383
|
+
import * as fs12 from "node:fs";
|
|
30384
|
+
import * as path13 from "node:path";
|
|
29866
30385
|
function resolveMainRepoFromWorktreeGitFile(wt) {
|
|
29867
|
-
const gitDirFile =
|
|
29868
|
-
if (!
|
|
29869
|
-
const first2 =
|
|
30386
|
+
const gitDirFile = path13.join(wt, ".git");
|
|
30387
|
+
if (!fs12.existsSync(gitDirFile) || !fs12.statSync(gitDirFile).isFile()) return "";
|
|
30388
|
+
const first2 = fs12.readFileSync(gitDirFile, "utf8").trim();
|
|
29870
30389
|
const m = first2.match(/^gitdir:\s*(.+)$/im);
|
|
29871
30390
|
if (!m) return "";
|
|
29872
|
-
const gitWorktreePath =
|
|
29873
|
-
const gitDir =
|
|
29874
|
-
return
|
|
30391
|
+
const gitWorktreePath = path13.resolve(wt, m[1].trim());
|
|
30392
|
+
const gitDir = path13.dirname(path13.dirname(gitWorktreePath));
|
|
30393
|
+
return path13.dirname(gitDir);
|
|
29875
30394
|
}
|
|
29876
30395
|
|
|
29877
30396
|
// src/git/worktree-remove.ts
|
|
@@ -29880,7 +30399,7 @@ async function gitWorktreeRemoveForce(worktreePath) {
|
|
|
29880
30399
|
if (mainRepo) {
|
|
29881
30400
|
await simpleGit(mainRepo).raw(["worktree", "remove", "--force", worktreePath]);
|
|
29882
30401
|
} else {
|
|
29883
|
-
|
|
30402
|
+
fs13.rmSync(worktreePath, { recursive: true, force: true });
|
|
29884
30403
|
}
|
|
29885
30404
|
}
|
|
29886
30405
|
|
|
@@ -29893,7 +30412,7 @@ async function removeSessionWorktrees(paths, log2) {
|
|
|
29893
30412
|
} catch (e) {
|
|
29894
30413
|
log2(`[worktrees] Remove failed for ${wt}: ${e instanceof Error ? e.message : String(e)}`);
|
|
29895
30414
|
try {
|
|
29896
|
-
|
|
30415
|
+
fs14.rmSync(wt, { recursive: true, force: true });
|
|
29897
30416
|
} catch {
|
|
29898
30417
|
}
|
|
29899
30418
|
}
|
|
@@ -30113,7 +30632,7 @@ function formatRemoteDisplayLabel(remoteUrl) {
|
|
|
30113
30632
|
}
|
|
30114
30633
|
|
|
30115
30634
|
// src/git/working-directory/changes/get-working-tree-change-repo-details.ts
|
|
30116
|
-
import * as
|
|
30635
|
+
import * as path15 from "node:path";
|
|
30117
30636
|
|
|
30118
30637
|
// src/git/working-directory/changes/parse-git-status.ts
|
|
30119
30638
|
function parseNameStatusLines(lines) {
|
|
@@ -30233,8 +30752,8 @@ async function listChangedFilesForCommit(repoGitCwd, repoRelPath, commitSha) {
|
|
|
30233
30752
|
}
|
|
30234
30753
|
|
|
30235
30754
|
// src/git/working-directory/changes/list-changed-files-for-repo.ts
|
|
30236
|
-
import * as
|
|
30237
|
-
import * as
|
|
30755
|
+
import * as fs16 from "node:fs";
|
|
30756
|
+
import * as path14 from "node:path";
|
|
30238
30757
|
|
|
30239
30758
|
// src/git/working-directory/changes/count-lines.ts
|
|
30240
30759
|
import { createReadStream } from "node:fs";
|
|
@@ -30258,7 +30777,7 @@ async function countTextFileLines(absFile) {
|
|
|
30258
30777
|
}
|
|
30259
30778
|
|
|
30260
30779
|
// src/git/working-directory/changes/hydrate-patch.ts
|
|
30261
|
-
import * as
|
|
30780
|
+
import * as fs15 from "node:fs";
|
|
30262
30781
|
var UNIFIED_HUNK_HEADER_RE = /^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/;
|
|
30263
30782
|
var MAX_HYDRATE_LINES_PER_GAP = 8e3;
|
|
30264
30783
|
var MAX_HYDRATE_LINES_PER_FILE = 8e4;
|
|
@@ -30273,7 +30792,7 @@ async function readGitBlobLines(repoCwd, pathInRepo) {
|
|
|
30273
30792
|
}
|
|
30274
30793
|
async function readWorktreeFileLines(abs) {
|
|
30275
30794
|
try {
|
|
30276
|
-
const raw = await
|
|
30795
|
+
const raw = await fs15.promises.readFile(abs, "utf8");
|
|
30277
30796
|
return raw.split(/\r?\n/);
|
|
30278
30797
|
} catch {
|
|
30279
30798
|
return null;
|
|
@@ -30408,7 +30927,7 @@ async function listChangedFilesForRepo(repoGitCwd, repoRelPath) {
|
|
|
30408
30927
|
const rows = [];
|
|
30409
30928
|
for (const pathInRepo of paths) {
|
|
30410
30929
|
const relLauncher = posixJoinDirFile(repoRelPath, pathInRepo.replace(/\\/g, "/"));
|
|
30411
|
-
const abs =
|
|
30930
|
+
const abs = path14.join(repoGitCwd, pathInRepo);
|
|
30412
30931
|
const nums = numByPath.get(pathInRepo);
|
|
30413
30932
|
let additions = nums?.additions ?? 0;
|
|
30414
30933
|
let deletions = nums?.deletions ?? 0;
|
|
@@ -30421,7 +30940,7 @@ async function listChangedFilesForRepo(repoGitCwd, repoRelPath) {
|
|
|
30421
30940
|
deletions = fromGit.deletions;
|
|
30422
30941
|
} else {
|
|
30423
30942
|
try {
|
|
30424
|
-
const st = await
|
|
30943
|
+
const st = await fs16.promises.stat(abs);
|
|
30425
30944
|
if (st.isFile()) additions = await countTextFileLines(abs);
|
|
30426
30945
|
else additions = 0;
|
|
30427
30946
|
} catch {
|
|
@@ -30447,7 +30966,7 @@ async function listChangedFilesForRepo(repoGitCwd, repoRelPath) {
|
|
|
30447
30966
|
} else {
|
|
30448
30967
|
pathInRepo = row.pathRelLauncher;
|
|
30449
30968
|
}
|
|
30450
|
-
const absFile =
|
|
30969
|
+
const absFile = path14.join(repoGitCwd, pathInRepo);
|
|
30451
30970
|
let patch = await unifiedDiffForFile(repoGitCwd, pathInRepo, row.change);
|
|
30452
30971
|
if (patch) {
|
|
30453
30972
|
patch = await hydrateUnifiedPatchWithFileContext(patch, absFile, repoGitCwd, pathInRepo, row.change);
|
|
@@ -30463,8 +30982,8 @@ function normRepoRel(p) {
|
|
|
30463
30982
|
return x === "" ? "." : x;
|
|
30464
30983
|
}
|
|
30465
30984
|
async function getWorkingTreeChangeRepoDetails(options) {
|
|
30466
|
-
const launcher =
|
|
30467
|
-
const mirror = options.agentMirrorRootAbs ?
|
|
30985
|
+
const launcher = path15.resolve(getBridgeWorkspaceDirectory());
|
|
30986
|
+
const mirror = options.agentMirrorRootAbs ? path15.resolve(options.agentMirrorRootAbs) : null;
|
|
30468
30987
|
const out = [];
|
|
30469
30988
|
const filter = options.repoFilterRelPath != null ? normRepoRel(options.repoFilterRelPath) : null;
|
|
30470
30989
|
const basisInput = options.basis ?? { kind: "working" };
|
|
@@ -30476,7 +30995,7 @@ async function getWorkingTreeChangeRepoDetails(options) {
|
|
|
30476
30995
|
}
|
|
30477
30996
|
const basis = filter == null && basisInput.kind === "commit" ? { kind: "working" } : basisInput;
|
|
30478
30997
|
for (const target of options.commitTargetAbsDirs) {
|
|
30479
|
-
const t =
|
|
30998
|
+
const t = path15.resolve(target);
|
|
30480
30999
|
if (!await isGitRepoDirectory(t)) continue;
|
|
30481
31000
|
const g = simpleGit(t);
|
|
30482
31001
|
let branch = "HEAD";
|
|
@@ -30489,7 +31008,7 @@ async function getWorkingTreeChangeRepoDetails(options) {
|
|
|
30489
31008
|
const remoteDisplay = formatRemoteDisplayLabel(remoteUrl);
|
|
30490
31009
|
let repoRelPath;
|
|
30491
31010
|
if (mirror) {
|
|
30492
|
-
const relNorm =
|
|
31011
|
+
const relNorm = path15.relative(mirror, path15.dirname(t));
|
|
30493
31012
|
repoRelPath = relNorm === "" ? "." : relNorm.replace(/\\/g, "/");
|
|
30494
31013
|
} else {
|
|
30495
31014
|
let top = t;
|
|
@@ -30498,8 +31017,8 @@ async function getWorkingTreeChangeRepoDetails(options) {
|
|
|
30498
31017
|
} catch {
|
|
30499
31018
|
top = t;
|
|
30500
31019
|
}
|
|
30501
|
-
const rel =
|
|
30502
|
-
repoRelPath = rel.startsWith("..") ?
|
|
31020
|
+
const rel = path15.relative(launcher, path15.resolve(top)).replace(/\\/g, "/") || ".";
|
|
31021
|
+
repoRelPath = rel.startsWith("..") ? path15.basename(path15.resolve(top)) : rel;
|
|
30503
31022
|
}
|
|
30504
31023
|
const norm = normRepoRel(repoRelPath === "" ? "." : repoRelPath);
|
|
30505
31024
|
if (filter && norm !== filter) continue;
|
|
@@ -30591,7 +31110,7 @@ var SessionWorktreeManager = class {
|
|
|
30591
31110
|
}
|
|
30592
31111
|
if (!opts.isNewSession) {
|
|
30593
31112
|
const agentCwd = this.sessionAgentCwd.get(sessionId);
|
|
30594
|
-
if (agentCwd) return
|
|
31113
|
+
if (agentCwd) return path16.resolve(agentCwd);
|
|
30595
31114
|
return void 0;
|
|
30596
31115
|
}
|
|
30597
31116
|
const prep = await prepareNewSessionWorktrees({
|
|
@@ -30604,7 +31123,7 @@ var SessionWorktreeManager = class {
|
|
|
30604
31123
|
if (!prep) return void 0;
|
|
30605
31124
|
this.sessionPaths.set(sessionId, prep.worktreePaths);
|
|
30606
31125
|
this.sessionAgentCwd.set(sessionId, prep.agentCwd);
|
|
30607
|
-
return
|
|
31126
|
+
return path16.resolve(prep.agentCwd);
|
|
30608
31127
|
}
|
|
30609
31128
|
async renameSessionBranch(sessionId, newBranch) {
|
|
30610
31129
|
const paths = this.sessionPaths.get(sessionId);
|
|
@@ -30625,7 +31144,7 @@ var SessionWorktreeManager = class {
|
|
|
30625
31144
|
getAgentCwdForSession(sessionId) {
|
|
30626
31145
|
if (!sessionId) return null;
|
|
30627
31146
|
const c = this.sessionAgentCwd.get(sessionId);
|
|
30628
|
-
return c ?
|
|
31147
|
+
return c ? path16.resolve(c) : null;
|
|
30629
31148
|
}
|
|
30630
31149
|
async removeSessionWorktrees(sessionId) {
|
|
30631
31150
|
const paths = this.sessionPaths.get(sessionId);
|
|
@@ -30673,15 +31192,15 @@ var SessionWorktreeManager = class {
|
|
|
30673
31192
|
}
|
|
30674
31193
|
};
|
|
30675
31194
|
function defaultWorktreesRootAbs() {
|
|
30676
|
-
return
|
|
31195
|
+
return path16.join(os4.homedir(), ".buildautomaton", "worktrees");
|
|
30677
31196
|
}
|
|
30678
31197
|
|
|
30679
31198
|
// src/files/watch-file-index.ts
|
|
30680
31199
|
import { watch } from "node:fs";
|
|
30681
|
-
import
|
|
31200
|
+
import path23 from "node:path";
|
|
30682
31201
|
|
|
30683
31202
|
// src/files/index/build-file-index.ts
|
|
30684
|
-
import
|
|
31203
|
+
import path20 from "node:path";
|
|
30685
31204
|
|
|
30686
31205
|
// src/runtime/yield-to-event-loop.ts
|
|
30687
31206
|
function yieldToEventLoop() {
|
|
@@ -30689,14 +31208,14 @@ function yieldToEventLoop() {
|
|
|
30689
31208
|
}
|
|
30690
31209
|
|
|
30691
31210
|
// src/files/index/walk-workspace-tree.ts
|
|
30692
|
-
import
|
|
30693
|
-
import
|
|
31211
|
+
import fs17 from "node:fs";
|
|
31212
|
+
import path18 from "node:path";
|
|
30694
31213
|
|
|
30695
31214
|
// src/files/index/constants.ts
|
|
30696
|
-
import
|
|
30697
|
-
import
|
|
31215
|
+
import path17 from "node:path";
|
|
31216
|
+
import os5 from "node:os";
|
|
30698
31217
|
var INDEX_WORK_YIELD_EVERY = 256;
|
|
30699
|
-
var INDEX_DIR =
|
|
31218
|
+
var INDEX_DIR = path17.join(os5.homedir(), ".buildautomaton");
|
|
30700
31219
|
var INDEX_HASH_LEN = 16;
|
|
30701
31220
|
var INDEX_VERSION = 2;
|
|
30702
31221
|
var INDEX_LOG_PREFIX = "[file-index]";
|
|
@@ -30705,20 +31224,20 @@ var INDEX_LOG_PREFIX = "[file-index]";
|
|
|
30705
31224
|
function walkWorkspaceTreeSync(dir, baseDir, out) {
|
|
30706
31225
|
let names;
|
|
30707
31226
|
try {
|
|
30708
|
-
names =
|
|
31227
|
+
names = fs17.readdirSync(dir);
|
|
30709
31228
|
} catch {
|
|
30710
31229
|
return;
|
|
30711
31230
|
}
|
|
30712
31231
|
for (const name of names) {
|
|
30713
31232
|
if (name.startsWith(".")) continue;
|
|
30714
|
-
const full =
|
|
31233
|
+
const full = path18.join(dir, name);
|
|
30715
31234
|
let stat2;
|
|
30716
31235
|
try {
|
|
30717
|
-
stat2 =
|
|
31236
|
+
stat2 = fs17.statSync(full);
|
|
30718
31237
|
} catch {
|
|
30719
31238
|
continue;
|
|
30720
31239
|
}
|
|
30721
|
-
const relative5 =
|
|
31240
|
+
const relative5 = path18.relative(baseDir, full).replace(/\\/g, "/");
|
|
30722
31241
|
if (stat2.isDirectory()) {
|
|
30723
31242
|
walkWorkspaceTreeSync(full, baseDir, out);
|
|
30724
31243
|
} else if (stat2.isFile()) {
|
|
@@ -30729,7 +31248,7 @@ function walkWorkspaceTreeSync(dir, baseDir, out) {
|
|
|
30729
31248
|
async function walkWorkspaceTreeAsync(dir, baseDir, out, state) {
|
|
30730
31249
|
let names;
|
|
30731
31250
|
try {
|
|
30732
|
-
names = await
|
|
31251
|
+
names = await fs17.promises.readdir(dir);
|
|
30733
31252
|
} catch {
|
|
30734
31253
|
return;
|
|
30735
31254
|
}
|
|
@@ -30739,14 +31258,14 @@ async function walkWorkspaceTreeAsync(dir, baseDir, out, state) {
|
|
|
30739
31258
|
await yieldToEventLoop();
|
|
30740
31259
|
}
|
|
30741
31260
|
state.n++;
|
|
30742
|
-
const full =
|
|
31261
|
+
const full = path18.join(dir, name);
|
|
30743
31262
|
let stat2;
|
|
30744
31263
|
try {
|
|
30745
|
-
stat2 = await
|
|
31264
|
+
stat2 = await fs17.promises.stat(full);
|
|
30746
31265
|
} catch {
|
|
30747
31266
|
continue;
|
|
30748
31267
|
}
|
|
30749
|
-
const relative5 =
|
|
31268
|
+
const relative5 = path18.relative(baseDir, full).replace(/\\/g, "/");
|
|
30750
31269
|
if (stat2.isDirectory()) {
|
|
30751
31270
|
await walkWorkspaceTreeAsync(full, baseDir, out, state);
|
|
30752
31271
|
} else if (stat2.isFile()) {
|
|
@@ -30827,22 +31346,22 @@ async function buildTrigramMapForPathsAsync(paths) {
|
|
|
30827
31346
|
}
|
|
30828
31347
|
|
|
30829
31348
|
// src/files/index/write-index-file.ts
|
|
30830
|
-
import
|
|
31349
|
+
import fs18 from "node:fs";
|
|
30831
31350
|
|
|
30832
31351
|
// src/files/index/paths.ts
|
|
30833
|
-
import
|
|
31352
|
+
import path19 from "node:path";
|
|
30834
31353
|
import crypto2 from "node:crypto";
|
|
30835
31354
|
function getIndexPathForCwd(resolvedCwd) {
|
|
30836
31355
|
const hash = crypto2.createHash("sha256").update(resolvedCwd).digest("hex").slice(0, INDEX_HASH_LEN);
|
|
30837
|
-
return
|
|
31356
|
+
return path19.join(INDEX_DIR, `.file-index-${hash}.json`);
|
|
30838
31357
|
}
|
|
30839
31358
|
|
|
30840
31359
|
// src/files/index/write-index-file.ts
|
|
30841
31360
|
function writeIndexFileSync(resolvedCwd, data) {
|
|
30842
31361
|
const indexPath = getIndexPathForCwd(resolvedCwd);
|
|
30843
31362
|
try {
|
|
30844
|
-
if (!
|
|
30845
|
-
|
|
31363
|
+
if (!fs18.existsSync(INDEX_DIR)) fs18.mkdirSync(INDEX_DIR, { recursive: true });
|
|
31364
|
+
fs18.writeFileSync(indexPath, JSON.stringify(data), "utf8");
|
|
30846
31365
|
} catch (e) {
|
|
30847
31366
|
console.error(`${INDEX_LOG_PREFIX} Failed to write index:`, e);
|
|
30848
31367
|
}
|
|
@@ -30850,8 +31369,8 @@ function writeIndexFileSync(resolvedCwd, data) {
|
|
|
30850
31369
|
async function writeIndexFileAsync(resolvedCwd, data) {
|
|
30851
31370
|
const indexPath = getIndexPathForCwd(resolvedCwd);
|
|
30852
31371
|
try {
|
|
30853
|
-
await
|
|
30854
|
-
await
|
|
31372
|
+
await fs18.promises.mkdir(INDEX_DIR, { recursive: true });
|
|
31373
|
+
await fs18.promises.writeFile(indexPath, JSON.stringify(data), "utf8");
|
|
30855
31374
|
} catch (e) {
|
|
30856
31375
|
console.error(`${INDEX_LOG_PREFIX} Failed to write index:`, e);
|
|
30857
31376
|
}
|
|
@@ -30865,7 +31384,7 @@ function sortPaths(paths) {
|
|
|
30865
31384
|
paths.sort((a, b) => a.localeCompare(b, void 0, { sensitivity: "base" }));
|
|
30866
31385
|
}
|
|
30867
31386
|
function buildFileIndex(cwd) {
|
|
30868
|
-
const resolved =
|
|
31387
|
+
const resolved = path20.resolve(cwd);
|
|
30869
31388
|
const paths = [];
|
|
30870
31389
|
walkWorkspaceTreeSync(resolved, resolved, paths);
|
|
30871
31390
|
sortPaths(paths);
|
|
@@ -30875,7 +31394,7 @@ function buildFileIndex(cwd) {
|
|
|
30875
31394
|
return data;
|
|
30876
31395
|
}
|
|
30877
31396
|
async function buildFileIndexAsync(cwd) {
|
|
30878
|
-
const resolved =
|
|
31397
|
+
const resolved = path20.resolve(cwd);
|
|
30879
31398
|
const paths = [];
|
|
30880
31399
|
await walkWorkspaceTreeAsync(resolved, resolved, paths, createWalkYieldState());
|
|
30881
31400
|
await yieldToEventLoop();
|
|
@@ -30887,13 +31406,13 @@ async function buildFileIndexAsync(cwd) {
|
|
|
30887
31406
|
}
|
|
30888
31407
|
|
|
30889
31408
|
// src/files/index/load-file-index.ts
|
|
30890
|
-
import
|
|
30891
|
-
import
|
|
31409
|
+
import fs19 from "node:fs";
|
|
31410
|
+
import path21 from "node:path";
|
|
30892
31411
|
function loadFileIndex(cwd) {
|
|
30893
|
-
const resolved =
|
|
31412
|
+
const resolved = path21.resolve(cwd);
|
|
30894
31413
|
const indexPath = getIndexPathForCwd(resolved);
|
|
30895
31414
|
try {
|
|
30896
|
-
const raw =
|
|
31415
|
+
const raw = fs19.readFileSync(indexPath, "utf8");
|
|
30897
31416
|
const parsed = JSON.parse(raw);
|
|
30898
31417
|
if (parsed !== null && typeof parsed === "object" && Array.isArray(parsed.paths)) {
|
|
30899
31418
|
const obj = parsed;
|
|
@@ -30912,9 +31431,9 @@ function loadFileIndex(cwd) {
|
|
|
30912
31431
|
}
|
|
30913
31432
|
|
|
30914
31433
|
// src/files/index/ensure-file-index.ts
|
|
30915
|
-
import
|
|
31434
|
+
import path22 from "node:path";
|
|
30916
31435
|
async function ensureFileIndexAsync(cwd) {
|
|
30917
|
-
const resolved =
|
|
31436
|
+
const resolved = path22.resolve(cwd);
|
|
30918
31437
|
const cached2 = loadFileIndex(resolved);
|
|
30919
31438
|
if (cached2 !== null) return { data: cached2, fromCache: true };
|
|
30920
31439
|
const data = await buildFileIndexAsync(resolved);
|
|
@@ -30997,7 +31516,7 @@ function createFsWatcher(resolved, schedule) {
|
|
|
30997
31516
|
}
|
|
30998
31517
|
}
|
|
30999
31518
|
function startFileIndexWatcher(cwd = getBridgeWorkspaceDirectory()) {
|
|
31000
|
-
const resolved =
|
|
31519
|
+
const resolved = path23.resolve(cwd);
|
|
31001
31520
|
void buildFileIndexAsync(resolved).catch((e) => {
|
|
31002
31521
|
console.error("[file-index] Initial index build failed:", e);
|
|
31003
31522
|
});
|
|
@@ -31025,7 +31544,7 @@ function startFileIndexWatcher(cwd = getBridgeWorkspaceDirectory()) {
|
|
|
31025
31544
|
}
|
|
31026
31545
|
|
|
31027
31546
|
// src/dev-servers/manager/dev-server-manager.ts
|
|
31028
|
-
import { rm } from "node:fs/promises";
|
|
31547
|
+
import { rm as rm2 } from "node:fs/promises";
|
|
31029
31548
|
|
|
31030
31549
|
// src/dev-servers/process/send-server-status.ts
|
|
31031
31550
|
function sendDevServerStatus(getWs, serverId, status, options) {
|
|
@@ -31066,7 +31585,7 @@ function forceKillChild(proc, log2, shortId, graceMs) {
|
|
|
31066
31585
|
}
|
|
31067
31586
|
|
|
31068
31587
|
// src/dev-servers/process/wire-dev-server-child-process.ts
|
|
31069
|
-
import
|
|
31588
|
+
import fs20 from "node:fs";
|
|
31070
31589
|
|
|
31071
31590
|
// src/dev-servers/manager/forward-pipe.ts
|
|
31072
31591
|
function forwardChildPipe(childReadable, terminal, onData) {
|
|
@@ -31102,7 +31621,7 @@ function wireDevServerChildProcess(d) {
|
|
|
31102
31621
|
d.setPollInterval(void 0);
|
|
31103
31622
|
return;
|
|
31104
31623
|
}
|
|
31105
|
-
|
|
31624
|
+
fs20.readFile(d.mergedLogPath, (err, buf) => {
|
|
31106
31625
|
if (err || (d.getSpawnGeneration() ?? 0) !== d.scheduledGen) return;
|
|
31107
31626
|
if (buf.length <= d.mergedReadPos.value) return;
|
|
31108
31627
|
const chunk = Buffer.from(buf.subarray(d.mergedReadPos.value));
|
|
@@ -31140,7 +31659,7 @@ ${errTail}` : ""}`);
|
|
|
31140
31659
|
d.sendStatus(code === 0 || code == null ? "stopped" : "error", detail, tails);
|
|
31141
31660
|
};
|
|
31142
31661
|
if (mergedPath) {
|
|
31143
|
-
|
|
31662
|
+
fs20.readFile(mergedPath, (err, buf) => {
|
|
31144
31663
|
if (!err && buf.length > d.mergedReadPos.value) {
|
|
31145
31664
|
const chunk = Buffer.from(buf.subarray(d.mergedReadPos.value));
|
|
31146
31665
|
if (chunk.length > 0) {
|
|
@@ -31242,13 +31761,13 @@ function parseDevServerDefs(servers) {
|
|
|
31242
31761
|
}
|
|
31243
31762
|
|
|
31244
31763
|
// src/dev-servers/manager/shell-spawn/utils.ts
|
|
31245
|
-
import
|
|
31764
|
+
import fs21 from "node:fs";
|
|
31246
31765
|
function isSpawnEbadf(e) {
|
|
31247
31766
|
return typeof e === "object" && e !== null && "code" in e && e.code === "EBADF";
|
|
31248
31767
|
}
|
|
31249
31768
|
function rmDirQuiet(dir) {
|
|
31250
31769
|
try {
|
|
31251
|
-
|
|
31770
|
+
fs21.rmSync(dir, { recursive: true, force: true });
|
|
31252
31771
|
} catch {
|
|
31253
31772
|
}
|
|
31254
31773
|
}
|
|
@@ -31256,7 +31775,7 @@ var cachedDevNullReadFd;
|
|
|
31256
31775
|
function devNullReadFd() {
|
|
31257
31776
|
if (cachedDevNullReadFd === void 0) {
|
|
31258
31777
|
const devPath = process.platform === "win32" ? "nul" : "/dev/null";
|
|
31259
|
-
cachedDevNullReadFd =
|
|
31778
|
+
cachedDevNullReadFd = fs21.openSync(devPath, "r");
|
|
31260
31779
|
}
|
|
31261
31780
|
return cachedDevNullReadFd;
|
|
31262
31781
|
}
|
|
@@ -31330,15 +31849,15 @@ function trySpawnShellTruePiped(command, env, cwd, devNullFd, signal) {
|
|
|
31330
31849
|
|
|
31331
31850
|
// src/dev-servers/manager/shell-spawn/try-spawn-merged-log-file.ts
|
|
31332
31851
|
import { spawn as spawn7 } from "node:child_process";
|
|
31333
|
-
import
|
|
31852
|
+
import fs22 from "node:fs";
|
|
31334
31853
|
import { tmpdir } from "node:os";
|
|
31335
|
-
import
|
|
31854
|
+
import path24 from "node:path";
|
|
31336
31855
|
function trySpawnMergedLogFile(command, env, cwd, signal) {
|
|
31337
|
-
const tmpRoot =
|
|
31338
|
-
const logPath =
|
|
31856
|
+
const tmpRoot = fs22.mkdtempSync(path24.join(tmpdir(), "ba-devsrv-log-"));
|
|
31857
|
+
const logPath = path24.join(tmpRoot, "combined.log");
|
|
31339
31858
|
let logFd;
|
|
31340
31859
|
try {
|
|
31341
|
-
logFd =
|
|
31860
|
+
logFd = fs22.openSync(logPath, "a");
|
|
31342
31861
|
} catch {
|
|
31343
31862
|
rmDirQuiet(tmpRoot);
|
|
31344
31863
|
return null;
|
|
@@ -31357,7 +31876,7 @@ function trySpawnMergedLogFile(command, env, cwd, signal) {
|
|
|
31357
31876
|
} else {
|
|
31358
31877
|
proc = spawn7("/bin/sh", ["-c", command], { env, cwd, stdio, ...signal ? { signal } : {} });
|
|
31359
31878
|
}
|
|
31360
|
-
|
|
31879
|
+
fs22.closeSync(logFd);
|
|
31361
31880
|
return {
|
|
31362
31881
|
proc,
|
|
31363
31882
|
pipedStdoutStderr: true,
|
|
@@ -31366,7 +31885,7 @@ function trySpawnMergedLogFile(command, env, cwd, signal) {
|
|
|
31366
31885
|
};
|
|
31367
31886
|
} catch (e) {
|
|
31368
31887
|
try {
|
|
31369
|
-
|
|
31888
|
+
fs22.closeSync(logFd);
|
|
31370
31889
|
} catch {
|
|
31371
31890
|
}
|
|
31372
31891
|
rmDirQuiet(tmpRoot);
|
|
@@ -31377,22 +31896,22 @@ function trySpawnMergedLogFile(command, env, cwd, signal) {
|
|
|
31377
31896
|
|
|
31378
31897
|
// src/dev-servers/manager/shell-spawn/try-spawn-shell-script-log-redirect.ts
|
|
31379
31898
|
import { spawn as spawn8 } from "node:child_process";
|
|
31380
|
-
import
|
|
31899
|
+
import fs23 from "node:fs";
|
|
31381
31900
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
31382
|
-
import
|
|
31901
|
+
import path25 from "node:path";
|
|
31383
31902
|
function shSingleQuote(s) {
|
|
31384
31903
|
return `'${s.replace(/'/g, `'\\''`)}'`;
|
|
31385
31904
|
}
|
|
31386
31905
|
function trySpawnShellScriptLogRedirectUnix(command, env, cwd, signal) {
|
|
31387
|
-
const tmpRoot =
|
|
31388
|
-
const logPath =
|
|
31389
|
-
const innerPath =
|
|
31390
|
-
const runnerPath =
|
|
31906
|
+
const tmpRoot = fs23.mkdtempSync(path25.join(tmpdir2(), "ba-devsrv-sh-"));
|
|
31907
|
+
const logPath = path25.join(tmpRoot, "combined.log");
|
|
31908
|
+
const innerPath = path25.join(tmpRoot, "_cmd.sh");
|
|
31909
|
+
const runnerPath = path25.join(tmpRoot, "_run.sh");
|
|
31391
31910
|
try {
|
|
31392
|
-
|
|
31911
|
+
fs23.writeFileSync(innerPath, `#!/bin/sh
|
|
31393
31912
|
${command}
|
|
31394
31913
|
`);
|
|
31395
|
-
|
|
31914
|
+
fs23.writeFileSync(
|
|
31396
31915
|
runnerPath,
|
|
31397
31916
|
`#!/bin/sh
|
|
31398
31917
|
cd ${shSingleQuote(cwd)}
|
|
@@ -31418,13 +31937,13 @@ cd ${shSingleQuote(cwd)}
|
|
|
31418
31937
|
}
|
|
31419
31938
|
}
|
|
31420
31939
|
function trySpawnShellScriptLogRedirectWin(command, env, cwd, signal) {
|
|
31421
|
-
const tmpRoot =
|
|
31422
|
-
const logPath =
|
|
31423
|
-
const runnerPath =
|
|
31940
|
+
const tmpRoot = fs23.mkdtempSync(path25.join(tmpdir2(), "ba-devsrv-sh-"));
|
|
31941
|
+
const logPath = path25.join(tmpRoot, "combined.log");
|
|
31942
|
+
const runnerPath = path25.join(tmpRoot, "_run.bat");
|
|
31424
31943
|
const q = (p) => `"${p.replace(/"/g, '""')}"`;
|
|
31425
31944
|
const com = process.env.ComSpec || "cmd.exe";
|
|
31426
31945
|
try {
|
|
31427
|
-
|
|
31946
|
+
fs23.writeFileSync(
|
|
31428
31947
|
runnerPath,
|
|
31429
31948
|
`@ECHO OFF\r
|
|
31430
31949
|
CD /D ${q(cwd)}\r
|
|
@@ -31534,8 +32053,90 @@ var StreamTail = class {
|
|
|
31534
32053
|
}
|
|
31535
32054
|
};
|
|
31536
32055
|
|
|
31537
|
-
// src/dev-servers/manager/dev-server-
|
|
32056
|
+
// src/dev-servers/manager/dev-server-constants.ts
|
|
31538
32057
|
var BRIDGE_SHUTDOWN_GRACE_MS = 8e3;
|
|
32058
|
+
|
|
32059
|
+
// src/dev-servers/manager/dev-server-firehose-messages.ts
|
|
32060
|
+
function buildFirehoseSnapshotMessage(params) {
|
|
32061
|
+
const payload = {
|
|
32062
|
+
type: "log_snapshot",
|
|
32063
|
+
serverId: params.serverId,
|
|
32064
|
+
viewerId: params.viewerId,
|
|
32065
|
+
stdoutTail: params.tails.stdout,
|
|
32066
|
+
stderrTail: params.tails.stderr
|
|
32067
|
+
};
|
|
32068
|
+
return params.e2ee ? params.e2ee.encryptFields(payload, ["stdoutTail", "stderrTail"]) : payload;
|
|
32069
|
+
}
|
|
32070
|
+
function buildFirehoseLogChunkMessage(params) {
|
|
32071
|
+
const payload = {
|
|
32072
|
+
type: "log_chunk",
|
|
32073
|
+
serverId: params.serverId,
|
|
32074
|
+
stream: params.stream,
|
|
32075
|
+
text: params.text
|
|
32076
|
+
};
|
|
32077
|
+
return params.e2ee ? params.e2ee.encryptFields(payload, ["text"]) : payload;
|
|
32078
|
+
}
|
|
32079
|
+
|
|
32080
|
+
// src/dev-servers/manager/dev-server-firehose-sink.ts
|
|
32081
|
+
var DevServerFirehoseSink = class {
|
|
32082
|
+
constructor(options) {
|
|
32083
|
+
this.options = options;
|
|
32084
|
+
}
|
|
32085
|
+
logViewerRefCountByServerId = /* @__PURE__ */ new Map();
|
|
32086
|
+
firehoseSend = null;
|
|
32087
|
+
attach(send) {
|
|
32088
|
+
this.firehoseSend = send;
|
|
32089
|
+
}
|
|
32090
|
+
detach() {
|
|
32091
|
+
this.firehoseSend = null;
|
|
32092
|
+
this.logViewerRefCountByServerId.clear();
|
|
32093
|
+
}
|
|
32094
|
+
openLogViewer(serverId, viewerId) {
|
|
32095
|
+
const next = (this.logViewerRefCountByServerId.get(serverId) ?? 0) + 1;
|
|
32096
|
+
this.logViewerRefCountByServerId.set(serverId, next);
|
|
32097
|
+
this.sendSnapshot(serverId, viewerId);
|
|
32098
|
+
}
|
|
32099
|
+
closeLogViewer(serverId) {
|
|
32100
|
+
const n = (this.logViewerRefCountByServerId.get(serverId) ?? 0) - 1;
|
|
32101
|
+
if (n <= 0) this.logViewerRefCountByServerId.delete(serverId);
|
|
32102
|
+
else this.logViewerRefCountByServerId.set(serverId, n);
|
|
32103
|
+
}
|
|
32104
|
+
pushLogChunk(serverId, stream, chunk) {
|
|
32105
|
+
if ((this.logViewerRefCountByServerId.get(serverId) ?? 0) <= 0) return;
|
|
32106
|
+
if (!this.options.isPipedCaptureEnabled(serverId)) return;
|
|
32107
|
+
if (!this.firehoseSend) return;
|
|
32108
|
+
const text = chunk.toString("utf8");
|
|
32109
|
+
setImmediate(() => {
|
|
32110
|
+
if (!this.firehoseSend) return;
|
|
32111
|
+
this.firehoseSend(buildFirehoseLogChunkMessage({ serverId, stream, text, e2ee: this.options.e2ee }));
|
|
32112
|
+
});
|
|
32113
|
+
}
|
|
32114
|
+
sendSnapshot(serverId, viewerId) {
|
|
32115
|
+
const payload = buildFirehoseSnapshotMessage({
|
|
32116
|
+
serverId,
|
|
32117
|
+
viewerId,
|
|
32118
|
+
tails: this.options.getTails(serverId),
|
|
32119
|
+
e2ee: this.options.e2ee
|
|
32120
|
+
});
|
|
32121
|
+
setImmediate(() => {
|
|
32122
|
+
const send = this.firehoseSend;
|
|
32123
|
+
if (!send) return;
|
|
32124
|
+
send(payload);
|
|
32125
|
+
});
|
|
32126
|
+
}
|
|
32127
|
+
};
|
|
32128
|
+
|
|
32129
|
+
// src/dev-servers/manager/cleanup-merged-log-dir.ts
|
|
32130
|
+
import { rm } from "node:fs/promises";
|
|
32131
|
+
function cleanupMergedLogDirForServer(map2, serverId) {
|
|
32132
|
+
const mergedDir = map2.get(serverId);
|
|
32133
|
+
if (!mergedDir) return;
|
|
32134
|
+
map2.delete(serverId);
|
|
32135
|
+
void rm(mergedDir, { recursive: true, force: true }).catch(() => {
|
|
32136
|
+
});
|
|
32137
|
+
}
|
|
32138
|
+
|
|
32139
|
+
// src/dev-servers/manager/dev-server-manager.ts
|
|
31539
32140
|
var emptyTails = () => ({ stdout: [], stderr: [] });
|
|
31540
32141
|
var DevServerManager = class {
|
|
31541
32142
|
defsById = /* @__PURE__ */ new Map();
|
|
@@ -31543,66 +32144,36 @@ var DevServerManager = class {
|
|
|
31543
32144
|
streamTailsByServerId = /* @__PURE__ */ new Map();
|
|
31544
32145
|
spawnGenerationByServerId = /* @__PURE__ */ new Map();
|
|
31545
32146
|
pipedCaptureByServerId = /* @__PURE__ */ new Map();
|
|
31546
|
-
logViewerRefCountByServerId = /* @__PURE__ */ new Map();
|
|
31547
|
-
firehoseSend = null;
|
|
31548
32147
|
mergedLogPollByServerId = /* @__PURE__ */ new Map();
|
|
31549
32148
|
mergedLogCleanupDirByServerId = /* @__PURE__ */ new Map();
|
|
31550
32149
|
abortControllersByServerId = /* @__PURE__ */ new Map();
|
|
31551
32150
|
getWs;
|
|
31552
32151
|
log;
|
|
31553
32152
|
getBridgeCwd;
|
|
32153
|
+
e2ee;
|
|
32154
|
+
firehoseSink;
|
|
31554
32155
|
constructor(options) {
|
|
31555
32156
|
this.getWs = options.getWs;
|
|
31556
32157
|
this.log = options.log;
|
|
31557
32158
|
this.getBridgeCwd = options.getBridgeCwd ?? (() => process.cwd());
|
|
32159
|
+
this.e2ee = options.e2ee;
|
|
32160
|
+
this.firehoseSink = new DevServerFirehoseSink({
|
|
32161
|
+
getTails: (serverId) => this.snapshotTails(serverId),
|
|
32162
|
+
isPipedCaptureEnabled: (serverId) => this.pipedCaptureByServerId.get(serverId) === true,
|
|
32163
|
+
e2ee: this.e2ee
|
|
32164
|
+
});
|
|
31558
32165
|
}
|
|
31559
32166
|
attachFirehose(send) {
|
|
31560
|
-
this.
|
|
32167
|
+
this.firehoseSink.attach(send);
|
|
31561
32168
|
}
|
|
31562
32169
|
detachFirehose() {
|
|
31563
|
-
this.
|
|
31564
|
-
this.logViewerRefCountByServerId.clear();
|
|
32170
|
+
this.firehoseSink.detach();
|
|
31565
32171
|
}
|
|
31566
32172
|
handleFirehoseLogViewerOpen(serverId, _viewerId) {
|
|
31567
|
-
|
|
31568
|
-
this.logViewerRefCountByServerId.set(serverId, next);
|
|
31569
|
-
this.sendSnapshotToFirehose(serverId, _viewerId);
|
|
32173
|
+
this.firehoseSink.openLogViewer(serverId, _viewerId);
|
|
31570
32174
|
}
|
|
31571
32175
|
handleFirehoseLogViewerClose(serverId, _viewerId) {
|
|
31572
|
-
|
|
31573
|
-
if (n <= 0) this.logViewerRefCountByServerId.delete(serverId);
|
|
31574
|
-
else this.logViewerRefCountByServerId.set(serverId, n);
|
|
31575
|
-
}
|
|
31576
|
-
sendSnapshotToFirehose(serverId, viewerId) {
|
|
31577
|
-
const tails = this.streamTailsByServerId.get(serverId);
|
|
31578
|
-
const payload = {
|
|
31579
|
-
type: "log_snapshot",
|
|
31580
|
-
serverId,
|
|
31581
|
-
viewerId,
|
|
31582
|
-
stdoutTail: tails?.stdout.getTail() ?? [],
|
|
31583
|
-
stderrTail: tails?.stderr.getTail() ?? []
|
|
31584
|
-
};
|
|
31585
|
-
setImmediate(() => {
|
|
31586
|
-
const send = this.firehoseSend;
|
|
31587
|
-
if (!send) return;
|
|
31588
|
-
send(payload);
|
|
31589
|
-
});
|
|
31590
|
-
}
|
|
31591
|
-
pushRemoteLogChunk(serverId, stream, chunk) {
|
|
31592
|
-
if ((this.logViewerRefCountByServerId.get(serverId) ?? 0) <= 0) return;
|
|
31593
|
-
if (!this.pipedCaptureByServerId.get(serverId)) return;
|
|
31594
|
-
const send = this.firehoseSend;
|
|
31595
|
-
if (!send) return;
|
|
31596
|
-
const text = chunk.toString("utf8");
|
|
31597
|
-
setImmediate(() => {
|
|
31598
|
-
if (!this.firehoseSend) return;
|
|
31599
|
-
this.firehoseSend({
|
|
31600
|
-
type: "log_chunk",
|
|
31601
|
-
serverId,
|
|
31602
|
-
stream,
|
|
31603
|
-
text
|
|
31604
|
-
});
|
|
31605
|
-
});
|
|
32176
|
+
this.firehoseSink.closeLogViewer(serverId);
|
|
31606
32177
|
}
|
|
31607
32178
|
applyConfig(servers) {
|
|
31608
32179
|
this.defsById.clear();
|
|
@@ -31655,12 +32226,7 @@ var DevServerManager = class {
|
|
|
31655
32226
|
}
|
|
31656
32227
|
this.clearTails(serverId);
|
|
31657
32228
|
this.pipedCaptureByServerId.delete(serverId);
|
|
31658
|
-
|
|
31659
|
-
if (mergedDir) {
|
|
31660
|
-
this.mergedLogCleanupDirByServerId.delete(serverId);
|
|
31661
|
-
void rm(mergedDir, { recursive: true, force: true }).catch(() => {
|
|
31662
|
-
});
|
|
31663
|
-
}
|
|
32229
|
+
cleanupMergedLogDirForServer(this.mergedLogCleanupDirByServerId, serverId);
|
|
31664
32230
|
this.sendStatus(serverId, "stopped", void 0, tails);
|
|
31665
32231
|
}
|
|
31666
32232
|
start(serverId) {
|
|
@@ -31743,7 +32309,7 @@ var DevServerManager = class {
|
|
|
31743
32309
|
log: this.log,
|
|
31744
32310
|
stdoutTail,
|
|
31745
32311
|
stderrTail,
|
|
31746
|
-
pushRemoteLogChunk: (sid, stream, chunk) => this.
|
|
32312
|
+
pushRemoteLogChunk: (sid, stream, chunk) => this.firehoseSink.pushLogChunk(sid, stream, chunk),
|
|
31747
32313
|
sendStatus: (status, detail, tails) => this.sendStatus(serverId, status, detail, tails),
|
|
31748
32314
|
setPollInterval: (iv) => {
|
|
31749
32315
|
if (iv) this.mergedLogPollByServerId.set(serverId, iv);
|
|
@@ -31757,7 +32323,7 @@ var DevServerManager = class {
|
|
|
31757
32323
|
this.mergedLogCleanupDirByServerId.delete(serverId);
|
|
31758
32324
|
},
|
|
31759
32325
|
rmMergedCleanupDir: (dir) => {
|
|
31760
|
-
void
|
|
32326
|
+
void rm2(dir, { recursive: true, force: true }).catch(() => {
|
|
31761
32327
|
});
|
|
31762
32328
|
},
|
|
31763
32329
|
clearTailBuffers: () => this.clearTails(serverId)
|
|
@@ -31794,12 +32360,7 @@ var DevServerManager = class {
|
|
|
31794
32360
|
this.processes.delete(serverId);
|
|
31795
32361
|
this.clearPoll(serverId);
|
|
31796
32362
|
this.pipedCaptureByServerId.delete(serverId);
|
|
31797
|
-
|
|
31798
|
-
if (mergedDir) {
|
|
31799
|
-
this.mergedLogCleanupDirByServerId.delete(serverId);
|
|
31800
|
-
void rm(mergedDir, { recursive: true, force: true }).catch(() => {
|
|
31801
|
-
});
|
|
31802
|
-
}
|
|
32363
|
+
cleanupMergedLogDirForServer(this.mergedLogCleanupDirByServerId, serverId);
|
|
31803
32364
|
const tails = this.snapshotTails(serverId);
|
|
31804
32365
|
this.clearTails(serverId);
|
|
31805
32366
|
this.sendStatus(serverId, "unknown", "Bridge closed before process exited", tails);
|
|
@@ -32106,30 +32667,30 @@ function createOnBridgeIdentified(opts) {
|
|
|
32106
32667
|
}
|
|
32107
32668
|
|
|
32108
32669
|
// src/skills/discover-local-agent-skills.ts
|
|
32109
|
-
import
|
|
32110
|
-
import
|
|
32670
|
+
import fs24 from "node:fs";
|
|
32671
|
+
import path26 from "node:path";
|
|
32111
32672
|
var SKILL_DISCOVERY_ROOTS = [".agents/skills", ".claude/skills", ".cursor/skills", "skills"];
|
|
32112
32673
|
function discoverLocalSkills(cwd) {
|
|
32113
32674
|
const out = [];
|
|
32114
32675
|
const seenKeys = /* @__PURE__ */ new Set();
|
|
32115
32676
|
for (const rel of SKILL_DISCOVERY_ROOTS) {
|
|
32116
|
-
const base =
|
|
32117
|
-
if (!
|
|
32677
|
+
const base = path26.join(cwd, rel);
|
|
32678
|
+
if (!fs24.existsSync(base) || !fs24.statSync(base).isDirectory()) continue;
|
|
32118
32679
|
let entries = [];
|
|
32119
32680
|
try {
|
|
32120
|
-
entries =
|
|
32681
|
+
entries = fs24.readdirSync(base);
|
|
32121
32682
|
} catch {
|
|
32122
32683
|
continue;
|
|
32123
32684
|
}
|
|
32124
32685
|
for (const name of entries) {
|
|
32125
|
-
const dir =
|
|
32686
|
+
const dir = path26.join(base, name);
|
|
32126
32687
|
try {
|
|
32127
|
-
if (!
|
|
32688
|
+
if (!fs24.statSync(dir).isDirectory()) continue;
|
|
32128
32689
|
} catch {
|
|
32129
32690
|
continue;
|
|
32130
32691
|
}
|
|
32131
|
-
const skillMd =
|
|
32132
|
-
if (!
|
|
32692
|
+
const skillMd = path26.join(dir, "SKILL.md");
|
|
32693
|
+
if (!fs24.existsSync(skillMd)) continue;
|
|
32133
32694
|
const key = `${rel}/${name}`;
|
|
32134
32695
|
if (seenKeys.has(key)) continue;
|
|
32135
32696
|
seenKeys.add(key);
|
|
@@ -32141,23 +32702,23 @@ function discoverLocalSkills(cwd) {
|
|
|
32141
32702
|
function discoverSkillLayoutRoots(cwd) {
|
|
32142
32703
|
const roots = [];
|
|
32143
32704
|
for (const rel of SKILL_DISCOVERY_ROOTS) {
|
|
32144
|
-
const base =
|
|
32145
|
-
if (!
|
|
32705
|
+
const base = path26.join(cwd, rel);
|
|
32706
|
+
if (!fs24.existsSync(base) || !fs24.statSync(base).isDirectory()) continue;
|
|
32146
32707
|
let entries = [];
|
|
32147
32708
|
try {
|
|
32148
|
-
entries =
|
|
32709
|
+
entries = fs24.readdirSync(base);
|
|
32149
32710
|
} catch {
|
|
32150
32711
|
continue;
|
|
32151
32712
|
}
|
|
32152
32713
|
const skills2 = [];
|
|
32153
32714
|
for (const name of entries) {
|
|
32154
|
-
const dir =
|
|
32715
|
+
const dir = path26.join(base, name);
|
|
32155
32716
|
try {
|
|
32156
|
-
if (!
|
|
32717
|
+
if (!fs24.statSync(dir).isDirectory()) continue;
|
|
32157
32718
|
} catch {
|
|
32158
32719
|
continue;
|
|
32159
32720
|
}
|
|
32160
|
-
if (!
|
|
32721
|
+
if (!fs24.existsSync(path26.join(dir, "SKILL.md"))) continue;
|
|
32161
32722
|
const relPath = `${rel}/${name}`.replace(/\\/g, "/");
|
|
32162
32723
|
skills2.push({ name, relPath });
|
|
32163
32724
|
}
|
|
@@ -32259,7 +32820,7 @@ function reportGitRepos(getWs, log2) {
|
|
|
32259
32820
|
var handleAuthToken = (msg, { log: log2 }) => {
|
|
32260
32821
|
if (typeof msg.token !== "string") return;
|
|
32261
32822
|
log2("Received auth token. Save it for future runs:");
|
|
32262
|
-
log2(` export
|
|
32823
|
+
log2(` export BUILDAUTOMATON_AUTH_TOKEN="${msg.token}"`);
|
|
32263
32824
|
};
|
|
32264
32825
|
|
|
32265
32826
|
// src/bridge/routing/handlers/bridge-identified.ts
|
|
@@ -32302,12 +32863,12 @@ var handleAgentConfigMessage = (msg, deps) => {
|
|
|
32302
32863
|
};
|
|
32303
32864
|
|
|
32304
32865
|
// src/agents/acp/from-bridge/handle-bridge-prompt.ts
|
|
32305
|
-
import * as
|
|
32306
|
-
import { execFile as
|
|
32307
|
-
import { promisify as
|
|
32866
|
+
import * as path28 from "node:path";
|
|
32867
|
+
import { execFile as execFile10 } from "node:child_process";
|
|
32868
|
+
import { promisify as promisify10 } from "node:util";
|
|
32308
32869
|
|
|
32309
32870
|
// src/git/bridge-queue-key.ts
|
|
32310
|
-
import * as
|
|
32871
|
+
import * as path27 from "node:path";
|
|
32311
32872
|
import { createHash } from "node:crypto";
|
|
32312
32873
|
function normalizeCanonicalGitUrl(url2) {
|
|
32313
32874
|
let s = url2.trim();
|
|
@@ -32335,11 +32896,11 @@ function canonicalUrlToRepoIdSync(url2) {
|
|
|
32335
32896
|
return createHash("sha256").update(normalized).digest("hex").slice(0, 32);
|
|
32336
32897
|
}
|
|
32337
32898
|
function fallbackRepoIdFromPath(absPath) {
|
|
32338
|
-
return createHash("sha256").update(
|
|
32899
|
+
return createHash("sha256").update(path27.resolve(absPath)).digest("hex").slice(0, 32);
|
|
32339
32900
|
}
|
|
32340
32901
|
async function resolveBridgeQueueBindFields(options) {
|
|
32341
32902
|
const { effectiveCwd, worktreePaths, primaryRepoRoots, log: log2 } = options;
|
|
32342
|
-
const cwdAbs = worktreePaths.length > 0 ?
|
|
32903
|
+
const cwdAbs = worktreePaths.length > 0 ? path27.resolve(worktreePaths[0]) : path27.resolve(effectiveCwd);
|
|
32343
32904
|
if (!primaryRepoRoots.length) {
|
|
32344
32905
|
log2("[Bridge service] Prompt queue bind skipped: no Git repository roots under the working directory.");
|
|
32345
32906
|
return null;
|
|
@@ -32362,10 +32923,10 @@ async function resolveBridgeQueueBindFields(options) {
|
|
|
32362
32923
|
}
|
|
32363
32924
|
|
|
32364
32925
|
// src/agents/acp/from-bridge/handle-bridge-prompt.ts
|
|
32365
|
-
var
|
|
32926
|
+
var execFileAsync9 = promisify10(execFile10);
|
|
32366
32927
|
async function readGitBranch(cwd) {
|
|
32367
32928
|
try {
|
|
32368
|
-
const { stdout } = await
|
|
32929
|
+
const { stdout } = await execFileAsync9("git", ["branch", "--show-current"], { cwd, maxBuffer: 64 * 1024 });
|
|
32369
32930
|
const b = stdout.trim();
|
|
32370
32931
|
return b || null;
|
|
32371
32932
|
} catch {
|
|
@@ -32376,22 +32937,40 @@ function handleBridgePrompt(msg, deps) {
|
|
|
32376
32937
|
const { getWs, log: log2, acpManager, sessionWorktreeManager } = deps;
|
|
32377
32938
|
const rawPrompt = msg.prompt;
|
|
32378
32939
|
const promptText = typeof rawPrompt === "string" ? rawPrompt : rawPrompt != null ? String(rawPrompt) : "";
|
|
32940
|
+
const sessionId = msg.sessionId;
|
|
32941
|
+
const runId = typeof msg.runId === "string" ? msg.runId : void 0;
|
|
32942
|
+
const promptId = typeof msg.id === "string" ? msg.id : void 0;
|
|
32943
|
+
const sendBridgeMessage = (message, encryptedFields = []) => {
|
|
32944
|
+
const s = getWs();
|
|
32945
|
+
if (!s) return false;
|
|
32946
|
+
const wire = deps.e2ee && encryptedFields.length > 0 ? deps.e2ee.encryptFields(message, encryptedFields) : message;
|
|
32947
|
+
sendWsMessage(s, wire);
|
|
32948
|
+
return true;
|
|
32949
|
+
};
|
|
32379
32950
|
if (!promptText.trim()) {
|
|
32380
32951
|
log2(
|
|
32381
32952
|
`[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).`
|
|
32382
32953
|
);
|
|
32954
|
+
sendBridgeMessage(
|
|
32955
|
+
{
|
|
32956
|
+
type: "prompt_result",
|
|
32957
|
+
...promptId ? { id: promptId } : {},
|
|
32958
|
+
...sessionId ? { sessionId } : {},
|
|
32959
|
+
...runId ? { runId } : {},
|
|
32960
|
+
success: false,
|
|
32961
|
+
error: "Empty or missing prompt text from the bridge; this turn was not sent to the agent."
|
|
32962
|
+
},
|
|
32963
|
+
["error"]
|
|
32964
|
+
);
|
|
32383
32965
|
return;
|
|
32384
32966
|
}
|
|
32385
|
-
const sessionId = msg.sessionId;
|
|
32386
32967
|
const isNewSession = msg.isNewSession === true;
|
|
32387
32968
|
const sessionWorktreesEnabled = msg.sessionWorktreesEnabled === true;
|
|
32388
32969
|
const agentType = typeof msg.agentType === "string" && msg.agentType.trim() ? msg.agentType.trim() : void 0;
|
|
32389
|
-
const runId = typeof msg.runId === "string" ? msg.runId : void 0;
|
|
32390
32970
|
const mode = typeof msg.mode === "string" && msg.mode.trim() ? msg.mode.trim() : void 0;
|
|
32391
32971
|
acpManager.logPromptReceivedFromBridge({ agentType, mode });
|
|
32392
32972
|
const sendResult2 = (result) => {
|
|
32393
|
-
|
|
32394
|
-
if (s) sendWsMessage(s, result);
|
|
32973
|
+
sendBridgeMessage(result, result.type === "prompt_result" ? ["output", "error"] : []);
|
|
32395
32974
|
};
|
|
32396
32975
|
const sendSessionUpdate = (payload) => {
|
|
32397
32976
|
const s = getWs();
|
|
@@ -32400,11 +32979,19 @@ function handleBridgePrompt(msg, deps) {
|
|
|
32400
32979
|
return;
|
|
32401
32980
|
}
|
|
32402
32981
|
const p = payload;
|
|
32403
|
-
|
|
32982
|
+
const wire = p.type === "session_update" && deps.e2ee ? deps.e2ee.encryptFields(payload, ["payload"]) : p.type === "session_file_change" && deps.e2ee ? deps.e2ee.encryptFields(payload, [
|
|
32983
|
+
"path",
|
|
32984
|
+
"oldText",
|
|
32985
|
+
"newText",
|
|
32986
|
+
"patchContent",
|
|
32987
|
+
"isDirectory",
|
|
32988
|
+
"directoryRemoved"
|
|
32989
|
+
]) : payload;
|
|
32990
|
+
sendWsMessage(s, wire);
|
|
32404
32991
|
};
|
|
32405
32992
|
async function preambleAndPrompt(resolvedCwd) {
|
|
32406
32993
|
const s = getWs();
|
|
32407
|
-
const effectiveCwd =
|
|
32994
|
+
const effectiveCwd = path28.resolve(resolvedCwd ?? getBridgeWorkspaceDirectory());
|
|
32408
32995
|
const worktreePaths = sessionWorktreeManager.getWorktreePathsForSession(sessionId) ?? [];
|
|
32409
32996
|
const repoRoots = await resolveSnapshotRepoRoots({
|
|
32410
32997
|
worktreePaths,
|
|
@@ -32529,15 +33116,15 @@ var handleSkillCallMessage = (msg, { getWs, log: log2 }) => {
|
|
|
32529
33116
|
};
|
|
32530
33117
|
|
|
32531
33118
|
// src/files/list-dir.ts
|
|
32532
|
-
import
|
|
32533
|
-
import
|
|
33119
|
+
import fs25 from "node:fs";
|
|
33120
|
+
import path30 from "node:path";
|
|
32534
33121
|
|
|
32535
33122
|
// src/files/ensure-under-cwd.ts
|
|
32536
|
-
import
|
|
33123
|
+
import path29 from "node:path";
|
|
32537
33124
|
function ensureUnderCwd(relativePath, cwd = getBridgeWorkspaceDirectory()) {
|
|
32538
|
-
const normalized =
|
|
32539
|
-
const resolved =
|
|
32540
|
-
if (!resolved.startsWith(cwd +
|
|
33125
|
+
const normalized = path29.normalize(relativePath).replace(/^(\.\/)+/, "");
|
|
33126
|
+
const resolved = path29.resolve(cwd, normalized);
|
|
33127
|
+
if (!resolved.startsWith(cwd + path29.sep) && resolved !== cwd) {
|
|
32541
33128
|
return null;
|
|
32542
33129
|
}
|
|
32543
33130
|
return resolved;
|
|
@@ -32551,7 +33138,7 @@ async function listDirAsync(relativePath) {
|
|
|
32551
33138
|
return { error: "Path is outside working directory" };
|
|
32552
33139
|
}
|
|
32553
33140
|
try {
|
|
32554
|
-
const names = await
|
|
33141
|
+
const names = await fs25.promises.readdir(resolved, { withFileTypes: true });
|
|
32555
33142
|
const visible = names.filter((d) => !d.name.startsWith("."));
|
|
32556
33143
|
const entries = [];
|
|
32557
33144
|
for (let i = 0; i < visible.length; i++) {
|
|
@@ -32559,12 +33146,12 @@ async function listDirAsync(relativePath) {
|
|
|
32559
33146
|
await yieldToEventLoop();
|
|
32560
33147
|
}
|
|
32561
33148
|
const d = visible[i];
|
|
32562
|
-
const entryPath =
|
|
32563
|
-
const fullPath =
|
|
33149
|
+
const entryPath = path30.join(relativePath || ".", d.name).replace(/\\/g, "/");
|
|
33150
|
+
const fullPath = path30.join(resolved, d.name);
|
|
32564
33151
|
let isDir = d.isDirectory();
|
|
32565
33152
|
if (d.isSymbolicLink()) {
|
|
32566
33153
|
try {
|
|
32567
|
-
const targetStat = await
|
|
33154
|
+
const targetStat = await fs25.promises.stat(fullPath);
|
|
32568
33155
|
isDir = targetStat.isDirectory();
|
|
32569
33156
|
} catch {
|
|
32570
33157
|
isDir = false;
|
|
@@ -32589,25 +33176,25 @@ async function listDirAsync(relativePath) {
|
|
|
32589
33176
|
}
|
|
32590
33177
|
|
|
32591
33178
|
// src/files/read-file.ts
|
|
32592
|
-
import
|
|
33179
|
+
import fs26 from "node:fs";
|
|
32593
33180
|
import { StringDecoder } from "node:string_decoder";
|
|
32594
33181
|
function resolveFilePath(relativePath) {
|
|
32595
33182
|
const resolved = ensureUnderCwd(relativePath, getBridgeWorkspaceDirectory());
|
|
32596
33183
|
if (!resolved) return { error: "Path is outside working directory" };
|
|
32597
33184
|
let real;
|
|
32598
33185
|
try {
|
|
32599
|
-
real =
|
|
33186
|
+
real = fs26.realpathSync(resolved);
|
|
32600
33187
|
} catch {
|
|
32601
33188
|
real = resolved;
|
|
32602
33189
|
}
|
|
32603
|
-
const stat2 =
|
|
33190
|
+
const stat2 = fs26.statSync(real);
|
|
32604
33191
|
if (!stat2.isFile()) return { error: "Not a file" };
|
|
32605
33192
|
return real;
|
|
32606
33193
|
}
|
|
32607
33194
|
var LINE_CHUNK_SIZE = 64 * 1024;
|
|
32608
33195
|
function readFileRange(filePath, startLine, endLine, lineOffsetIn, lineChunkSize = LINE_CHUNK_SIZE) {
|
|
32609
|
-
const fileSize =
|
|
32610
|
-
const fd =
|
|
33196
|
+
const fileSize = fs26.statSync(filePath).size;
|
|
33197
|
+
const fd = fs26.openSync(filePath, "r");
|
|
32611
33198
|
const bufSize = 64 * 1024;
|
|
32612
33199
|
const buf = Buffer.alloc(bufSize);
|
|
32613
33200
|
const decoder = new StringDecoder("utf8");
|
|
@@ -32620,7 +33207,7 @@ function readFileRange(filePath, startLine, endLine, lineOffsetIn, lineChunkSize
|
|
|
32620
33207
|
let line0Accum = "";
|
|
32621
33208
|
try {
|
|
32622
33209
|
let bytesRead;
|
|
32623
|
-
while (!done && (bytesRead =
|
|
33210
|
+
while (!done && (bytesRead = fs26.readSync(fd, buf, 0, bufSize, null)) > 0) {
|
|
32624
33211
|
const text = partial2 + decoder.write(buf.subarray(0, bytesRead));
|
|
32625
33212
|
partial2 = "";
|
|
32626
33213
|
let lineStart = 0;
|
|
@@ -32755,7 +33342,7 @@ function readFileRange(filePath, startLine, endLine, lineOffsetIn, lineChunkSize
|
|
|
32755
33342
|
}
|
|
32756
33343
|
return { content: resultLines.join("\n"), size: fileSize };
|
|
32757
33344
|
} finally {
|
|
32758
|
-
|
|
33345
|
+
fs26.closeSync(fd);
|
|
32759
33346
|
}
|
|
32760
33347
|
}
|
|
32761
33348
|
function readFile2(relativePath, startLine, endLine, lineOffset, lineChunkSize = LINE_CHUNK_SIZE) {
|
|
@@ -32766,8 +33353,8 @@ function readFile2(relativePath, startLine, endLine, lineOffset, lineChunkSize =
|
|
|
32766
33353
|
if (hasRange) {
|
|
32767
33354
|
return readFileRange(result, startLine, endLine, lineOffset, lineChunkSize);
|
|
32768
33355
|
}
|
|
32769
|
-
const stat2 =
|
|
32770
|
-
const raw =
|
|
33356
|
+
const stat2 = fs26.statSync(result);
|
|
33357
|
+
const raw = fs26.readFileSync(result, "utf8");
|
|
32771
33358
|
const lines = raw.split(/\r?\n/);
|
|
32772
33359
|
return { content: raw, totalLines: lines.length, size: stat2.size };
|
|
32773
33360
|
} catch (err) {
|
|
@@ -32781,28 +33368,30 @@ async function readFileAsync(relativePath, startLine, endLine, lineOffset, lineC
|
|
|
32781
33368
|
|
|
32782
33369
|
// src/files/handle-file-browser-search.ts
|
|
32783
33370
|
var SEARCH_LIMIT = 100;
|
|
32784
|
-
function handleFileBrowserSearch(msg, socket) {
|
|
33371
|
+
function handleFileBrowserSearch(msg, socket, e2ee) {
|
|
32785
33372
|
void (async () => {
|
|
32786
33373
|
await yieldToEventLoop();
|
|
32787
33374
|
const q = typeof msg.q === "string" ? msg.q : "";
|
|
32788
33375
|
const cwd = getBridgeWorkspaceDirectory();
|
|
32789
33376
|
const index = loadFileIndex(cwd);
|
|
32790
33377
|
if (index === null) {
|
|
32791
|
-
|
|
33378
|
+
const payload2 = {
|
|
32792
33379
|
type: "file_browser_search_response",
|
|
32793
33380
|
id: msg.id,
|
|
32794
33381
|
paths: [],
|
|
32795
33382
|
indexReady: false
|
|
32796
|
-
}
|
|
33383
|
+
};
|
|
33384
|
+
sendWsMessage(socket, e2ee ? e2ee.encryptFields(payload2, ["paths"]) : payload2);
|
|
32797
33385
|
return;
|
|
32798
33386
|
}
|
|
32799
33387
|
const results = await searchFileIndexAsync(index, q, SEARCH_LIMIT);
|
|
32800
|
-
|
|
33388
|
+
const payload = {
|
|
32801
33389
|
type: "file_browser_search_response",
|
|
32802
33390
|
id: msg.id,
|
|
32803
33391
|
paths: results,
|
|
32804
33392
|
indexReady: true
|
|
32805
|
-
}
|
|
33393
|
+
};
|
|
33394
|
+
sendWsMessage(socket, e2ee ? e2ee.encryptFields(payload, ["paths"]) : payload);
|
|
32806
33395
|
})();
|
|
32807
33396
|
}
|
|
32808
33397
|
function triggerFileIndexBuild() {
|
|
@@ -32814,7 +33403,10 @@ function triggerFileIndexBuild() {
|
|
|
32814
33403
|
}
|
|
32815
33404
|
|
|
32816
33405
|
// src/files/handle-file-browser-request.ts
|
|
32817
|
-
function
|
|
33406
|
+
function sendFileBrowserMessage(socket, e2ee, payload) {
|
|
33407
|
+
sendWsMessage(socket, e2ee ? e2ee.encryptFields(payload, ["entries", "content", "totalLines", "size", "lineOffset"]) : payload);
|
|
33408
|
+
}
|
|
33409
|
+
function handleFileBrowserRequest(msg, socket, e2ee) {
|
|
32818
33410
|
void (async () => {
|
|
32819
33411
|
const reqPath = msg.path.replace(/^\/+/, "") || ".";
|
|
32820
33412
|
const op = msg.op === "read" ? "read" : "list";
|
|
@@ -32823,7 +33415,7 @@ function handleFileBrowserRequest(msg, socket) {
|
|
|
32823
33415
|
if ("error" in result) {
|
|
32824
33416
|
sendWsMessage(socket, { type: "file_browser_response", id: msg.id, error: result.error });
|
|
32825
33417
|
} else {
|
|
32826
|
-
|
|
33418
|
+
sendFileBrowserMessage(socket, e2ee, { type: "file_browser_response", id: msg.id, entries: result.entries });
|
|
32827
33419
|
if (reqPath === "." || reqPath === "") {
|
|
32828
33420
|
triggerFileIndexBuild();
|
|
32829
33421
|
}
|
|
@@ -32845,27 +33437,28 @@ function handleFileBrowserRequest(msg, socket) {
|
|
|
32845
33437
|
size: result.size
|
|
32846
33438
|
};
|
|
32847
33439
|
if (result.lineOffset != null) payload.lineOffset = result.lineOffset;
|
|
32848
|
-
|
|
33440
|
+
sendFileBrowserMessage(socket, e2ee, payload);
|
|
32849
33441
|
}
|
|
32850
33442
|
}
|
|
32851
33443
|
})();
|
|
32852
33444
|
}
|
|
32853
33445
|
|
|
32854
33446
|
// src/bridge/routing/handlers/file-browser-messages.ts
|
|
32855
|
-
function handleFileBrowserRequestMessage(msg, { getWs }) {
|
|
33447
|
+
function handleFileBrowserRequestMessage(msg, { getWs, e2ee }) {
|
|
32856
33448
|
if (typeof msg.id !== "string" || typeof msg.path !== "string") return;
|
|
32857
33449
|
const socket = getWs();
|
|
32858
33450
|
if (!socket) return;
|
|
32859
33451
|
handleFileBrowserRequest(
|
|
32860
33452
|
msg,
|
|
32861
|
-
socket
|
|
33453
|
+
socket,
|
|
33454
|
+
e2ee
|
|
32862
33455
|
);
|
|
32863
33456
|
}
|
|
32864
|
-
function handleFileBrowserSearchMessage(msg, { getWs }) {
|
|
33457
|
+
function handleFileBrowserSearchMessage(msg, { getWs, e2ee }) {
|
|
32865
33458
|
if (typeof msg.id !== "string") return;
|
|
32866
33459
|
const socket = getWs();
|
|
32867
33460
|
if (!socket) return;
|
|
32868
|
-
handleFileBrowserSearch(msg, socket);
|
|
33461
|
+
handleFileBrowserSearch(msg, socket, e2ee);
|
|
32869
33462
|
}
|
|
32870
33463
|
|
|
32871
33464
|
// src/bridge/routing/handlers/skill-layout-request.ts
|
|
@@ -32877,8 +33470,8 @@ function handleSkillLayoutRequest(msg, deps) {
|
|
|
32877
33470
|
}
|
|
32878
33471
|
|
|
32879
33472
|
// src/skills/install-remote-skills.ts
|
|
32880
|
-
import
|
|
32881
|
-
import
|
|
33473
|
+
import fs27 from "node:fs";
|
|
33474
|
+
import path31 from "node:path";
|
|
32882
33475
|
function installRemoteSkills(cwd, targetDir, items) {
|
|
32883
33476
|
const installed2 = [];
|
|
32884
33477
|
if (!Array.isArray(items)) {
|
|
@@ -32889,15 +33482,15 @@ function installRemoteSkills(cwd, targetDir, items) {
|
|
|
32889
33482
|
if (typeof item.sourceId !== "string" || typeof item.skillName !== "string" || typeof item.versionHash !== "string" || !Array.isArray(item.files)) {
|
|
32890
33483
|
continue;
|
|
32891
33484
|
}
|
|
32892
|
-
const skillDir =
|
|
33485
|
+
const skillDir = path31.join(cwd, targetDir, item.skillName);
|
|
32893
33486
|
for (const f of item.files) {
|
|
32894
33487
|
if (typeof f.path !== "string" || !f.text && !f.base64) continue;
|
|
32895
|
-
const dest =
|
|
32896
|
-
|
|
33488
|
+
const dest = path31.join(skillDir, f.path);
|
|
33489
|
+
fs27.mkdirSync(path31.dirname(dest), { recursive: true });
|
|
32897
33490
|
if (f.text !== void 0) {
|
|
32898
|
-
|
|
33491
|
+
fs27.writeFileSync(dest, f.text, "utf8");
|
|
32899
33492
|
} else if (f.base64) {
|
|
32900
|
-
|
|
33493
|
+
fs27.writeFileSync(dest, Buffer.from(f.base64, "base64"));
|
|
32901
33494
|
}
|
|
32902
33495
|
}
|
|
32903
33496
|
installed2.push({
|
|
@@ -32935,9 +33528,10 @@ var handleRefreshLocalSkills = (_msg, deps) => {
|
|
|
32935
33528
|
};
|
|
32936
33529
|
|
|
32937
33530
|
// src/bridge/routing/handlers/session-git-request.ts
|
|
32938
|
-
function sendResult(ws, id, payload) {
|
|
33531
|
+
function sendResult(ws, id, payload, e2ee, encryptedFields = []) {
|
|
32939
33532
|
if (!ws) return;
|
|
32940
|
-
|
|
33533
|
+
const message = { type: "session_git_result", id, ...payload };
|
|
33534
|
+
sendWsMessage(ws, e2ee && encryptedFields.length > 0 ? e2ee.encryptFields(message, encryptedFields) : message);
|
|
32941
33535
|
}
|
|
32942
33536
|
var handleSessionGitRequestMessage = (msg, deps) => {
|
|
32943
33537
|
if (typeof msg.id !== "string") return;
|
|
@@ -32947,7 +33541,7 @@ var handleSessionGitRequestMessage = (msg, deps) => {
|
|
|
32947
33541
|
return;
|
|
32948
33542
|
void (async () => {
|
|
32949
33543
|
const ws = deps.getWs();
|
|
32950
|
-
const reply = (payload) => sendResult(ws, msg.id, payload);
|
|
33544
|
+
const reply = (payload, encryptedFields = []) => sendResult(ws, msg.id, payload, deps.e2ee, encryptedFields);
|
|
32951
33545
|
try {
|
|
32952
33546
|
if (action === "status") {
|
|
32953
33547
|
const r = await deps.sessionWorktreeManager.getSessionWorkingTreeStatus(sessionId);
|
|
@@ -32973,7 +33567,7 @@ var handleSessionGitRequestMessage = (msg, deps) => {
|
|
|
32973
33567
|
reply({
|
|
32974
33568
|
ok: true,
|
|
32975
33569
|
repos
|
|
32976
|
-
});
|
|
33570
|
+
}, ["repos"]);
|
|
32977
33571
|
return;
|
|
32978
33572
|
}
|
|
32979
33573
|
if (action === "push") {
|
|
@@ -33042,7 +33636,7 @@ var handleSessionDiscardedMessage = (msg, deps) => {
|
|
|
33042
33636
|
};
|
|
33043
33637
|
|
|
33044
33638
|
// src/bridge/routing/handlers/revert-turn-snapshot.ts
|
|
33045
|
-
import * as
|
|
33639
|
+
import * as fs28 from "node:fs";
|
|
33046
33640
|
var handleRevertTurnSnapshotMessage = (msg, deps) => {
|
|
33047
33641
|
const id = typeof msg.id === "string" ? msg.id : "";
|
|
33048
33642
|
const sessionId = typeof msg.sessionId === "string" ? msg.sessionId : "";
|
|
@@ -33054,7 +33648,7 @@ var handleRevertTurnSnapshotMessage = (msg, deps) => {
|
|
|
33054
33648
|
if (!s) return;
|
|
33055
33649
|
const agentBase = sessionWorktreeManager.getAgentCwdForSession(sessionId) ?? getBridgeWorkspaceDirectory();
|
|
33056
33650
|
const file2 = snapshotFilePath(agentBase, turnId);
|
|
33057
|
-
if (!
|
|
33651
|
+
if (!fs28.existsSync(file2)) {
|
|
33058
33652
|
sendWsMessage(s, {
|
|
33059
33653
|
type: "revert_turn_snapshot_result",
|
|
33060
33654
|
id,
|
|
@@ -33075,8 +33669,15 @@ var handleRevertTurnSnapshotMessage = (msg, deps) => {
|
|
|
33075
33669
|
|
|
33076
33670
|
// src/bridge/routing/handlers/dev-server-control.ts
|
|
33077
33671
|
var handleDevServerControl = (msg, deps) => {
|
|
33078
|
-
|
|
33079
|
-
|
|
33672
|
+
let wire = msg;
|
|
33673
|
+
try {
|
|
33674
|
+
wire = deps.e2ee ? deps.e2ee.decryptMessage(msg) : msg;
|
|
33675
|
+
} catch (e) {
|
|
33676
|
+
deps.log(`[E2EE] Could not decrypt dev server command: ${e instanceof Error ? e.message : String(e)}`);
|
|
33677
|
+
return;
|
|
33678
|
+
}
|
|
33679
|
+
const serverId = typeof wire.serverId === "string" ? wire.serverId : "";
|
|
33680
|
+
const action = wire.action === "start" || wire.action === "stop" ? wire.action : null;
|
|
33080
33681
|
if (!serverId || !action) return;
|
|
33081
33682
|
deps.devServerManager?.handleControl(serverId, action);
|
|
33082
33683
|
};
|
|
@@ -33202,7 +33803,8 @@ function createMainBridgeWebSocketLifecycle(params) {
|
|
|
33202
33803
|
messageDeps,
|
|
33203
33804
|
tokens,
|
|
33204
33805
|
persistTokens,
|
|
33205
|
-
onAuthInvalid
|
|
33806
|
+
onAuthInvalid,
|
|
33807
|
+
e2ee
|
|
33206
33808
|
} = params;
|
|
33207
33809
|
let authRefreshInFlight = false;
|
|
33208
33810
|
function handleOpen() {
|
|
@@ -33215,15 +33817,15 @@ function createMainBridgeWebSocketLifecycle(params) {
|
|
|
33215
33817
|
}
|
|
33216
33818
|
const socket = getWs();
|
|
33217
33819
|
if (socket) {
|
|
33218
|
-
sendWsMessage(socket, { type: "identify", role: "cli" });
|
|
33820
|
+
sendWsMessage(socket, { type: "identify", role: "cli", ...e2ee ? { e: e2ee.handshake } : {} });
|
|
33219
33821
|
reportGitRepos(getWs, logFn);
|
|
33220
33822
|
}
|
|
33221
33823
|
if (justAuthenticated && socket) {
|
|
33222
33824
|
logFn(
|
|
33223
33825
|
"Save these for future runs (access token may rotate; refresh token is stored in ~/.buildautomaton/config.json when you use browser auth):"
|
|
33224
33826
|
);
|
|
33225
|
-
logFn(` export
|
|
33226
|
-
logFn(` export
|
|
33827
|
+
logFn(` export BUILDAUTOMATON_AUTH_TOKEN="${tokens.accessToken}"`);
|
|
33828
|
+
logFn(` export BUILDAUTOMATON_WORKSPACE_ID="${workspaceId}"`);
|
|
33227
33829
|
}
|
|
33228
33830
|
}
|
|
33229
33831
|
function handleClose(code, reason) {
|
|
@@ -33305,6 +33907,100 @@ function createMainBridgeWebSocketLifecycle(params) {
|
|
|
33305
33907
|
return { connect };
|
|
33306
33908
|
}
|
|
33307
33909
|
|
|
33910
|
+
// ../e2ee/src/constants.ts
|
|
33911
|
+
var E2EE_NONCE_BYTES = 12;
|
|
33912
|
+
|
|
33913
|
+
// ../e2ee/src/types.ts
|
|
33914
|
+
function isE2eeEnvelope(value) {
|
|
33915
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
|
|
33916
|
+
const o = value;
|
|
33917
|
+
return typeof o.k === "string" && typeof o.n === "string" && typeof o.c === "string";
|
|
33918
|
+
}
|
|
33919
|
+
|
|
33920
|
+
// ../e2ee/src/encoding.ts
|
|
33921
|
+
function base64UrlEncode(bytes) {
|
|
33922
|
+
let binary = "";
|
|
33923
|
+
for (let i = 0; i < bytes.length; i += 1) binary += String.fromCharCode(bytes[i]);
|
|
33924
|
+
const b64 = btoa(binary);
|
|
33925
|
+
return b64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
|
|
33926
|
+
}
|
|
33927
|
+
function base64UrlDecode(value) {
|
|
33928
|
+
const b64 = value.replace(/-/g, "+").replace(/_/g, "/");
|
|
33929
|
+
const padded = b64 + "=".repeat((4 - b64.length % 4) % 4);
|
|
33930
|
+
const binary = atob(padded);
|
|
33931
|
+
const out = new Uint8Array(binary.length);
|
|
33932
|
+
for (let i = 0; i < binary.length; i += 1) out[i] = binary.charCodeAt(i);
|
|
33933
|
+
return out;
|
|
33934
|
+
}
|
|
33935
|
+
|
|
33936
|
+
// src/lib/e2ee/cli-e2ee-runtime.ts
|
|
33937
|
+
import { createCipheriv, createDecipheriv, randomBytes } from "node:crypto";
|
|
33938
|
+
function nonceFromCounter(prefix, counter) {
|
|
33939
|
+
const nonce = Buffer.alloc(E2EE_NONCE_BYTES);
|
|
33940
|
+
prefix.copy(nonce, 0);
|
|
33941
|
+
nonce.writeBigUInt64BE(counter, 4);
|
|
33942
|
+
return nonce;
|
|
33943
|
+
}
|
|
33944
|
+
function createCliE2eeRuntime(key) {
|
|
33945
|
+
const rawKey = Buffer.from(base64UrlDecode(key.k));
|
|
33946
|
+
const prefix = randomBytes(4);
|
|
33947
|
+
let counter = 0n;
|
|
33948
|
+
function nextNonce() {
|
|
33949
|
+
counter += 1n;
|
|
33950
|
+
return nonceFromCounter(prefix, counter);
|
|
33951
|
+
}
|
|
33952
|
+
function encryptObject(messageWithoutSensitiveFields, plaintext) {
|
|
33953
|
+
const nonce = nextNonce();
|
|
33954
|
+
const cipher = createCipheriv("aes-256-gcm", rawKey, nonce);
|
|
33955
|
+
const ciphertext = Buffer.concat([cipher.update(JSON.stringify(plaintext), "utf8"), cipher.final()]);
|
|
33956
|
+
const tag = cipher.getAuthTag();
|
|
33957
|
+
return {
|
|
33958
|
+
k: key.id,
|
|
33959
|
+
n: base64UrlEncode(nonce),
|
|
33960
|
+
c: base64UrlEncode(Buffer.concat([ciphertext, tag]))
|
|
33961
|
+
};
|
|
33962
|
+
}
|
|
33963
|
+
return {
|
|
33964
|
+
keyId: key.id,
|
|
33965
|
+
handshake: { k: key.id, a: key.a },
|
|
33966
|
+
encryptFields(message, fields) {
|
|
33967
|
+
const plaintext = {};
|
|
33968
|
+
const stripped = { ...message };
|
|
33969
|
+
let hasPlaintext = false;
|
|
33970
|
+
for (const field of fields) {
|
|
33971
|
+
if (Object.prototype.hasOwnProperty.call(stripped, field) && stripped[field] !== void 0) {
|
|
33972
|
+
plaintext[field] = stripped[field];
|
|
33973
|
+
delete stripped[field];
|
|
33974
|
+
hasPlaintext = true;
|
|
33975
|
+
}
|
|
33976
|
+
}
|
|
33977
|
+
if (!hasPlaintext) return message;
|
|
33978
|
+
stripped.ee = encryptObject(stripped, plaintext);
|
|
33979
|
+
return stripped;
|
|
33980
|
+
},
|
|
33981
|
+
decryptMessage(message) {
|
|
33982
|
+
const envelope = message.ee;
|
|
33983
|
+
if (!isE2eeEnvelope(envelope)) return message;
|
|
33984
|
+
if (envelope.k !== key.id) throw new Error(`E2EE key mismatch: ${envelope.k}`);
|
|
33985
|
+
const sealed = Buffer.from(base64UrlDecode(envelope.c));
|
|
33986
|
+
if (sealed.length < 16) throw new Error("Invalid E2EE payload.");
|
|
33987
|
+
const ciphertext = sealed.subarray(0, sealed.length - 16);
|
|
33988
|
+
const tag = sealed.subarray(sealed.length - 16);
|
|
33989
|
+
const nonce = Buffer.from(base64UrlDecode(envelope.n));
|
|
33990
|
+
const decipher = createDecipheriv("aes-256-gcm", rawKey, nonce);
|
|
33991
|
+
decipher.setAuthTag(tag);
|
|
33992
|
+
const decrypted = Buffer.concat([decipher.update(ciphertext), decipher.final()]).toString("utf8");
|
|
33993
|
+
const parsed = JSON.parse(decrypted);
|
|
33994
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
33995
|
+
throw new Error("E2EE payload did not decode to an object.");
|
|
33996
|
+
}
|
|
33997
|
+
const merged = { ...message, ...parsed };
|
|
33998
|
+
delete merged.ee;
|
|
33999
|
+
return merged;
|
|
34000
|
+
}
|
|
34001
|
+
};
|
|
34002
|
+
}
|
|
34003
|
+
|
|
33308
34004
|
// src/bridge/connection/create-bridge-connection.ts
|
|
33309
34005
|
async function createBridgeConnection(options) {
|
|
33310
34006
|
const { apiUrl, workspaceId, justAuthenticated, onAuthInvalid, persistTokens } = options;
|
|
@@ -33338,7 +34034,8 @@ async function createBridgeConnection(options) {
|
|
|
33338
34034
|
function getWs() {
|
|
33339
34035
|
return state.currentWs;
|
|
33340
34036
|
}
|
|
33341
|
-
const
|
|
34037
|
+
const e2ee = options.e2eCertificate ? createCliE2eeRuntime(options.e2eCertificate) : void 0;
|
|
34038
|
+
const devServerManager = new DevServerManager({ getWs, log: logFn, getBridgeCwd: getBridgeWorkspaceDirectory, e2ee });
|
|
33342
34039
|
const onBridgeIdentified = createOnBridgeIdentified({
|
|
33343
34040
|
sessionWorktreeManager,
|
|
33344
34041
|
devServerManager,
|
|
@@ -33357,7 +34054,8 @@ async function createBridgeConnection(options) {
|
|
|
33357
34054
|
onBridgeIdentified,
|
|
33358
34055
|
sendLocalSkillsReport,
|
|
33359
34056
|
reportAutoDetectedAgents,
|
|
33360
|
-
devServerManager
|
|
34057
|
+
devServerManager,
|
|
34058
|
+
e2ee
|
|
33361
34059
|
};
|
|
33362
34060
|
const { connect } = createMainBridgeWebSocketLifecycle({
|
|
33363
34061
|
state,
|
|
@@ -33369,7 +34067,8 @@ async function createBridgeConnection(options) {
|
|
|
33369
34067
|
messageDeps,
|
|
33370
34068
|
tokens,
|
|
33371
34069
|
persistTokens,
|
|
33372
|
-
onAuthInvalid
|
|
34070
|
+
onAuthInvalid,
|
|
34071
|
+
e2ee
|
|
33373
34072
|
});
|
|
33374
34073
|
connect();
|
|
33375
34074
|
const stopFileIndexWatcher = startFileIndexWatcher(getBridgeWorkspaceDirectory());
|
|
@@ -33381,56 +34080,72 @@ async function createBridgeConnection(options) {
|
|
|
33381
34080
|
};
|
|
33382
34081
|
}
|
|
33383
34082
|
|
|
33384
|
-
// src/
|
|
33385
|
-
|
|
33386
|
-
|
|
33387
|
-
|
|
33388
|
-
|
|
33389
|
-
|
|
33390
|
-
|
|
33391
|
-
|
|
33392
|
-
|
|
33393
|
-
|
|
33394
|
-
preferredBridgeName: bridgeName,
|
|
33395
|
-
log,
|
|
33396
|
-
onAuth: (_auth) => {
|
|
33397
|
-
}
|
|
33398
|
-
});
|
|
33399
|
-
const onSignal2 = (kind) => {
|
|
33400
|
-
logImmediate(
|
|
33401
|
-
kind === "interrupt" ? "Keyboard interrupt (Ctrl+C) \u2014 stopping\u2026" : "Stop requested \u2014 shutting down\u2026"
|
|
33402
|
-
);
|
|
33403
|
-
setImmediate(() => {
|
|
33404
|
-
handle2.close();
|
|
33405
|
-
process.exit(0);
|
|
33406
|
-
});
|
|
34083
|
+
// src/e2e-certificates/key-command.ts
|
|
34084
|
+
import * as readline3 from "node:readline";
|
|
34085
|
+
function installE2eCertificateKeyCommand({
|
|
34086
|
+
log: log2,
|
|
34087
|
+
onOpenCertificate,
|
|
34088
|
+
onInterrupt
|
|
34089
|
+
}) {
|
|
34090
|
+
if (!process.stdin.isTTY || typeof process.stdin.setRawMode !== "function") {
|
|
34091
|
+
log2("[E2EE] Press c to import the E2EE key in a browser when running in an interactive terminal.");
|
|
34092
|
+
return () => {
|
|
33407
34093
|
};
|
|
33408
|
-
const onSigInt2 = () => onSignal2("interrupt");
|
|
33409
|
-
const onSigTerm2 = () => onSignal2("stop");
|
|
33410
|
-
process.on("SIGINT", onSigInt2);
|
|
33411
|
-
process.on("SIGTERM", onSigTerm2);
|
|
33412
|
-
const auth = await handle2.authPromise;
|
|
33413
|
-
process.off("SIGINT", onSigInt2);
|
|
33414
|
-
process.off("SIGTERM", onSigTerm2);
|
|
33415
|
-
handle2.close();
|
|
33416
|
-
if (!auth) return;
|
|
33417
|
-
writeConfigForApi(apiUrl, {
|
|
33418
|
-
workspaceId: auth.workspaceId,
|
|
33419
|
-
token: auth.token,
|
|
33420
|
-
refreshToken: auth.refreshToken
|
|
33421
|
-
});
|
|
33422
|
-
await runBridge({
|
|
33423
|
-
apiUrl,
|
|
33424
|
-
workspaceId: auth.workspaceId,
|
|
33425
|
-
authToken: auth.token,
|
|
33426
|
-
refreshToken: auth.refreshToken,
|
|
33427
|
-
firehoseServerUrl,
|
|
33428
|
-
bridgeName,
|
|
33429
|
-
justAuthenticated: true,
|
|
33430
|
-
worktreesRootAbs
|
|
33431
|
-
});
|
|
33432
|
-
return;
|
|
33433
34094
|
}
|
|
34095
|
+
readline3.emitKeypressEvents(process.stdin);
|
|
34096
|
+
process.stdin.setRawMode(true);
|
|
34097
|
+
process.stdin.resume();
|
|
34098
|
+
const onKeypress = (str, key) => {
|
|
34099
|
+
if (key?.ctrl && key.name === "c") {
|
|
34100
|
+
onInterrupt();
|
|
34101
|
+
return;
|
|
34102
|
+
}
|
|
34103
|
+
if (!key?.ctrl && !key?.meta && (key?.name === "c" || str === "c")) {
|
|
34104
|
+
onOpenCertificate();
|
|
34105
|
+
}
|
|
34106
|
+
};
|
|
34107
|
+
process.stdin.on("keypress", onKeypress);
|
|
34108
|
+
log2("[E2EE] Press c to import the active E2EE key into the browser.");
|
|
34109
|
+
return () => {
|
|
34110
|
+
process.stdin.off("keypress", onKeypress);
|
|
34111
|
+
if (process.stdin.isTTY && typeof process.stdin.setRawMode === "function") {
|
|
34112
|
+
process.stdin.setRawMode(false);
|
|
34113
|
+
}
|
|
34114
|
+
};
|
|
34115
|
+
}
|
|
34116
|
+
|
|
34117
|
+
// src/e2e-certificates/open-import-url.ts
|
|
34118
|
+
async function openE2eCertificateImportUrl({
|
|
34119
|
+
apiUrl,
|
|
34120
|
+
workspaceId,
|
|
34121
|
+
certificate,
|
|
34122
|
+
log: log2
|
|
34123
|
+
}) {
|
|
34124
|
+
const appUrl = appUrlForApiUrl(apiUrl);
|
|
34125
|
+
const payload = encodeURIComponent(certificate.pemBundle);
|
|
34126
|
+
const url2 = `${appUrl.replace(/\/$/, "")}/w/${encodeURIComponent(workspaceId)}/settings/e2e-encryption?certificate=${payload}`;
|
|
34127
|
+
log2(`[E2EE] Opening browser to import key "${certificate.name}" (${certificate.id})...`);
|
|
34128
|
+
try {
|
|
34129
|
+
await open_default(url2, { wait: false });
|
|
34130
|
+
} catch {
|
|
34131
|
+
log2("[E2EE] Could not open browser. Open this URL manually:");
|
|
34132
|
+
log2(url2);
|
|
34133
|
+
}
|
|
34134
|
+
}
|
|
34135
|
+
|
|
34136
|
+
// src/run-bridge-connected.ts
|
|
34137
|
+
async function runConnectedBridge(options, restartWithoutAuth) {
|
|
34138
|
+
const {
|
|
34139
|
+
apiUrl,
|
|
34140
|
+
workspaceId,
|
|
34141
|
+
authToken,
|
|
34142
|
+
refreshToken,
|
|
34143
|
+
justAuthenticated,
|
|
34144
|
+
worktreesRootAbs,
|
|
34145
|
+
e2eCertificate
|
|
34146
|
+
} = options;
|
|
34147
|
+
const firehoseServerUrl = options.firehoseServerUrl ?? options.proxyServerUrl;
|
|
34148
|
+
let cleanupKeyCommand;
|
|
33434
34149
|
const handle = await createBridgeConnection({
|
|
33435
34150
|
apiUrl,
|
|
33436
34151
|
workspaceId,
|
|
@@ -33439,6 +34154,7 @@ async function runBridge(options) {
|
|
|
33439
34154
|
firehoseServerUrl,
|
|
33440
34155
|
justAuthenticated,
|
|
33441
34156
|
worktreesRootAbs,
|
|
34157
|
+
e2eCertificate,
|
|
33442
34158
|
log,
|
|
33443
34159
|
persistTokens: (t) => {
|
|
33444
34160
|
writeConfigForApi(apiUrl, {
|
|
@@ -33448,14 +34164,16 @@ async function runBridge(options) {
|
|
|
33448
34164
|
});
|
|
33449
34165
|
},
|
|
33450
34166
|
onAuthInvalid: () => {
|
|
34167
|
+
cleanupKeyCommand?.();
|
|
33451
34168
|
log("[Bridge service] Access token invalid or revoked; re-authenticating\u2026");
|
|
33452
34169
|
clearConfigForApi(apiUrl);
|
|
33453
34170
|
void handle.close().then(() => {
|
|
33454
|
-
void
|
|
34171
|
+
void restartWithoutAuth({ apiUrl, firehoseServerUrl, worktreesRootAbs, e2eCertificate });
|
|
33455
34172
|
});
|
|
33456
34173
|
}
|
|
33457
34174
|
});
|
|
33458
34175
|
const onSignal = (kind) => {
|
|
34176
|
+
cleanupKeyCommand?.();
|
|
33459
34177
|
logImmediate(
|
|
33460
34178
|
kind === "interrupt" ? "Keyboard interrupt (Ctrl+C) \u2014 stopping\u2026" : "Stop requested \u2014 shutting down\u2026"
|
|
33461
34179
|
);
|
|
@@ -33469,6 +34187,86 @@ async function runBridge(options) {
|
|
|
33469
34187
|
const onSigTerm = () => onSignal("stop");
|
|
33470
34188
|
process.on("SIGINT", onSigInt);
|
|
33471
34189
|
process.on("SIGTERM", onSigTerm);
|
|
34190
|
+
if (e2eCertificate) {
|
|
34191
|
+
let openingCertificate = false;
|
|
34192
|
+
cleanupKeyCommand = installE2eCertificateKeyCommand({
|
|
34193
|
+
log,
|
|
34194
|
+
onInterrupt: onSigInt,
|
|
34195
|
+
onOpenCertificate: () => {
|
|
34196
|
+
if (openingCertificate) return;
|
|
34197
|
+
openingCertificate = true;
|
|
34198
|
+
void openE2eCertificateImportUrl({
|
|
34199
|
+
apiUrl,
|
|
34200
|
+
workspaceId,
|
|
34201
|
+
certificate: e2eCertificate,
|
|
34202
|
+
log
|
|
34203
|
+
}).finally(() => {
|
|
34204
|
+
openingCertificate = false;
|
|
34205
|
+
});
|
|
34206
|
+
}
|
|
34207
|
+
});
|
|
34208
|
+
}
|
|
34209
|
+
}
|
|
34210
|
+
|
|
34211
|
+
// src/run-bridge.ts
|
|
34212
|
+
async function runBridge(options) {
|
|
34213
|
+
installBridgeProcessResilience();
|
|
34214
|
+
const {
|
|
34215
|
+
apiUrl,
|
|
34216
|
+
workspaceId,
|
|
34217
|
+
authToken,
|
|
34218
|
+
bridgeName,
|
|
34219
|
+
worktreesRootAbs,
|
|
34220
|
+
e2eCertificate
|
|
34221
|
+
} = options;
|
|
34222
|
+
const firehoseServerUrl = options.firehoseServerUrl ?? options.proxyServerUrl;
|
|
34223
|
+
const hasAuth = workspaceId && authToken;
|
|
34224
|
+
if (!hasAuth) {
|
|
34225
|
+
const handle = runPendingAuth({
|
|
34226
|
+
apiUrl,
|
|
34227
|
+
initialWorkspaceId: workspaceId,
|
|
34228
|
+
preferredBridgeName: bridgeName,
|
|
34229
|
+
log,
|
|
34230
|
+
onAuth: (_auth) => {
|
|
34231
|
+
}
|
|
34232
|
+
});
|
|
34233
|
+
const onSignal = (kind) => {
|
|
34234
|
+
logImmediate(
|
|
34235
|
+
kind === "interrupt" ? "Keyboard interrupt (Ctrl+C) \u2014 stopping\u2026" : "Stop requested \u2014 shutting down\u2026"
|
|
34236
|
+
);
|
|
34237
|
+
setImmediate(() => {
|
|
34238
|
+
handle.close();
|
|
34239
|
+
process.exit(0);
|
|
34240
|
+
});
|
|
34241
|
+
};
|
|
34242
|
+
const onSigInt = () => onSignal("interrupt");
|
|
34243
|
+
const onSigTerm = () => onSignal("stop");
|
|
34244
|
+
process.on("SIGINT", onSigInt);
|
|
34245
|
+
process.on("SIGTERM", onSigTerm);
|
|
34246
|
+
const auth = await handle.authPromise;
|
|
34247
|
+
process.off("SIGINT", onSigInt);
|
|
34248
|
+
process.off("SIGTERM", onSigTerm);
|
|
34249
|
+
handle.close();
|
|
34250
|
+
if (!auth) return;
|
|
34251
|
+
writeConfigForApi(apiUrl, {
|
|
34252
|
+
workspaceId: auth.workspaceId,
|
|
34253
|
+
token: auth.token,
|
|
34254
|
+
refreshToken: auth.refreshToken
|
|
34255
|
+
});
|
|
34256
|
+
await runBridge({
|
|
34257
|
+
apiUrl,
|
|
34258
|
+
workspaceId: auth.workspaceId,
|
|
34259
|
+
authToken: auth.token,
|
|
34260
|
+
refreshToken: auth.refreshToken,
|
|
34261
|
+
firehoseServerUrl,
|
|
34262
|
+
bridgeName,
|
|
34263
|
+
justAuthenticated: true,
|
|
34264
|
+
worktreesRootAbs,
|
|
34265
|
+
e2eCertificate
|
|
34266
|
+
});
|
|
34267
|
+
return;
|
|
34268
|
+
}
|
|
34269
|
+
await runConnectedBridge(options, runBridge);
|
|
33472
34270
|
}
|
|
33473
34271
|
export {
|
|
33474
34272
|
callSkill,
|