@buildautomaton/cli 0.1.17 → 0.1.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +474 -257
- package/dist/cli.js.map +4 -4
- package/dist/index.js +431 -234
- package/dist/index.js.map +4 -4
- package/package.json +3 -3
package/dist/cli.js
CHANGED
|
@@ -973,8 +973,8 @@ var require_command = __commonJS({
|
|
|
973
973
|
"../../node_modules/.pnpm/commander@12.1.0/node_modules/commander/lib/command.js"(exports) {
|
|
974
974
|
var EventEmitter2 = __require("node:events").EventEmitter;
|
|
975
975
|
var childProcess2 = __require("node:child_process");
|
|
976
|
-
var
|
|
977
|
-
var
|
|
976
|
+
var path36 = __require("node:path");
|
|
977
|
+
var fs32 = __require("node:fs");
|
|
978
978
|
var process8 = __require("node:process");
|
|
979
979
|
var { Argument: Argument2, humanReadableArgName } = require_argument();
|
|
980
980
|
var { CommanderError: CommanderError2 } = require_error();
|
|
@@ -1906,11 +1906,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1906
1906
|
let launchWithNode = false;
|
|
1907
1907
|
const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
|
|
1908
1908
|
function findFile(baseDir, baseName) {
|
|
1909
|
-
const localBin =
|
|
1910
|
-
if (
|
|
1911
|
-
if (sourceExt.includes(
|
|
1909
|
+
const localBin = path36.resolve(baseDir, baseName);
|
|
1910
|
+
if (fs32.existsSync(localBin)) return localBin;
|
|
1911
|
+
if (sourceExt.includes(path36.extname(baseName))) return void 0;
|
|
1912
1912
|
const foundExt = sourceExt.find(
|
|
1913
|
-
(ext) =>
|
|
1913
|
+
(ext) => fs32.existsSync(`${localBin}${ext}`)
|
|
1914
1914
|
);
|
|
1915
1915
|
if (foundExt) return `${localBin}${foundExt}`;
|
|
1916
1916
|
return void 0;
|
|
@@ -1922,21 +1922,21 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1922
1922
|
if (this._scriptPath) {
|
|
1923
1923
|
let resolvedScriptPath;
|
|
1924
1924
|
try {
|
|
1925
|
-
resolvedScriptPath =
|
|
1925
|
+
resolvedScriptPath = fs32.realpathSync(this._scriptPath);
|
|
1926
1926
|
} catch (err) {
|
|
1927
1927
|
resolvedScriptPath = this._scriptPath;
|
|
1928
1928
|
}
|
|
1929
|
-
executableDir =
|
|
1930
|
-
|
|
1929
|
+
executableDir = path36.resolve(
|
|
1930
|
+
path36.dirname(resolvedScriptPath),
|
|
1931
1931
|
executableDir
|
|
1932
1932
|
);
|
|
1933
1933
|
}
|
|
1934
1934
|
if (executableDir) {
|
|
1935
1935
|
let localFile = findFile(executableDir, executableFile);
|
|
1936
1936
|
if (!localFile && !subcommand._executableFile && this._scriptPath) {
|
|
1937
|
-
const legacyName =
|
|
1937
|
+
const legacyName = path36.basename(
|
|
1938
1938
|
this._scriptPath,
|
|
1939
|
-
|
|
1939
|
+
path36.extname(this._scriptPath)
|
|
1940
1940
|
);
|
|
1941
1941
|
if (legacyName !== this._name) {
|
|
1942
1942
|
localFile = findFile(
|
|
@@ -1947,7 +1947,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1947
1947
|
}
|
|
1948
1948
|
executableFile = localFile || executableFile;
|
|
1949
1949
|
}
|
|
1950
|
-
launchWithNode = sourceExt.includes(
|
|
1950
|
+
launchWithNode = sourceExt.includes(path36.extname(executableFile));
|
|
1951
1951
|
let proc;
|
|
1952
1952
|
if (process8.platform !== "win32") {
|
|
1953
1953
|
if (launchWithNode) {
|
|
@@ -2787,7 +2787,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2787
2787
|
* @return {Command}
|
|
2788
2788
|
*/
|
|
2789
2789
|
nameFromFilename(filename) {
|
|
2790
|
-
this._name =
|
|
2790
|
+
this._name = path36.basename(filename, path36.extname(filename));
|
|
2791
2791
|
return this;
|
|
2792
2792
|
}
|
|
2793
2793
|
/**
|
|
@@ -2801,9 +2801,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2801
2801
|
* @param {string} [path]
|
|
2802
2802
|
* @return {(string|null|Command)}
|
|
2803
2803
|
*/
|
|
2804
|
-
executableDir(
|
|
2805
|
-
if (
|
|
2806
|
-
this._executableDir =
|
|
2804
|
+
executableDir(path37) {
|
|
2805
|
+
if (path37 === void 0) return this._executableDir;
|
|
2806
|
+
this._executableDir = path37;
|
|
2807
2807
|
return this;
|
|
2808
2808
|
}
|
|
2809
2809
|
/**
|
|
@@ -7423,10 +7423,10 @@ var require_src2 = __commonJS({
|
|
|
7423
7423
|
var fs_1 = __require("fs");
|
|
7424
7424
|
var debug_1 = __importDefault(require_src());
|
|
7425
7425
|
var log2 = debug_1.default("@kwsites/file-exists");
|
|
7426
|
-
function check2(
|
|
7427
|
-
log2(`checking %s`,
|
|
7426
|
+
function check2(path36, isFile, isDirectory) {
|
|
7427
|
+
log2(`checking %s`, path36);
|
|
7428
7428
|
try {
|
|
7429
|
-
const stat3 = fs_1.statSync(
|
|
7429
|
+
const stat3 = fs_1.statSync(path36);
|
|
7430
7430
|
if (stat3.isFile() && isFile) {
|
|
7431
7431
|
log2(`[OK] path represents a file`);
|
|
7432
7432
|
return true;
|
|
@@ -7446,8 +7446,8 @@ var require_src2 = __commonJS({
|
|
|
7446
7446
|
throw e;
|
|
7447
7447
|
}
|
|
7448
7448
|
}
|
|
7449
|
-
function exists2(
|
|
7450
|
-
return check2(
|
|
7449
|
+
function exists2(path36, type = exports.READABLE) {
|
|
7450
|
+
return check2(path36, (type & exports.FILE) > 0, (type & exports.FOLDER) > 0);
|
|
7451
7451
|
}
|
|
7452
7452
|
exports.exists = exists2;
|
|
7453
7453
|
exports.FILE = 1;
|
|
@@ -7922,8 +7922,8 @@ var init_parseUtil = __esm({
|
|
|
7922
7922
|
init_errors();
|
|
7923
7923
|
init_en();
|
|
7924
7924
|
makeIssue = (params) => {
|
|
7925
|
-
const { data, path:
|
|
7926
|
-
const fullPath = [...
|
|
7925
|
+
const { data, path: path36, errorMaps, issueData } = params;
|
|
7926
|
+
const fullPath = [...path36, ...issueData.path || []];
|
|
7927
7927
|
const fullIssue = {
|
|
7928
7928
|
...issueData,
|
|
7929
7929
|
path: fullPath
|
|
@@ -8231,11 +8231,11 @@ var init_types = __esm({
|
|
|
8231
8231
|
init_parseUtil();
|
|
8232
8232
|
init_util2();
|
|
8233
8233
|
ParseInputLazyPath = class {
|
|
8234
|
-
constructor(parent, value,
|
|
8234
|
+
constructor(parent, value, path36, key) {
|
|
8235
8235
|
this._cachedPath = [];
|
|
8236
8236
|
this.parent = parent;
|
|
8237
8237
|
this.data = value;
|
|
8238
|
-
this._path =
|
|
8238
|
+
this._path = path36;
|
|
8239
8239
|
this._key = key;
|
|
8240
8240
|
}
|
|
8241
8241
|
get path() {
|
|
@@ -11850,10 +11850,10 @@ function assignProp(target, prop, value) {
|
|
|
11850
11850
|
configurable: true
|
|
11851
11851
|
});
|
|
11852
11852
|
}
|
|
11853
|
-
function getElementAtPath(obj,
|
|
11854
|
-
if (!
|
|
11853
|
+
function getElementAtPath(obj, path36) {
|
|
11854
|
+
if (!path36)
|
|
11855
11855
|
return obj;
|
|
11856
|
-
return
|
|
11856
|
+
return path36.reduce((acc, key) => acc?.[key], obj);
|
|
11857
11857
|
}
|
|
11858
11858
|
function promiseAllObject(promisesObj) {
|
|
11859
11859
|
const keys = Object.keys(promisesObj);
|
|
@@ -12102,11 +12102,11 @@ function aborted(x, startIndex = 0) {
|
|
|
12102
12102
|
}
|
|
12103
12103
|
return false;
|
|
12104
12104
|
}
|
|
12105
|
-
function prefixIssues(
|
|
12105
|
+
function prefixIssues(path36, issues) {
|
|
12106
12106
|
return issues.map((iss) => {
|
|
12107
12107
|
var _a2;
|
|
12108
12108
|
(_a2 = iss).path ?? (_a2.path = []);
|
|
12109
|
-
iss.path.unshift(
|
|
12109
|
+
iss.path.unshift(path36);
|
|
12110
12110
|
return iss;
|
|
12111
12111
|
});
|
|
12112
12112
|
}
|
|
@@ -12295,7 +12295,7 @@ function treeifyError(error40, _mapper) {
|
|
|
12295
12295
|
return issue2.message;
|
|
12296
12296
|
};
|
|
12297
12297
|
const result = { errors: [] };
|
|
12298
|
-
const processError = (error41,
|
|
12298
|
+
const processError = (error41, path36 = []) => {
|
|
12299
12299
|
var _a2, _b;
|
|
12300
12300
|
for (const issue2 of error41.issues) {
|
|
12301
12301
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
@@ -12305,7 +12305,7 @@ function treeifyError(error40, _mapper) {
|
|
|
12305
12305
|
} else if (issue2.code === "invalid_element") {
|
|
12306
12306
|
processError({ issues: issue2.issues }, issue2.path);
|
|
12307
12307
|
} else {
|
|
12308
|
-
const fullpath = [...
|
|
12308
|
+
const fullpath = [...path36, ...issue2.path];
|
|
12309
12309
|
if (fullpath.length === 0) {
|
|
12310
12310
|
result.errors.push(mapper(issue2));
|
|
12311
12311
|
continue;
|
|
@@ -12335,9 +12335,9 @@ function treeifyError(error40, _mapper) {
|
|
|
12335
12335
|
processError(error40);
|
|
12336
12336
|
return result;
|
|
12337
12337
|
}
|
|
12338
|
-
function toDotPath(
|
|
12338
|
+
function toDotPath(path36) {
|
|
12339
12339
|
const segs = [];
|
|
12340
|
-
for (const seg of
|
|
12340
|
+
for (const seg of path36) {
|
|
12341
12341
|
if (typeof seg === "number")
|
|
12342
12342
|
segs.push(`[${seg}]`);
|
|
12343
12343
|
else if (typeof seg === "symbol")
|
|
@@ -24800,8 +24800,8 @@ var init_acp = __esm({
|
|
|
24800
24800
|
this.#requestHandler = requestHandler;
|
|
24801
24801
|
this.#notificationHandler = notificationHandler;
|
|
24802
24802
|
this.#stream = stream;
|
|
24803
|
-
this.#closedPromise = new Promise((
|
|
24804
|
-
this.#abortController.signal.addEventListener("abort", () =>
|
|
24803
|
+
this.#closedPromise = new Promise((resolve19) => {
|
|
24804
|
+
this.#abortController.signal.addEventListener("abort", () => resolve19());
|
|
24805
24805
|
});
|
|
24806
24806
|
this.#receive();
|
|
24807
24807
|
}
|
|
@@ -24950,8 +24950,8 @@ var init_acp = __esm({
|
|
|
24950
24950
|
}
|
|
24951
24951
|
async sendRequest(method, params) {
|
|
24952
24952
|
const id = this.#nextRequestId++;
|
|
24953
|
-
const responsePromise = new Promise((
|
|
24954
|
-
this.#pendingResponses.set(id, { resolve:
|
|
24953
|
+
const responsePromise = new Promise((resolve19, reject) => {
|
|
24954
|
+
this.#pendingResponses.set(id, { resolve: resolve19, reject });
|
|
24955
24955
|
});
|
|
24956
24956
|
await this.#sendMessage({ jsonrpc: "2.0", id, method, params });
|
|
24957
24957
|
return responsePromise;
|
|
@@ -25063,13 +25063,16 @@ var {
|
|
|
25063
25063
|
Help
|
|
25064
25064
|
} = import_index.default;
|
|
25065
25065
|
|
|
25066
|
+
// src/cli-version.ts
|
|
25067
|
+
var CLI_VERSION = "0.1.19".length > 0 ? "0.1.19" : "0.0.0-dev";
|
|
25068
|
+
|
|
25066
25069
|
// src/cli/defaults.ts
|
|
25067
25070
|
var DEFAULT_API_URL = process.env.BUILDAUTOMATON_API_URL ?? "https://api.buildautomaton.com";
|
|
25068
25071
|
var DEFAULT_FIREHOSE_URL = "https://buildautomaton-firehose.fly.dev";
|
|
25069
25072
|
|
|
25070
25073
|
// src/cli/run-cli-action.ts
|
|
25071
|
-
import * as
|
|
25072
|
-
import * as
|
|
25074
|
+
import * as fs31 from "node:fs";
|
|
25075
|
+
import * as path35 from "node:path";
|
|
25073
25076
|
|
|
25074
25077
|
// src/config.ts
|
|
25075
25078
|
import fs from "node:fs";
|
|
@@ -26034,14 +26037,14 @@ var baseOpen = async (options) => {
|
|
|
26034
26037
|
}
|
|
26035
26038
|
const subprocess = childProcess.spawn(command, cliArguments, childProcessOptions);
|
|
26036
26039
|
if (options.wait) {
|
|
26037
|
-
return new Promise((
|
|
26040
|
+
return new Promise((resolve19, reject) => {
|
|
26038
26041
|
subprocess.once("error", reject);
|
|
26039
26042
|
subprocess.once("close", (exitCode) => {
|
|
26040
26043
|
if (!options.allowNonzeroExitCode && exitCode > 0) {
|
|
26041
26044
|
reject(new Error(`Exited with code ${exitCode}`));
|
|
26042
26045
|
return;
|
|
26043
26046
|
}
|
|
26044
|
-
|
|
26047
|
+
resolve19(subprocess);
|
|
26045
26048
|
});
|
|
26046
26049
|
});
|
|
26047
26050
|
}
|
|
@@ -26337,8 +26340,8 @@ function runPendingAuth(options) {
|
|
|
26337
26340
|
let hasOpenedBrowser = false;
|
|
26338
26341
|
let resolved = false;
|
|
26339
26342
|
let resolveAuth;
|
|
26340
|
-
const authPromise = new Promise((
|
|
26341
|
-
resolveAuth =
|
|
26343
|
+
const authPromise = new Promise((resolve19) => {
|
|
26344
|
+
resolveAuth = resolve19;
|
|
26342
26345
|
});
|
|
26343
26346
|
let reconnectAttempt = 0;
|
|
26344
26347
|
const signInQuiet = createEmptyReconnectQuietSlot();
|
|
@@ -26390,7 +26393,7 @@ function runPendingAuth(options) {
|
|
|
26390
26393
|
url: url2,
|
|
26391
26394
|
onOpen: () => {
|
|
26392
26395
|
clearQuietOnOpen();
|
|
26393
|
-
sendWsMessage(ws, { type: "identify", role: "cli" });
|
|
26396
|
+
sendWsMessage(ws, { type: "identify", role: "cli", cliVersion: CLI_VERSION });
|
|
26394
26397
|
keepaliveInterval = setInterval(() => {
|
|
26395
26398
|
if (resolved || !ws || ws.readyState !== 1) return;
|
|
26396
26399
|
sendWsMessage(ws, { type: "ping", timestamp: Date.now() });
|
|
@@ -26460,7 +26463,7 @@ function runPendingAuth(options) {
|
|
|
26460
26463
|
async function closeBridgeConnection(state, acpManager, devServerManager, log2) {
|
|
26461
26464
|
const say = log2 ?? logImmediate;
|
|
26462
26465
|
say("Cleaning up connections\u2026");
|
|
26463
|
-
await new Promise((
|
|
26466
|
+
await new Promise((resolve19) => setImmediate(resolve19));
|
|
26464
26467
|
state.closedByUser = true;
|
|
26465
26468
|
clearReconnectQuietTimer(state.mainQuiet);
|
|
26466
26469
|
clearReconnectQuietTimer(state.firehoseQuiet);
|
|
@@ -26582,8 +26585,8 @@ function pathspec(...paths) {
|
|
|
26582
26585
|
cache.set(key, paths);
|
|
26583
26586
|
return key;
|
|
26584
26587
|
}
|
|
26585
|
-
function isPathSpec(
|
|
26586
|
-
return
|
|
26588
|
+
function isPathSpec(path36) {
|
|
26589
|
+
return path36 instanceof String && cache.has(path36);
|
|
26587
26590
|
}
|
|
26588
26591
|
function toPaths(pathSpec) {
|
|
26589
26592
|
return cache.get(pathSpec) || [];
|
|
@@ -26672,8 +26675,8 @@ function toLinesWithContent(input = "", trimmed2 = true, separator = "\n") {
|
|
|
26672
26675
|
function forEachLineWithContent(input, callback) {
|
|
26673
26676
|
return toLinesWithContent(input, true).map((line) => callback(line));
|
|
26674
26677
|
}
|
|
26675
|
-
function folderExists(
|
|
26676
|
-
return (0, import_file_exists.exists)(
|
|
26678
|
+
function folderExists(path36) {
|
|
26679
|
+
return (0, import_file_exists.exists)(path36, import_file_exists.FOLDER);
|
|
26677
26680
|
}
|
|
26678
26681
|
function append(target, item) {
|
|
26679
26682
|
if (Array.isArray(target)) {
|
|
@@ -27077,8 +27080,8 @@ function checkIsRepoRootTask() {
|
|
|
27077
27080
|
commands,
|
|
27078
27081
|
format: "utf-8",
|
|
27079
27082
|
onError,
|
|
27080
|
-
parser(
|
|
27081
|
-
return /^\.(git)?$/.test(
|
|
27083
|
+
parser(path36) {
|
|
27084
|
+
return /^\.(git)?$/.test(path36.trim());
|
|
27082
27085
|
}
|
|
27083
27086
|
};
|
|
27084
27087
|
}
|
|
@@ -27512,11 +27515,11 @@ function parseGrep(grep) {
|
|
|
27512
27515
|
const paths = /* @__PURE__ */ new Set();
|
|
27513
27516
|
const results = {};
|
|
27514
27517
|
forEachLineWithContent(grep, (input) => {
|
|
27515
|
-
const [
|
|
27516
|
-
paths.add(
|
|
27517
|
-
(results[
|
|
27518
|
+
const [path36, line, preview] = input.split(NULL);
|
|
27519
|
+
paths.add(path36);
|
|
27520
|
+
(results[path36] = results[path36] || []).push({
|
|
27518
27521
|
line: asNumber(line),
|
|
27519
|
-
path:
|
|
27522
|
+
path: path36,
|
|
27520
27523
|
preview
|
|
27521
27524
|
});
|
|
27522
27525
|
});
|
|
@@ -28281,14 +28284,14 @@ var init_hash_object = __esm2({
|
|
|
28281
28284
|
init_task();
|
|
28282
28285
|
}
|
|
28283
28286
|
});
|
|
28284
|
-
function parseInit(bare,
|
|
28287
|
+
function parseInit(bare, path36, text) {
|
|
28285
28288
|
const response = String(text).trim();
|
|
28286
28289
|
let result;
|
|
28287
28290
|
if (result = initResponseRegex.exec(response)) {
|
|
28288
|
-
return new InitSummary(bare,
|
|
28291
|
+
return new InitSummary(bare, path36, false, result[1]);
|
|
28289
28292
|
}
|
|
28290
28293
|
if (result = reInitResponseRegex.exec(response)) {
|
|
28291
|
-
return new InitSummary(bare,
|
|
28294
|
+
return new InitSummary(bare, path36, true, result[1]);
|
|
28292
28295
|
}
|
|
28293
28296
|
let gitDir = "";
|
|
28294
28297
|
const tokens = response.split(" ");
|
|
@@ -28299,7 +28302,7 @@ function parseInit(bare, path34, text) {
|
|
|
28299
28302
|
break;
|
|
28300
28303
|
}
|
|
28301
28304
|
}
|
|
28302
|
-
return new InitSummary(bare,
|
|
28305
|
+
return new InitSummary(bare, path36, /^re/i.test(response), gitDir);
|
|
28303
28306
|
}
|
|
28304
28307
|
var InitSummary;
|
|
28305
28308
|
var initResponseRegex;
|
|
@@ -28308,9 +28311,9 @@ var init_InitSummary = __esm2({
|
|
|
28308
28311
|
"src/lib/responses/InitSummary.ts"() {
|
|
28309
28312
|
"use strict";
|
|
28310
28313
|
InitSummary = class {
|
|
28311
|
-
constructor(bare,
|
|
28314
|
+
constructor(bare, path36, existing, gitDir) {
|
|
28312
28315
|
this.bare = bare;
|
|
28313
|
-
this.path =
|
|
28316
|
+
this.path = path36;
|
|
28314
28317
|
this.existing = existing;
|
|
28315
28318
|
this.gitDir = gitDir;
|
|
28316
28319
|
}
|
|
@@ -28322,7 +28325,7 @@ var init_InitSummary = __esm2({
|
|
|
28322
28325
|
function hasBareCommand(command) {
|
|
28323
28326
|
return command.includes(bareCommand);
|
|
28324
28327
|
}
|
|
28325
|
-
function initTask(bare = false,
|
|
28328
|
+
function initTask(bare = false, path36, customArgs) {
|
|
28326
28329
|
const commands = ["init", ...customArgs];
|
|
28327
28330
|
if (bare && !hasBareCommand(commands)) {
|
|
28328
28331
|
commands.splice(1, 0, bareCommand);
|
|
@@ -28331,7 +28334,7 @@ function initTask(bare = false, path34, customArgs) {
|
|
|
28331
28334
|
commands,
|
|
28332
28335
|
format: "utf-8",
|
|
28333
28336
|
parser(text) {
|
|
28334
|
-
return parseInit(commands.includes("--bare"),
|
|
28337
|
+
return parseInit(commands.includes("--bare"), path36, text);
|
|
28335
28338
|
}
|
|
28336
28339
|
};
|
|
28337
28340
|
}
|
|
@@ -29147,12 +29150,12 @@ var init_FileStatusSummary = __esm2({
|
|
|
29147
29150
|
"use strict";
|
|
29148
29151
|
fromPathRegex = /^(.+)\0(.+)$/;
|
|
29149
29152
|
FileStatusSummary = class {
|
|
29150
|
-
constructor(
|
|
29151
|
-
this.path =
|
|
29153
|
+
constructor(path36, index, working_dir) {
|
|
29154
|
+
this.path = path36;
|
|
29152
29155
|
this.index = index;
|
|
29153
29156
|
this.working_dir = working_dir;
|
|
29154
29157
|
if (index === "R" || working_dir === "R") {
|
|
29155
|
-
const detail = fromPathRegex.exec(
|
|
29158
|
+
const detail = fromPathRegex.exec(path36) || [null, path36, path36];
|
|
29156
29159
|
this.from = detail[2] || "";
|
|
29157
29160
|
this.path = detail[1] || "";
|
|
29158
29161
|
}
|
|
@@ -29183,14 +29186,14 @@ function splitLine(result, lineStr) {
|
|
|
29183
29186
|
default:
|
|
29184
29187
|
return;
|
|
29185
29188
|
}
|
|
29186
|
-
function data(index, workingDir,
|
|
29189
|
+
function data(index, workingDir, path36) {
|
|
29187
29190
|
const raw = `${index}${workingDir}`;
|
|
29188
29191
|
const handler = parsers6.get(raw);
|
|
29189
29192
|
if (handler) {
|
|
29190
|
-
handler(result,
|
|
29193
|
+
handler(result, path36);
|
|
29191
29194
|
}
|
|
29192
29195
|
if (raw !== "##" && raw !== "!!") {
|
|
29193
|
-
result.files.push(new FileStatusSummary(
|
|
29196
|
+
result.files.push(new FileStatusSummary(path36, index, workingDir));
|
|
29194
29197
|
}
|
|
29195
29198
|
}
|
|
29196
29199
|
}
|
|
@@ -29499,9 +29502,9 @@ var init_simple_git_api = __esm2({
|
|
|
29499
29502
|
next
|
|
29500
29503
|
);
|
|
29501
29504
|
}
|
|
29502
|
-
hashObject(
|
|
29505
|
+
hashObject(path36, write) {
|
|
29503
29506
|
return this._runTask(
|
|
29504
|
-
hashObjectTask(
|
|
29507
|
+
hashObjectTask(path36, write === true),
|
|
29505
29508
|
trailingFunctionArgument(arguments)
|
|
29506
29509
|
);
|
|
29507
29510
|
}
|
|
@@ -29854,8 +29857,8 @@ var init_branch = __esm2({
|
|
|
29854
29857
|
}
|
|
29855
29858
|
});
|
|
29856
29859
|
function toPath(input) {
|
|
29857
|
-
const
|
|
29858
|
-
return
|
|
29860
|
+
const path36 = input.trim().replace(/^["']|["']$/g, "");
|
|
29861
|
+
return path36 && normalize(path36);
|
|
29859
29862
|
}
|
|
29860
29863
|
var parseCheckIgnore;
|
|
29861
29864
|
var init_CheckIgnore = __esm2({
|
|
@@ -30169,8 +30172,8 @@ __export2(sub_module_exports, {
|
|
|
30169
30172
|
subModuleTask: () => subModuleTask,
|
|
30170
30173
|
updateSubModuleTask: () => updateSubModuleTask
|
|
30171
30174
|
});
|
|
30172
|
-
function addSubModuleTask(repo,
|
|
30173
|
-
return subModuleTask(["add", repo,
|
|
30175
|
+
function addSubModuleTask(repo, path36) {
|
|
30176
|
+
return subModuleTask(["add", repo, path36]);
|
|
30174
30177
|
}
|
|
30175
30178
|
function initSubModuleTask(customArgs) {
|
|
30176
30179
|
return subModuleTask(["init", ...customArgs]);
|
|
@@ -30503,8 +30506,8 @@ var require_git = __commonJS2({
|
|
|
30503
30506
|
}
|
|
30504
30507
|
return this._runTask(straightThroughStringTask2(command, this._trimmed), next);
|
|
30505
30508
|
};
|
|
30506
|
-
Git2.prototype.submoduleAdd = function(repo,
|
|
30507
|
-
return this._runTask(addSubModuleTask2(repo,
|
|
30509
|
+
Git2.prototype.submoduleAdd = function(repo, path36, then) {
|
|
30510
|
+
return this._runTask(addSubModuleTask2(repo, path36), trailingFunctionArgument2(arguments));
|
|
30508
30511
|
};
|
|
30509
30512
|
Git2.prototype.submoduleUpdate = function(args, then) {
|
|
30510
30513
|
return this._runTask(
|
|
@@ -31636,9 +31639,9 @@ function parseChangeSummaryJson(raw, allowedPaths, options) {
|
|
|
31636
31639
|
const rawPath = typeof o.path === "string" ? o.path.trim() : "";
|
|
31637
31640
|
const summary = typeof o.summary === "string" ? o.summary.trim() : "";
|
|
31638
31641
|
if (!rawPath || !summary) continue;
|
|
31639
|
-
const
|
|
31640
|
-
if (!
|
|
31641
|
-
rows.push({ path:
|
|
31642
|
+
const path36 = skip ? normalizeRepoRelativePath(rawPath) || rawPath : resolveChangeSummaryPathAgainstAllowed(rawPath, allowedPaths);
|
|
31643
|
+
if (!path36) continue;
|
|
31644
|
+
rows.push({ path: path36, summary: clampSummaryToAtMostTwoLines(summary) });
|
|
31642
31645
|
}
|
|
31643
31646
|
return rows;
|
|
31644
31647
|
}
|
|
@@ -31753,9 +31756,9 @@ var GitRepoMetaSchema = external_exports.object({
|
|
|
31753
31756
|
// src/agents/acp/put-summarize-change-summaries.ts
|
|
31754
31757
|
async function putEncryptedChangeSummaryRows(params) {
|
|
31755
31758
|
const base = params.apiBaseUrl.replace(/\/+$/, "");
|
|
31756
|
-
const entries = params.rows.map(({ path:
|
|
31759
|
+
const entries = params.rows.map(({ path: path36, summary }) => {
|
|
31757
31760
|
const enc = params.e2ee.encryptFields({ summary }, ["summary"]);
|
|
31758
|
-
return { path:
|
|
31761
|
+
return { path: path36, summary: JSON.stringify(enc) };
|
|
31759
31762
|
});
|
|
31760
31763
|
const res = await fetch(
|
|
31761
31764
|
`${base}/api/sessions/${encodeURIComponent(params.sessionId)}/follow-ups/summarize-changes`,
|
|
@@ -32154,7 +32157,7 @@ async function createSdkStdioAcpClient(options) {
|
|
|
32154
32157
|
child.once("close", (code, signal) => {
|
|
32155
32158
|
onAgentSubprocessExit?.({ code, signal });
|
|
32156
32159
|
});
|
|
32157
|
-
return new Promise((
|
|
32160
|
+
return new Promise((resolve19, reject) => {
|
|
32158
32161
|
let initSettled = false;
|
|
32159
32162
|
const settleReject = (err) => {
|
|
32160
32163
|
if (initSettled) return;
|
|
@@ -32168,7 +32171,7 @@ async function createSdkStdioAcpClient(options) {
|
|
|
32168
32171
|
const settleResolve = (handle) => {
|
|
32169
32172
|
if (initSettled) return;
|
|
32170
32173
|
initSettled = true;
|
|
32171
|
-
|
|
32174
|
+
resolve19(handle);
|
|
32172
32175
|
};
|
|
32173
32176
|
child.on("error", (err) => {
|
|
32174
32177
|
settleReject(new Error(formatSpawnError(err, command[0])));
|
|
@@ -32204,8 +32207,8 @@ async function createSdkStdioAcpClient(options) {
|
|
|
32204
32207
|
});
|
|
32205
32208
|
} catch {
|
|
32206
32209
|
}
|
|
32207
|
-
return await new Promise((
|
|
32208
|
-
pendingPermissionResolvers.set(requestId,
|
|
32210
|
+
return await new Promise((resolve20) => {
|
|
32211
|
+
pendingPermissionResolvers.set(requestId, resolve20);
|
|
32209
32212
|
});
|
|
32210
32213
|
},
|
|
32211
32214
|
async readTextFile(params) {
|
|
@@ -32313,9 +32316,9 @@ async function createSdkStdioAcpClient(options) {
|
|
|
32313
32316
|
}
|
|
32314
32317
|
},
|
|
32315
32318
|
async cancel() {
|
|
32316
|
-
for (const [id,
|
|
32319
|
+
for (const [id, resolve20] of [...pendingPermissionResolvers.entries()]) {
|
|
32317
32320
|
pendingPermissionResolvers.delete(id);
|
|
32318
|
-
|
|
32321
|
+
resolve20({ outcome: { outcome: "cancelled" } });
|
|
32319
32322
|
}
|
|
32320
32323
|
try {
|
|
32321
32324
|
await connection.cancel({ sessionId });
|
|
@@ -32331,10 +32334,10 @@ async function createSdkStdioAcpClient(options) {
|
|
|
32331
32334
|
}
|
|
32332
32335
|
},
|
|
32333
32336
|
resolveRequest(requestId, result) {
|
|
32334
|
-
const
|
|
32335
|
-
if (!
|
|
32337
|
+
const resolve20 = pendingPermissionResolvers.get(requestId);
|
|
32338
|
+
if (!resolve20) return;
|
|
32336
32339
|
pendingPermissionResolvers.delete(requestId);
|
|
32337
|
-
|
|
32340
|
+
resolve20(result);
|
|
32338
32341
|
},
|
|
32339
32342
|
disconnect() {
|
|
32340
32343
|
child.kill();
|
|
@@ -32485,7 +32488,7 @@ async function createCursorAcpClient(options) {
|
|
|
32485
32488
|
});
|
|
32486
32489
|
const stderrCapture = createStderrCapture(child);
|
|
32487
32490
|
child.stderr?.on("data", (chunk) => stderrCapture.append(chunk));
|
|
32488
|
-
return new Promise((
|
|
32491
|
+
return new Promise((resolve19, reject) => {
|
|
32489
32492
|
child.on("error", (err) => {
|
|
32490
32493
|
child.kill();
|
|
32491
32494
|
reject(new Error(formatSpawnError2(err, command[0])));
|
|
@@ -32672,7 +32675,7 @@ async function createCursorAcpClient(options) {
|
|
|
32672
32675
|
const newResult = await send("session/new", { cwd, mcpServers: [] });
|
|
32673
32676
|
const sessionId = newResult?.sessionId ?? "";
|
|
32674
32677
|
if (!sessionId) throw new Error("Cursor ACP session/new did not return sessionId");
|
|
32675
|
-
|
|
32678
|
+
resolve19({
|
|
32676
32679
|
sessionId,
|
|
32677
32680
|
async sendPrompt(prompt, _options) {
|
|
32678
32681
|
promptOutputBuffer = "";
|
|
@@ -33740,7 +33743,7 @@ async function createAcpManager(options) {
|
|
|
33740
33743
|
}
|
|
33741
33744
|
|
|
33742
33745
|
// src/worktrees/session-worktree-manager.ts
|
|
33743
|
-
import * as
|
|
33746
|
+
import * as path18 from "node:path";
|
|
33744
33747
|
import os4 from "node:os";
|
|
33745
33748
|
|
|
33746
33749
|
// src/worktrees/prepare-new-session-worktrees.ts
|
|
@@ -33789,10 +33792,15 @@ function saveWorktreeLayout(layout) {
|
|
|
33789
33792
|
function baseNameSafe(abs) {
|
|
33790
33793
|
return path12.basename(abs).replace(/[^a-zA-Z0-9._-]+/g, "-") || "cwd";
|
|
33791
33794
|
}
|
|
33792
|
-
function
|
|
33795
|
+
function getLauncherDirNameIfPresent(layout, launcherCwdAbs) {
|
|
33793
33796
|
const norm = path12.resolve(launcherCwdAbs);
|
|
33794
33797
|
const existing = layout.launcherCwds.find((e) => path12.resolve(e.absolutePath) === norm);
|
|
33795
|
-
|
|
33798
|
+
return existing?.dirName;
|
|
33799
|
+
}
|
|
33800
|
+
function allocateDirNameForLauncherCwd(layout, launcherCwdAbs) {
|
|
33801
|
+
const existing = getLauncherDirNameIfPresent(layout, launcherCwdAbs);
|
|
33802
|
+
if (existing) return existing;
|
|
33803
|
+
const norm = path12.resolve(launcherCwdAbs);
|
|
33796
33804
|
const base = baseNameSafe(norm);
|
|
33797
33805
|
const used = new Set(layout.launcherCwds.map((e) => e.dirName));
|
|
33798
33806
|
let name = base;
|
|
@@ -34570,11 +34578,88 @@ async function commitSessionWorktrees(options) {
|
|
|
34570
34578
|
}
|
|
34571
34579
|
}
|
|
34572
34580
|
|
|
34581
|
+
// src/worktrees/discover-session-worktree-on-disk.ts
|
|
34582
|
+
import * as fs18 from "node:fs";
|
|
34583
|
+
import * as path17 from "node:path";
|
|
34584
|
+
function isGitDir(abs) {
|
|
34585
|
+
try {
|
|
34586
|
+
return fs18.existsSync(path17.join(abs, ".git"));
|
|
34587
|
+
} catch {
|
|
34588
|
+
return false;
|
|
34589
|
+
}
|
|
34590
|
+
}
|
|
34591
|
+
function collectWorktreeRootsNamed(root, sessionId, maxDepth) {
|
|
34592
|
+
const out = [];
|
|
34593
|
+
const walk = (dir, depth) => {
|
|
34594
|
+
if (depth > maxDepth) return;
|
|
34595
|
+
let entries;
|
|
34596
|
+
try {
|
|
34597
|
+
entries = fs18.readdirSync(dir, { withFileTypes: true });
|
|
34598
|
+
} catch {
|
|
34599
|
+
return;
|
|
34600
|
+
}
|
|
34601
|
+
for (const e of entries) {
|
|
34602
|
+
if (e.name.startsWith(".")) continue;
|
|
34603
|
+
const full = path17.join(dir, e.name);
|
|
34604
|
+
if (!e.isDirectory()) continue;
|
|
34605
|
+
if (e.name === sessionId) {
|
|
34606
|
+
if (isGitDir(full)) out.push(path17.resolve(full));
|
|
34607
|
+
} else {
|
|
34608
|
+
walk(full, depth + 1);
|
|
34609
|
+
}
|
|
34610
|
+
}
|
|
34611
|
+
};
|
|
34612
|
+
walk(root, 0);
|
|
34613
|
+
return out;
|
|
34614
|
+
}
|
|
34615
|
+
function discoverSessionWorktreeOnDisk(options) {
|
|
34616
|
+
const { sessionId, worktreesRootAbs, layout, launcherCwd } = options;
|
|
34617
|
+
if (!sessionId.trim() || !fs18.existsSync(worktreesRootAbs)) return null;
|
|
34618
|
+
const preferredKey = getLauncherDirNameIfPresent(layout, launcherCwd);
|
|
34619
|
+
const keys = [];
|
|
34620
|
+
if (preferredKey) keys.push(preferredKey);
|
|
34621
|
+
try {
|
|
34622
|
+
for (const name of fs18.readdirSync(worktreesRootAbs)) {
|
|
34623
|
+
if (name.startsWith(".")) continue;
|
|
34624
|
+
const p = path17.join(worktreesRootAbs, name);
|
|
34625
|
+
if (!fs18.statSync(p).isDirectory()) continue;
|
|
34626
|
+
if (name !== preferredKey) keys.push(name);
|
|
34627
|
+
}
|
|
34628
|
+
} catch {
|
|
34629
|
+
return null;
|
|
34630
|
+
}
|
|
34631
|
+
for (const key of keys) {
|
|
34632
|
+
const mirrorRoot = path17.join(worktreesRootAbs, key);
|
|
34633
|
+
if (!fs18.existsSync(mirrorRoot) || !fs18.statSync(mirrorRoot).isDirectory()) continue;
|
|
34634
|
+
const worktreePaths = collectWorktreeRootsNamed(mirrorRoot, sessionId, 24);
|
|
34635
|
+
if (worktreePaths.length > 0) {
|
|
34636
|
+
return { agentCwd: path17.resolve(mirrorRoot), worktreePaths };
|
|
34637
|
+
}
|
|
34638
|
+
}
|
|
34639
|
+
return null;
|
|
34640
|
+
}
|
|
34641
|
+
function discoverSessionWorktreesUnderMirrorRoot(mirrorRootAbs, sessionId) {
|
|
34642
|
+
const mirrorRoot = path17.resolve(mirrorRootAbs);
|
|
34643
|
+
if (!sessionId.trim() || !fs18.existsSync(mirrorRoot)) return null;
|
|
34644
|
+
try {
|
|
34645
|
+
if (!fs18.statSync(mirrorRoot).isDirectory()) return null;
|
|
34646
|
+
} catch {
|
|
34647
|
+
return null;
|
|
34648
|
+
}
|
|
34649
|
+
const worktreePaths = collectWorktreeRootsNamed(mirrorRoot, sessionId, 24);
|
|
34650
|
+
if (worktreePaths.length === 0) return null;
|
|
34651
|
+
return { agentCwd: mirrorRoot, worktreePaths };
|
|
34652
|
+
}
|
|
34653
|
+
|
|
34573
34654
|
// src/worktrees/session-worktree-manager.ts
|
|
34655
|
+
function parseSessionParent(v) {
|
|
34656
|
+
if (v === "bridge_root" || v === "worktrees_root") return v;
|
|
34657
|
+
if (v === "session_worktrees_root") return "worktrees_root";
|
|
34658
|
+
return null;
|
|
34659
|
+
}
|
|
34574
34660
|
var SessionWorktreeManager = class {
|
|
34575
34661
|
rootAbs;
|
|
34576
34662
|
log;
|
|
34577
|
-
bridgeWantsWorktrees = false;
|
|
34578
34663
|
sessionPaths = /* @__PURE__ */ new Map();
|
|
34579
34664
|
sessionAgentCwd = /* @__PURE__ */ new Map();
|
|
34580
34665
|
layout;
|
|
@@ -34583,22 +34668,67 @@ var SessionWorktreeManager = class {
|
|
|
34583
34668
|
this.log = options.log;
|
|
34584
34669
|
this.layout = loadWorktreeLayout();
|
|
34585
34670
|
}
|
|
34586
|
-
|
|
34587
|
-
this.
|
|
34671
|
+
rememberWorktrees(sessionId, agentCwd, worktreePaths) {
|
|
34672
|
+
this.sessionPaths.set(sessionId, worktreePaths);
|
|
34673
|
+
this.sessionAgentCwd.set(sessionId, path18.resolve(agentCwd));
|
|
34588
34674
|
}
|
|
34589
|
-
|
|
34590
|
-
return
|
|
34675
|
+
tryDiscoverFromDisk(sessionId) {
|
|
34676
|
+
return discoverSessionWorktreeOnDisk({
|
|
34677
|
+
sessionId,
|
|
34678
|
+
worktreesRootAbs: this.rootAbs,
|
|
34679
|
+
layout: this.layout,
|
|
34680
|
+
launcherCwd: getBridgeWorkspaceDirectory()
|
|
34681
|
+
});
|
|
34591
34682
|
}
|
|
34592
34683
|
/**
|
|
34593
34684
|
* Returns cwd for the agent (mirror of launcher tree), or undefined to use the bridge workspace directory.
|
|
34594
34685
|
*/
|
|
34595
34686
|
async resolveCwdForPrompt(sessionId, opts) {
|
|
34596
|
-
if (!sessionId
|
|
34687
|
+
if (!sessionId) return void 0;
|
|
34688
|
+
const parentPathRaw = opts.sessionParentPath?.trim();
|
|
34689
|
+
if (parentPathRaw) {
|
|
34690
|
+
const agentCwd = path18.resolve(parentPathRaw);
|
|
34691
|
+
const sid = sessionId?.trim();
|
|
34692
|
+
if (sid && parseSessionParent(opts.sessionParent) === "worktrees_root") {
|
|
34693
|
+
const fromMirror = discoverSessionWorktreesUnderMirrorRoot(agentCwd, sid);
|
|
34694
|
+
if (fromMirror) this.rememberWorktrees(sid, fromMirror.agentCwd, fromMirror.worktreePaths);
|
|
34695
|
+
}
|
|
34696
|
+
return agentCwd;
|
|
34697
|
+
}
|
|
34698
|
+
const parentKind = parseSessionParent(opts.sessionParent);
|
|
34699
|
+
if (parentKind === "bridge_root") {
|
|
34597
34700
|
return void 0;
|
|
34598
34701
|
}
|
|
34702
|
+
if (parentKind === "worktrees_root") {
|
|
34703
|
+
if (!opts.isNewSession) {
|
|
34704
|
+
const cached2 = this.sessionAgentCwd.get(sessionId);
|
|
34705
|
+
if (cached2) return path18.resolve(cached2);
|
|
34706
|
+
const disc = this.tryDiscoverFromDisk(sessionId);
|
|
34707
|
+
if (disc) {
|
|
34708
|
+
this.rememberWorktrees(sessionId, disc.agentCwd, disc.worktreePaths);
|
|
34709
|
+
return path18.resolve(disc.agentCwd);
|
|
34710
|
+
}
|
|
34711
|
+
return void 0;
|
|
34712
|
+
}
|
|
34713
|
+
const prep2 = await prepareNewSessionWorktrees({
|
|
34714
|
+
rootAbs: this.rootAbs,
|
|
34715
|
+
launcherCwd: getBridgeWorkspaceDirectory(),
|
|
34716
|
+
sessionId,
|
|
34717
|
+
layout: this.layout,
|
|
34718
|
+
log: this.log
|
|
34719
|
+
});
|
|
34720
|
+
if (!prep2) return void 0;
|
|
34721
|
+
this.rememberWorktrees(sessionId, prep2.agentCwd, prep2.worktreePaths);
|
|
34722
|
+
return path18.resolve(prep2.agentCwd);
|
|
34723
|
+
}
|
|
34599
34724
|
if (!opts.isNewSession) {
|
|
34600
|
-
const
|
|
34601
|
-
if (
|
|
34725
|
+
const cached2 = this.sessionAgentCwd.get(sessionId);
|
|
34726
|
+
if (cached2) return path18.resolve(cached2);
|
|
34727
|
+
const disc = this.tryDiscoverFromDisk(sessionId);
|
|
34728
|
+
if (disc) {
|
|
34729
|
+
this.rememberWorktrees(sessionId, disc.agentCwd, disc.worktreePaths);
|
|
34730
|
+
return path18.resolve(disc.agentCwd);
|
|
34731
|
+
}
|
|
34602
34732
|
return void 0;
|
|
34603
34733
|
}
|
|
34604
34734
|
const prep = await prepareNewSessionWorktrees({
|
|
@@ -34609,9 +34739,8 @@ var SessionWorktreeManager = class {
|
|
|
34609
34739
|
log: this.log
|
|
34610
34740
|
});
|
|
34611
34741
|
if (!prep) return void 0;
|
|
34612
|
-
this.
|
|
34613
|
-
|
|
34614
|
-
return path17.resolve(prep.agentCwd);
|
|
34742
|
+
this.rememberWorktrees(sessionId, prep.agentCwd, prep.worktreePaths);
|
|
34743
|
+
return path18.resolve(prep.agentCwd);
|
|
34615
34744
|
}
|
|
34616
34745
|
async renameSessionBranch(sessionId, newBranch) {
|
|
34617
34746
|
const paths = this.sessionPaths.get(sessionId);
|
|
@@ -34632,7 +34761,7 @@ var SessionWorktreeManager = class {
|
|
|
34632
34761
|
getAgentCwdForSession(sessionId) {
|
|
34633
34762
|
if (!sessionId) return null;
|
|
34634
34763
|
const c = this.sessionAgentCwd.get(sessionId);
|
|
34635
|
-
return c ?
|
|
34764
|
+
return c ? path18.resolve(c) : null;
|
|
34636
34765
|
}
|
|
34637
34766
|
async removeSessionWorktrees(sessionId) {
|
|
34638
34767
|
const paths = this.sessionPaths.get(sessionId);
|
|
@@ -34653,7 +34782,13 @@ var SessionWorktreeManager = class {
|
|
|
34653
34782
|
}
|
|
34654
34783
|
resolveCommitTargets(sessionId) {
|
|
34655
34784
|
const paths = this.sessionPaths.get(sessionId);
|
|
34656
|
-
|
|
34785
|
+
if (paths?.length) return paths;
|
|
34786
|
+
const disc = this.tryDiscoverFromDisk(sessionId);
|
|
34787
|
+
if (disc?.worktreePaths.length) {
|
|
34788
|
+
this.rememberWorktrees(sessionId, disc.agentCwd, disc.worktreePaths);
|
|
34789
|
+
return disc.worktreePaths;
|
|
34790
|
+
}
|
|
34791
|
+
return [getBridgeWorkspaceDirectory()];
|
|
34657
34792
|
}
|
|
34658
34793
|
async getSessionWorkingTreeStatus(sessionId) {
|
|
34659
34794
|
return aggregateSessionPathsWorkingTreeStatus(this.resolveCommitTargets(sessionId));
|
|
@@ -34680,30 +34815,30 @@ var SessionWorktreeManager = class {
|
|
|
34680
34815
|
}
|
|
34681
34816
|
};
|
|
34682
34817
|
function defaultWorktreesRootAbs() {
|
|
34683
|
-
return
|
|
34818
|
+
return path18.join(os4.homedir(), ".buildautomaton", "worktrees");
|
|
34684
34819
|
}
|
|
34685
34820
|
|
|
34686
34821
|
// src/files/watch-file-index.ts
|
|
34687
34822
|
import { watch } from "node:fs";
|
|
34688
|
-
import
|
|
34823
|
+
import path25 from "node:path";
|
|
34689
34824
|
|
|
34690
34825
|
// src/files/index/build-file-index.ts
|
|
34691
|
-
import
|
|
34826
|
+
import path22 from "node:path";
|
|
34692
34827
|
|
|
34693
34828
|
// src/runtime/yield-to-event-loop.ts
|
|
34694
34829
|
function yieldToEventLoop() {
|
|
34695
|
-
return new Promise((
|
|
34830
|
+
return new Promise((resolve19) => setImmediate(resolve19));
|
|
34696
34831
|
}
|
|
34697
34832
|
|
|
34698
34833
|
// src/files/index/walk-workspace-tree.ts
|
|
34699
|
-
import
|
|
34700
|
-
import
|
|
34834
|
+
import fs19 from "node:fs";
|
|
34835
|
+
import path20 from "node:path";
|
|
34701
34836
|
|
|
34702
34837
|
// src/files/index/constants.ts
|
|
34703
|
-
import
|
|
34838
|
+
import path19 from "node:path";
|
|
34704
34839
|
import os5 from "node:os";
|
|
34705
34840
|
var INDEX_WORK_YIELD_EVERY = 256;
|
|
34706
|
-
var INDEX_DIR =
|
|
34841
|
+
var INDEX_DIR = path19.join(os5.homedir(), ".buildautomaton");
|
|
34707
34842
|
var INDEX_HASH_LEN = 16;
|
|
34708
34843
|
var INDEX_VERSION = 2;
|
|
34709
34844
|
var INDEX_LOG_PREFIX = "[file-index]";
|
|
@@ -34712,20 +34847,20 @@ var INDEX_LOG_PREFIX = "[file-index]";
|
|
|
34712
34847
|
function walkWorkspaceTreeSync(dir, baseDir, out) {
|
|
34713
34848
|
let names;
|
|
34714
34849
|
try {
|
|
34715
|
-
names =
|
|
34850
|
+
names = fs19.readdirSync(dir);
|
|
34716
34851
|
} catch {
|
|
34717
34852
|
return;
|
|
34718
34853
|
}
|
|
34719
34854
|
for (const name of names) {
|
|
34720
34855
|
if (name.startsWith(".")) continue;
|
|
34721
|
-
const full =
|
|
34856
|
+
const full = path20.join(dir, name);
|
|
34722
34857
|
let stat3;
|
|
34723
34858
|
try {
|
|
34724
|
-
stat3 =
|
|
34859
|
+
stat3 = fs19.statSync(full);
|
|
34725
34860
|
} catch {
|
|
34726
34861
|
continue;
|
|
34727
34862
|
}
|
|
34728
|
-
const relative5 =
|
|
34863
|
+
const relative5 = path20.relative(baseDir, full).replace(/\\/g, "/");
|
|
34729
34864
|
if (stat3.isDirectory()) {
|
|
34730
34865
|
walkWorkspaceTreeSync(full, baseDir, out);
|
|
34731
34866
|
} else if (stat3.isFile()) {
|
|
@@ -34736,7 +34871,7 @@ function walkWorkspaceTreeSync(dir, baseDir, out) {
|
|
|
34736
34871
|
async function walkWorkspaceTreeAsync(dir, baseDir, out, state) {
|
|
34737
34872
|
let names;
|
|
34738
34873
|
try {
|
|
34739
|
-
names = await
|
|
34874
|
+
names = await fs19.promises.readdir(dir);
|
|
34740
34875
|
} catch {
|
|
34741
34876
|
return;
|
|
34742
34877
|
}
|
|
@@ -34746,14 +34881,14 @@ async function walkWorkspaceTreeAsync(dir, baseDir, out, state) {
|
|
|
34746
34881
|
await yieldToEventLoop();
|
|
34747
34882
|
}
|
|
34748
34883
|
state.n++;
|
|
34749
|
-
const full =
|
|
34884
|
+
const full = path20.join(dir, name);
|
|
34750
34885
|
let stat3;
|
|
34751
34886
|
try {
|
|
34752
|
-
stat3 = await
|
|
34887
|
+
stat3 = await fs19.promises.stat(full);
|
|
34753
34888
|
} catch {
|
|
34754
34889
|
continue;
|
|
34755
34890
|
}
|
|
34756
|
-
const relative5 =
|
|
34891
|
+
const relative5 = path20.relative(baseDir, full).replace(/\\/g, "/");
|
|
34757
34892
|
if (stat3.isDirectory()) {
|
|
34758
34893
|
await walkWorkspaceTreeAsync(full, baseDir, out, state);
|
|
34759
34894
|
} else if (stat3.isFile()) {
|
|
@@ -34834,22 +34969,22 @@ async function buildTrigramMapForPathsAsync(paths) {
|
|
|
34834
34969
|
}
|
|
34835
34970
|
|
|
34836
34971
|
// src/files/index/write-index-file.ts
|
|
34837
|
-
import
|
|
34972
|
+
import fs20 from "node:fs";
|
|
34838
34973
|
|
|
34839
34974
|
// src/files/index/paths.ts
|
|
34840
|
-
import
|
|
34975
|
+
import path21 from "node:path";
|
|
34841
34976
|
import crypto2 from "node:crypto";
|
|
34842
34977
|
function getIndexPathForCwd(resolvedCwd) {
|
|
34843
34978
|
const hash = crypto2.createHash("sha256").update(resolvedCwd).digest("hex").slice(0, INDEX_HASH_LEN);
|
|
34844
|
-
return
|
|
34979
|
+
return path21.join(INDEX_DIR, `.file-index-${hash}.json`);
|
|
34845
34980
|
}
|
|
34846
34981
|
|
|
34847
34982
|
// src/files/index/write-index-file.ts
|
|
34848
34983
|
function writeIndexFileSync(resolvedCwd, data) {
|
|
34849
34984
|
const indexPath = getIndexPathForCwd(resolvedCwd);
|
|
34850
34985
|
try {
|
|
34851
|
-
if (!
|
|
34852
|
-
|
|
34986
|
+
if (!fs20.existsSync(INDEX_DIR)) fs20.mkdirSync(INDEX_DIR, { recursive: true });
|
|
34987
|
+
fs20.writeFileSync(indexPath, JSON.stringify(data), "utf8");
|
|
34853
34988
|
} catch (e) {
|
|
34854
34989
|
console.error(`${INDEX_LOG_PREFIX} Failed to write index:`, e);
|
|
34855
34990
|
}
|
|
@@ -34857,8 +34992,8 @@ function writeIndexFileSync(resolvedCwd, data) {
|
|
|
34857
34992
|
async function writeIndexFileAsync(resolvedCwd, data) {
|
|
34858
34993
|
const indexPath = getIndexPathForCwd(resolvedCwd);
|
|
34859
34994
|
try {
|
|
34860
|
-
await
|
|
34861
|
-
await
|
|
34995
|
+
await fs20.promises.mkdir(INDEX_DIR, { recursive: true });
|
|
34996
|
+
await fs20.promises.writeFile(indexPath, JSON.stringify(data), "utf8");
|
|
34862
34997
|
} catch (e) {
|
|
34863
34998
|
console.error(`${INDEX_LOG_PREFIX} Failed to write index:`, e);
|
|
34864
34999
|
}
|
|
@@ -34872,7 +35007,7 @@ function sortPaths(paths) {
|
|
|
34872
35007
|
paths.sort((a, b) => a.localeCompare(b, void 0, { sensitivity: "base" }));
|
|
34873
35008
|
}
|
|
34874
35009
|
function buildFileIndex(cwd) {
|
|
34875
|
-
const resolved =
|
|
35010
|
+
const resolved = path22.resolve(cwd);
|
|
34876
35011
|
const paths = [];
|
|
34877
35012
|
walkWorkspaceTreeSync(resolved, resolved, paths);
|
|
34878
35013
|
sortPaths(paths);
|
|
@@ -34882,7 +35017,7 @@ function buildFileIndex(cwd) {
|
|
|
34882
35017
|
return data;
|
|
34883
35018
|
}
|
|
34884
35019
|
async function buildFileIndexAsync(cwd) {
|
|
34885
|
-
const resolved =
|
|
35020
|
+
const resolved = path22.resolve(cwd);
|
|
34886
35021
|
const paths = [];
|
|
34887
35022
|
await walkWorkspaceTreeAsync(resolved, resolved, paths, createWalkYieldState());
|
|
34888
35023
|
await yieldToEventLoop();
|
|
@@ -34894,13 +35029,13 @@ async function buildFileIndexAsync(cwd) {
|
|
|
34894
35029
|
}
|
|
34895
35030
|
|
|
34896
35031
|
// src/files/index/load-file-index.ts
|
|
34897
|
-
import
|
|
34898
|
-
import
|
|
35032
|
+
import fs21 from "node:fs";
|
|
35033
|
+
import path23 from "node:path";
|
|
34899
35034
|
function loadFileIndex(cwd) {
|
|
34900
|
-
const resolved =
|
|
35035
|
+
const resolved = path23.resolve(cwd);
|
|
34901
35036
|
const indexPath = getIndexPathForCwd(resolved);
|
|
34902
35037
|
try {
|
|
34903
|
-
const raw =
|
|
35038
|
+
const raw = fs21.readFileSync(indexPath, "utf8");
|
|
34904
35039
|
const parsed = JSON.parse(raw);
|
|
34905
35040
|
if (parsed !== null && typeof parsed === "object" && Array.isArray(parsed.paths)) {
|
|
34906
35041
|
const obj = parsed;
|
|
@@ -34919,9 +35054,9 @@ function loadFileIndex(cwd) {
|
|
|
34919
35054
|
}
|
|
34920
35055
|
|
|
34921
35056
|
// src/files/index/ensure-file-index.ts
|
|
34922
|
-
import
|
|
35057
|
+
import path24 from "node:path";
|
|
34923
35058
|
async function ensureFileIndexAsync(cwd) {
|
|
34924
|
-
const resolved =
|
|
35059
|
+
const resolved = path24.resolve(cwd);
|
|
34925
35060
|
const cached2 = loadFileIndex(resolved);
|
|
34926
35061
|
if (cached2 !== null) return { data: cached2, fromCache: true };
|
|
34927
35062
|
const data = await buildFileIndexAsync(resolved);
|
|
@@ -35004,7 +35139,7 @@ function createFsWatcher(resolved, schedule) {
|
|
|
35004
35139
|
}
|
|
35005
35140
|
}
|
|
35006
35141
|
function startFileIndexWatcher(cwd = getBridgeWorkspaceDirectory()) {
|
|
35007
|
-
const resolved =
|
|
35142
|
+
const resolved = path25.resolve(cwd);
|
|
35008
35143
|
void buildFileIndexAsync(resolved).catch((e) => {
|
|
35009
35144
|
console.error("[file-index] Initial index build failed:", e);
|
|
35010
35145
|
});
|
|
@@ -35031,6 +35166,9 @@ function startFileIndexWatcher(cwd = getBridgeWorkspaceDirectory()) {
|
|
|
35031
35166
|
};
|
|
35032
35167
|
}
|
|
35033
35168
|
|
|
35169
|
+
// src/bridge/connection/create-bridge-connection.ts
|
|
35170
|
+
import * as path34 from "node:path";
|
|
35171
|
+
|
|
35034
35172
|
// src/dev-servers/manager/dev-server-manager.ts
|
|
35035
35173
|
import { rm as rm2 } from "node:fs/promises";
|
|
35036
35174
|
|
|
@@ -35051,15 +35189,15 @@ function sendDevServerStatus(getWs, serverId, status, options) {
|
|
|
35051
35189
|
|
|
35052
35190
|
// src/dev-servers/process/terminate-child-process.ts
|
|
35053
35191
|
async function sigtermAndWaitForExit(proc, graceMs, log2, shortId) {
|
|
35054
|
-
const exited = new Promise((
|
|
35055
|
-
proc.once("exit", () =>
|
|
35192
|
+
const exited = new Promise((resolve19) => {
|
|
35193
|
+
proc.once("exit", () => resolve19());
|
|
35056
35194
|
});
|
|
35057
35195
|
log2(`[dev-server] Sending SIGTERM to ${shortId} (pid=${proc.pid ?? "?"}).`);
|
|
35058
35196
|
try {
|
|
35059
35197
|
proc.kill("SIGTERM");
|
|
35060
35198
|
} catch {
|
|
35061
35199
|
}
|
|
35062
|
-
await Promise.race([exited, new Promise((
|
|
35200
|
+
await Promise.race([exited, new Promise((resolve19) => setTimeout(resolve19, graceMs))]);
|
|
35063
35201
|
}
|
|
35064
35202
|
function forceKillChild(proc, log2, shortId, graceMs) {
|
|
35065
35203
|
log2(
|
|
@@ -35073,7 +35211,7 @@ function forceKillChild(proc, log2, shortId, graceMs) {
|
|
|
35073
35211
|
}
|
|
35074
35212
|
|
|
35075
35213
|
// src/dev-servers/process/wire-dev-server-child-process.ts
|
|
35076
|
-
import
|
|
35214
|
+
import fs22 from "node:fs";
|
|
35077
35215
|
|
|
35078
35216
|
// src/dev-servers/manager/forward-pipe.ts
|
|
35079
35217
|
function forwardChildPipe(childReadable, terminal, onData) {
|
|
@@ -35109,7 +35247,7 @@ function wireDevServerChildProcess(d) {
|
|
|
35109
35247
|
d.setPollInterval(void 0);
|
|
35110
35248
|
return;
|
|
35111
35249
|
}
|
|
35112
|
-
|
|
35250
|
+
fs22.readFile(d.mergedLogPath, (err, buf) => {
|
|
35113
35251
|
if (err || (d.getSpawnGeneration() ?? 0) !== d.scheduledGen) return;
|
|
35114
35252
|
if (buf.length <= d.mergedReadPos.value) return;
|
|
35115
35253
|
const chunk = Buffer.from(buf.subarray(d.mergedReadPos.value));
|
|
@@ -35147,7 +35285,7 @@ ${errTail}` : ""}`);
|
|
|
35147
35285
|
d.sendStatus(code === 0 || code == null ? "stopped" : "error", detail, tails);
|
|
35148
35286
|
};
|
|
35149
35287
|
if (mergedPath) {
|
|
35150
|
-
|
|
35288
|
+
fs22.readFile(mergedPath, (err, buf) => {
|
|
35151
35289
|
if (!err && buf.length > d.mergedReadPos.value) {
|
|
35152
35290
|
const chunk = Buffer.from(buf.subarray(d.mergedReadPos.value));
|
|
35153
35291
|
if (chunk.length > 0) {
|
|
@@ -35249,13 +35387,13 @@ function parseDevServerDefs(servers) {
|
|
|
35249
35387
|
}
|
|
35250
35388
|
|
|
35251
35389
|
// src/dev-servers/manager/shell-spawn/utils.ts
|
|
35252
|
-
import
|
|
35390
|
+
import fs23 from "node:fs";
|
|
35253
35391
|
function isSpawnEbadf(e) {
|
|
35254
35392
|
return typeof e === "object" && e !== null && "code" in e && e.code === "EBADF";
|
|
35255
35393
|
}
|
|
35256
35394
|
function rmDirQuiet(dir) {
|
|
35257
35395
|
try {
|
|
35258
|
-
|
|
35396
|
+
fs23.rmSync(dir, { recursive: true, force: true });
|
|
35259
35397
|
} catch {
|
|
35260
35398
|
}
|
|
35261
35399
|
}
|
|
@@ -35263,7 +35401,7 @@ var cachedDevNullReadFd;
|
|
|
35263
35401
|
function devNullReadFd() {
|
|
35264
35402
|
if (cachedDevNullReadFd === void 0) {
|
|
35265
35403
|
const devPath = process.platform === "win32" ? "nul" : "/dev/null";
|
|
35266
|
-
cachedDevNullReadFd =
|
|
35404
|
+
cachedDevNullReadFd = fs23.openSync(devPath, "r");
|
|
35267
35405
|
}
|
|
35268
35406
|
return cachedDevNullReadFd;
|
|
35269
35407
|
}
|
|
@@ -35337,15 +35475,15 @@ function trySpawnShellTruePiped(command, env, cwd, devNullFd, signal) {
|
|
|
35337
35475
|
|
|
35338
35476
|
// src/dev-servers/manager/shell-spawn/try-spawn-merged-log-file.ts
|
|
35339
35477
|
import { spawn as spawn6 } from "node:child_process";
|
|
35340
|
-
import
|
|
35478
|
+
import fs24 from "node:fs";
|
|
35341
35479
|
import { tmpdir } from "node:os";
|
|
35342
|
-
import
|
|
35480
|
+
import path26 from "node:path";
|
|
35343
35481
|
function trySpawnMergedLogFile(command, env, cwd, signal) {
|
|
35344
|
-
const tmpRoot =
|
|
35345
|
-
const logPath =
|
|
35482
|
+
const tmpRoot = fs24.mkdtempSync(path26.join(tmpdir(), "ba-devsrv-log-"));
|
|
35483
|
+
const logPath = path26.join(tmpRoot, "combined.log");
|
|
35346
35484
|
let logFd;
|
|
35347
35485
|
try {
|
|
35348
|
-
logFd =
|
|
35486
|
+
logFd = fs24.openSync(logPath, "a");
|
|
35349
35487
|
} catch {
|
|
35350
35488
|
rmDirQuiet(tmpRoot);
|
|
35351
35489
|
return null;
|
|
@@ -35364,7 +35502,7 @@ function trySpawnMergedLogFile(command, env, cwd, signal) {
|
|
|
35364
35502
|
} else {
|
|
35365
35503
|
proc = spawn6("/bin/sh", ["-c", command], { env, cwd, stdio, ...signal ? { signal } : {} });
|
|
35366
35504
|
}
|
|
35367
|
-
|
|
35505
|
+
fs24.closeSync(logFd);
|
|
35368
35506
|
return {
|
|
35369
35507
|
proc,
|
|
35370
35508
|
pipedStdoutStderr: true,
|
|
@@ -35373,7 +35511,7 @@ function trySpawnMergedLogFile(command, env, cwd, signal) {
|
|
|
35373
35511
|
};
|
|
35374
35512
|
} catch (e) {
|
|
35375
35513
|
try {
|
|
35376
|
-
|
|
35514
|
+
fs24.closeSync(logFd);
|
|
35377
35515
|
} catch {
|
|
35378
35516
|
}
|
|
35379
35517
|
rmDirQuiet(tmpRoot);
|
|
@@ -35384,22 +35522,22 @@ function trySpawnMergedLogFile(command, env, cwd, signal) {
|
|
|
35384
35522
|
|
|
35385
35523
|
// src/dev-servers/manager/shell-spawn/try-spawn-shell-script-log-redirect.ts
|
|
35386
35524
|
import { spawn as spawn7 } from "node:child_process";
|
|
35387
|
-
import
|
|
35525
|
+
import fs25 from "node:fs";
|
|
35388
35526
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
35389
|
-
import
|
|
35527
|
+
import path27 from "node:path";
|
|
35390
35528
|
function shSingleQuote(s) {
|
|
35391
35529
|
return `'${s.replace(/'/g, `'\\''`)}'`;
|
|
35392
35530
|
}
|
|
35393
35531
|
function trySpawnShellScriptLogRedirectUnix(command, env, cwd, signal) {
|
|
35394
|
-
const tmpRoot =
|
|
35395
|
-
const logPath =
|
|
35396
|
-
const innerPath =
|
|
35397
|
-
const runnerPath =
|
|
35532
|
+
const tmpRoot = fs25.mkdtempSync(path27.join(tmpdir2(), "ba-devsrv-sh-"));
|
|
35533
|
+
const logPath = path27.join(tmpRoot, "combined.log");
|
|
35534
|
+
const innerPath = path27.join(tmpRoot, "_cmd.sh");
|
|
35535
|
+
const runnerPath = path27.join(tmpRoot, "_run.sh");
|
|
35398
35536
|
try {
|
|
35399
|
-
|
|
35537
|
+
fs25.writeFileSync(innerPath, `#!/bin/sh
|
|
35400
35538
|
${command}
|
|
35401
35539
|
`);
|
|
35402
|
-
|
|
35540
|
+
fs25.writeFileSync(
|
|
35403
35541
|
runnerPath,
|
|
35404
35542
|
`#!/bin/sh
|
|
35405
35543
|
cd ${shSingleQuote(cwd)}
|
|
@@ -35425,13 +35563,13 @@ cd ${shSingleQuote(cwd)}
|
|
|
35425
35563
|
}
|
|
35426
35564
|
}
|
|
35427
35565
|
function trySpawnShellScriptLogRedirectWin(command, env, cwd, signal) {
|
|
35428
|
-
const tmpRoot =
|
|
35429
|
-
const logPath =
|
|
35430
|
-
const runnerPath =
|
|
35566
|
+
const tmpRoot = fs25.mkdtempSync(path27.join(tmpdir2(), "ba-devsrv-sh-"));
|
|
35567
|
+
const logPath = path27.join(tmpRoot, "combined.log");
|
|
35568
|
+
const runnerPath = path27.join(tmpRoot, "_run.bat");
|
|
35431
35569
|
const q = (p) => `"${p.replace(/"/g, '""')}"`;
|
|
35432
35570
|
const com = process.env.ComSpec || "cmd.exe";
|
|
35433
35571
|
try {
|
|
35434
|
-
|
|
35572
|
+
fs25.writeFileSync(
|
|
35435
35573
|
runnerPath,
|
|
35436
35574
|
`@ECHO OFF\r
|
|
35437
35575
|
CD /D ${q(cwd)}\r
|
|
@@ -35942,7 +36080,7 @@ async function proxyToLocal(request) {
|
|
|
35942
36080
|
};
|
|
35943
36081
|
const maxAttempts = isIdempotentProxyMethod(request.method) ? LOCAL_PREVIEW_FETCH_RETRY_DELAYS_MS.length + 1 : 1;
|
|
35944
36082
|
for (let attempt = 0; attempt < maxAttempts; attempt += 1) {
|
|
35945
|
-
const once = await new Promise((
|
|
36083
|
+
const once = await new Promise((resolve19) => {
|
|
35946
36084
|
const req = mod.request(opts, (res) => {
|
|
35947
36085
|
const chunks = [];
|
|
35948
36086
|
res.on("data", (c) => chunks.push(c));
|
|
@@ -35953,7 +36091,7 @@ async function proxyToLocal(request) {
|
|
|
35953
36091
|
if (typeof v === "string") headers[k] = v;
|
|
35954
36092
|
else if (Array.isArray(v) && v[0]) headers[k] = v[0];
|
|
35955
36093
|
}
|
|
35956
|
-
|
|
36094
|
+
resolve19({
|
|
35957
36095
|
id: request.id,
|
|
35958
36096
|
statusCode: res.statusCode ?? 0,
|
|
35959
36097
|
headers,
|
|
@@ -35962,7 +36100,7 @@ async function proxyToLocal(request) {
|
|
|
35962
36100
|
});
|
|
35963
36101
|
});
|
|
35964
36102
|
req.on("error", (err) => {
|
|
35965
|
-
|
|
36103
|
+
resolve19({
|
|
35966
36104
|
id: request.id,
|
|
35967
36105
|
statusCode: 0,
|
|
35968
36106
|
headers: {},
|
|
@@ -36301,10 +36439,9 @@ function attachFirehoseAfterIdentified(ctx, params) {
|
|
|
36301
36439
|
|
|
36302
36440
|
// src/bridge/connection/create-bridge-identified-handler.ts
|
|
36303
36441
|
function createOnBridgeIdentified(opts) {
|
|
36304
|
-
const {
|
|
36442
|
+
const { devServerManager, firehoseServerUrl, workspaceId, state, logFn } = opts;
|
|
36305
36443
|
const firehoseCtx = { state, devServerManager, logFn };
|
|
36306
36444
|
return (msg) => {
|
|
36307
|
-
sessionWorktreeManager.setBridgeSessionWorktrees(msg.sessionWorktreesEnabled === true);
|
|
36308
36445
|
const bridgeName = msg.bridgeName;
|
|
36309
36446
|
const proxyPorts = Array.isArray(msg.proxyPorts) ? msg.proxyPorts : [];
|
|
36310
36447
|
const devServers = msg.devServers ?? [];
|
|
@@ -36323,30 +36460,30 @@ function createOnBridgeIdentified(opts) {
|
|
|
36323
36460
|
}
|
|
36324
36461
|
|
|
36325
36462
|
// src/skills/discover-local-agent-skills.ts
|
|
36326
|
-
import
|
|
36327
|
-
import
|
|
36463
|
+
import fs26 from "node:fs";
|
|
36464
|
+
import path28 from "node:path";
|
|
36328
36465
|
var SKILL_DISCOVERY_ROOTS = [".agents/skills", ".claude/skills", ".cursor/skills", "skills"];
|
|
36329
36466
|
function discoverLocalSkills(cwd) {
|
|
36330
36467
|
const out = [];
|
|
36331
36468
|
const seenKeys = /* @__PURE__ */ new Set();
|
|
36332
36469
|
for (const rel of SKILL_DISCOVERY_ROOTS) {
|
|
36333
|
-
const base =
|
|
36334
|
-
if (!
|
|
36470
|
+
const base = path28.join(cwd, rel);
|
|
36471
|
+
if (!fs26.existsSync(base) || !fs26.statSync(base).isDirectory()) continue;
|
|
36335
36472
|
let entries = [];
|
|
36336
36473
|
try {
|
|
36337
|
-
entries =
|
|
36474
|
+
entries = fs26.readdirSync(base);
|
|
36338
36475
|
} catch {
|
|
36339
36476
|
continue;
|
|
36340
36477
|
}
|
|
36341
36478
|
for (const name of entries) {
|
|
36342
|
-
const dir =
|
|
36479
|
+
const dir = path28.join(base, name);
|
|
36343
36480
|
try {
|
|
36344
|
-
if (!
|
|
36481
|
+
if (!fs26.statSync(dir).isDirectory()) continue;
|
|
36345
36482
|
} catch {
|
|
36346
36483
|
continue;
|
|
36347
36484
|
}
|
|
36348
|
-
const skillMd =
|
|
36349
|
-
if (!
|
|
36485
|
+
const skillMd = path28.join(dir, "SKILL.md");
|
|
36486
|
+
if (!fs26.existsSync(skillMd)) continue;
|
|
36350
36487
|
const key = `${rel}/${name}`;
|
|
36351
36488
|
if (seenKeys.has(key)) continue;
|
|
36352
36489
|
seenKeys.add(key);
|
|
@@ -36358,23 +36495,23 @@ function discoverLocalSkills(cwd) {
|
|
|
36358
36495
|
function discoverSkillLayoutRoots(cwd) {
|
|
36359
36496
|
const roots = [];
|
|
36360
36497
|
for (const rel of SKILL_DISCOVERY_ROOTS) {
|
|
36361
|
-
const base =
|
|
36362
|
-
if (!
|
|
36498
|
+
const base = path28.join(cwd, rel);
|
|
36499
|
+
if (!fs26.existsSync(base) || !fs26.statSync(base).isDirectory()) continue;
|
|
36363
36500
|
let entries = [];
|
|
36364
36501
|
try {
|
|
36365
|
-
entries =
|
|
36502
|
+
entries = fs26.readdirSync(base);
|
|
36366
36503
|
} catch {
|
|
36367
36504
|
continue;
|
|
36368
36505
|
}
|
|
36369
36506
|
const skills2 = [];
|
|
36370
36507
|
for (const name of entries) {
|
|
36371
|
-
const dir =
|
|
36508
|
+
const dir = path28.join(base, name);
|
|
36372
36509
|
try {
|
|
36373
|
-
if (!
|
|
36510
|
+
if (!fs26.statSync(dir).isDirectory()) continue;
|
|
36374
36511
|
} catch {
|
|
36375
36512
|
continue;
|
|
36376
36513
|
}
|
|
36377
|
-
if (!
|
|
36514
|
+
if (!fs26.existsSync(path28.join(dir, "SKILL.md"))) continue;
|
|
36378
36515
|
const relPath = `${rel}/${name}`.replace(/\\/g, "/");
|
|
36379
36516
|
skills2.push({ name, relPath });
|
|
36380
36517
|
}
|
|
@@ -36419,7 +36556,7 @@ function createSendLocalSkillsReport(getWs, logFn) {
|
|
|
36419
36556
|
const socket = getWs();
|
|
36420
36557
|
if (!socket || socket.readyState !== wrapper_default.OPEN) return;
|
|
36421
36558
|
const skills2 = discoverLocalSkills(getBridgeWorkspaceDirectory());
|
|
36422
|
-
socket
|
|
36559
|
+
sendWsMessage(socket, { type: "local_skills", skills: skills2 });
|
|
36423
36560
|
} catch (e) {
|
|
36424
36561
|
logFn(
|
|
36425
36562
|
`[Bridge service] Local skills report failed: ${e instanceof Error ? e.message : String(e)}`
|
|
@@ -36472,6 +36609,41 @@ function reportGitRepos(getWs, log2) {
|
|
|
36472
36609
|
});
|
|
36473
36610
|
}
|
|
36474
36611
|
|
|
36612
|
+
// src/types/api-to-bridge-messages.ts
|
|
36613
|
+
var API_TO_BRIDGE_MESSAGE_TYPES = [
|
|
36614
|
+
"auth_token",
|
|
36615
|
+
"bridge_identified",
|
|
36616
|
+
"dev_servers_config",
|
|
36617
|
+
"server_control",
|
|
36618
|
+
"agent_config",
|
|
36619
|
+
"prompt",
|
|
36620
|
+
"session_git_request",
|
|
36621
|
+
"rename_session_branch",
|
|
36622
|
+
"session_archived",
|
|
36623
|
+
"session_discarded",
|
|
36624
|
+
"revert_turn_snapshot",
|
|
36625
|
+
"cancel_run",
|
|
36626
|
+
"cursor_request_response",
|
|
36627
|
+
"skill_call",
|
|
36628
|
+
"file_browser_request",
|
|
36629
|
+
"file_browser_search",
|
|
36630
|
+
"skill_layout_request",
|
|
36631
|
+
"install_skills",
|
|
36632
|
+
"refresh_local_skills"
|
|
36633
|
+
];
|
|
36634
|
+
var API_TO_BRIDGE_TYPE_SET = new Set(API_TO_BRIDGE_MESSAGE_TYPES);
|
|
36635
|
+
function parseApiToBridgeMessage(data, log2) {
|
|
36636
|
+
if (data === null || typeof data !== "object" || Array.isArray(data)) return null;
|
|
36637
|
+
const t = data.type;
|
|
36638
|
+
if (typeof t !== "string" || !API_TO_BRIDGE_TYPE_SET.has(t)) {
|
|
36639
|
+
if (typeof t === "string") {
|
|
36640
|
+
log2?.(`[Bridge service] unhandled message type: ${t}`);
|
|
36641
|
+
}
|
|
36642
|
+
return null;
|
|
36643
|
+
}
|
|
36644
|
+
return data;
|
|
36645
|
+
}
|
|
36646
|
+
|
|
36475
36647
|
// src/bridge/routing/handlers/auth-token.ts
|
|
36476
36648
|
var handleAuthToken = (msg, { log: log2 }) => {
|
|
36477
36649
|
if (typeof msg.token !== "string") return;
|
|
@@ -36482,9 +36654,11 @@ var handleAuthToken = (msg, { log: log2 }) => {
|
|
|
36482
36654
|
// src/bridge/routing/handlers/bridge-identified.ts
|
|
36483
36655
|
var handleBridgeIdentified = (msg, deps) => {
|
|
36484
36656
|
if (typeof msg.bridgeName !== "string") return;
|
|
36485
|
-
deps.onBridgeIdentified(
|
|
36486
|
-
msg
|
|
36487
|
-
|
|
36657
|
+
deps.onBridgeIdentified({
|
|
36658
|
+
bridgeName: msg.bridgeName,
|
|
36659
|
+
proxyPorts: msg.proxyPorts,
|
|
36660
|
+
devServers: msg.devServers
|
|
36661
|
+
});
|
|
36488
36662
|
setImmediate(() => {
|
|
36489
36663
|
void (async () => {
|
|
36490
36664
|
try {
|
|
@@ -36519,7 +36693,7 @@ var handleAgentConfigMessage = (msg, deps) => {
|
|
|
36519
36693
|
};
|
|
36520
36694
|
|
|
36521
36695
|
// src/agents/acp/from-bridge/handle-bridge-prompt.ts
|
|
36522
|
-
import * as
|
|
36696
|
+
import * as path30 from "node:path";
|
|
36523
36697
|
|
|
36524
36698
|
// src/agents/acp/from-bridge/bridge-prompt-wiring.ts
|
|
36525
36699
|
function createBridgePromptSenders(deps, getWs) {
|
|
@@ -36560,7 +36734,7 @@ import { execFile as execFile10 } from "node:child_process";
|
|
|
36560
36734
|
import { promisify as promisify10 } from "node:util";
|
|
36561
36735
|
|
|
36562
36736
|
// src/git/bridge-queue-key.ts
|
|
36563
|
-
import * as
|
|
36737
|
+
import * as path29 from "node:path";
|
|
36564
36738
|
import { createHash as createHash2 } from "node:crypto";
|
|
36565
36739
|
function normalizeCanonicalGitUrl(url2) {
|
|
36566
36740
|
let s = url2.trim();
|
|
@@ -36588,11 +36762,11 @@ function canonicalUrlToRepoIdSync(url2) {
|
|
|
36588
36762
|
return createHash2("sha256").update(normalized).digest("hex").slice(0, 32);
|
|
36589
36763
|
}
|
|
36590
36764
|
function fallbackRepoIdFromPath(absPath) {
|
|
36591
|
-
return createHash2("sha256").update(
|
|
36765
|
+
return createHash2("sha256").update(path29.resolve(absPath)).digest("hex").slice(0, 32);
|
|
36592
36766
|
}
|
|
36593
36767
|
async function resolveBridgeQueueBindFields(options) {
|
|
36594
36768
|
const { effectiveCwd, worktreePaths, primaryRepoRoots, log: log2 } = options;
|
|
36595
|
-
const cwdAbs = worktreePaths.length > 0 ?
|
|
36769
|
+
const cwdAbs = worktreePaths.length > 0 ? path29.resolve(worktreePaths[0]) : path29.resolve(effectiveCwd);
|
|
36596
36770
|
if (!primaryRepoRoots.length) {
|
|
36597
36771
|
log2("[Bridge service] Prompt queue bind skipped: no Git repository roots under the working directory.");
|
|
36598
36772
|
return null;
|
|
@@ -36653,11 +36827,15 @@ async function runBridgePromptPreamble(params) {
|
|
|
36653
36827
|
}
|
|
36654
36828
|
if (s && sessionId) {
|
|
36655
36829
|
const cliGitBranch = await readGitBranch(effectiveCwd);
|
|
36830
|
+
const usesWt = sessionWorktreeManager.usesWorktreeSession(sessionId);
|
|
36831
|
+
const mirrorAbs = sessionWorktreeManager.getAgentCwdForSession(sessionId);
|
|
36656
36832
|
sendWsMessage(s, {
|
|
36657
36833
|
type: "session_git_context_report",
|
|
36658
36834
|
sessionId,
|
|
36659
36835
|
cliGitBranch,
|
|
36660
|
-
agentUsesWorktree:
|
|
36836
|
+
agentUsesWorktree: usesWt,
|
|
36837
|
+
sessionParent: usesWt ? "worktrees_root" : "bridge_root",
|
|
36838
|
+
sessionParentPath: usesWt ? mirrorAbs : getBridgeWorkspaceDirectory()
|
|
36661
36839
|
});
|
|
36662
36840
|
}
|
|
36663
36841
|
if (s && sessionId && runId) {
|
|
@@ -36676,9 +36854,9 @@ function parseChangeSummarySnapshots(raw) {
|
|
|
36676
36854
|
for (const item of raw) {
|
|
36677
36855
|
if (!item || typeof item !== "object") continue;
|
|
36678
36856
|
const o = item;
|
|
36679
|
-
const
|
|
36680
|
-
if (!
|
|
36681
|
-
const row = { path:
|
|
36857
|
+
const path36 = typeof o.path === "string" && o.path.trim() !== "" ? o.path.trim() : "";
|
|
36858
|
+
if (!path36) continue;
|
|
36859
|
+
const row = { path: path36 };
|
|
36682
36860
|
if (typeof o.patchContent === "string") row.patchContent = o.patchContent;
|
|
36683
36861
|
if (typeof o.oldText === "string") row.oldText = o.oldText;
|
|
36684
36862
|
if (typeof o.newText === "string") row.newText = o.newText;
|
|
@@ -36777,12 +36955,14 @@ function handleBridgePrompt(msg, deps) {
|
|
|
36777
36955
|
return;
|
|
36778
36956
|
}
|
|
36779
36957
|
const isNewSession = msg.isNewSession === true;
|
|
36780
|
-
const
|
|
36958
|
+
const rawParent = msg.sessionParent;
|
|
36959
|
+
const sessionParent = rawParent === "bridge_root" || rawParent === "worktrees_root" ? rawParent : rawParent === "session_worktrees_root" ? "worktrees_root" : null;
|
|
36960
|
+
const sessionParentPath = typeof msg.sessionParentPath === "string" && msg.sessionParentPath.trim() ? msg.sessionParentPath.trim() : null;
|
|
36781
36961
|
const agentType = typeof msg.agentType === "string" && msg.agentType.trim() ? msg.agentType.trim() : void 0;
|
|
36782
36962
|
const mode = typeof msg.mode === "string" && msg.mode.trim() ? msg.mode.trim() : void 0;
|
|
36783
36963
|
acpManager.logPromptReceivedFromBridge({ agentType, mode });
|
|
36784
36964
|
async function preambleAndPrompt(resolvedCwd) {
|
|
36785
|
-
const effectiveCwd =
|
|
36965
|
+
const effectiveCwd = path30.resolve(resolvedCwd ?? getBridgeWorkspaceDirectory());
|
|
36786
36966
|
await runBridgePromptPreamble({
|
|
36787
36967
|
getWs,
|
|
36788
36968
|
log: log2,
|
|
@@ -36825,7 +37005,7 @@ function handleBridgePrompt(msg, deps) {
|
|
|
36825
37005
|
e2ee: deps.e2ee
|
|
36826
37006
|
});
|
|
36827
37007
|
}
|
|
36828
|
-
void sessionWorktreeManager.resolveCwdForPrompt(sessionId, { isNewSession,
|
|
37008
|
+
void sessionWorktreeManager.resolveCwdForPrompt(sessionId, { isNewSession, sessionParent, sessionParentPath }).then((cwd) => preambleAndPrompt(cwd)).catch((err) => {
|
|
36829
37009
|
log2(`[Agent] Worktree resolve failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
36830
37010
|
void preambleAndPrompt(void 0);
|
|
36831
37011
|
});
|
|
@@ -36894,8 +37074,8 @@ function randomSecret() {
|
|
|
36894
37074
|
}
|
|
36895
37075
|
return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
36896
37076
|
}
|
|
36897
|
-
async function requestPreviewApi(port, secret, method,
|
|
36898
|
-
const url2 = `http://127.0.0.1:${port}${
|
|
37077
|
+
async function requestPreviewApi(port, secret, method, path36, body) {
|
|
37078
|
+
const url2 = `http://127.0.0.1:${port}${path36}`;
|
|
36899
37079
|
const headers = {
|
|
36900
37080
|
[PREVIEW_SECRET_HEADER]: secret,
|
|
36901
37081
|
"Content-Type": "application/json"
|
|
@@ -36907,7 +37087,7 @@ async function requestPreviewApi(port, secret, method, path34, body) {
|
|
|
36907
37087
|
});
|
|
36908
37088
|
const data = await res.json().catch(() => ({}));
|
|
36909
37089
|
if (!res.ok) {
|
|
36910
|
-
throw new Error(data?.error ?? `Preview API ${method} ${
|
|
37090
|
+
throw new Error(data?.error ?? `Preview API ${method} ${path36}: ${res.status}`);
|
|
36911
37091
|
}
|
|
36912
37092
|
return data;
|
|
36913
37093
|
}
|
|
@@ -37059,26 +37239,28 @@ function handleSkillCall(msg, socket, log2) {
|
|
|
37059
37239
|
|
|
37060
37240
|
// src/bridge/routing/handlers/skill-call.ts
|
|
37061
37241
|
var handleSkillCallMessage = (msg, { getWs, log: log2 }) => {
|
|
37062
|
-
|
|
37242
|
+
const skillId = typeof msg.skillId === "string" ? msg.skillId : "";
|
|
37243
|
+
const operationId = typeof msg.operationId === "string" ? msg.operationId : "";
|
|
37244
|
+
if (!skillId || !operationId) return;
|
|
37063
37245
|
const socket = getWs();
|
|
37064
37246
|
if (!socket) return;
|
|
37065
37247
|
handleSkillCall(
|
|
37066
|
-
msg,
|
|
37248
|
+
{ id: msg.id, skillId, operationId, params: msg.params },
|
|
37067
37249
|
socket,
|
|
37068
37250
|
log2
|
|
37069
37251
|
);
|
|
37070
37252
|
};
|
|
37071
37253
|
|
|
37072
37254
|
// src/files/list-dir.ts
|
|
37073
|
-
import
|
|
37074
|
-
import
|
|
37255
|
+
import fs27 from "node:fs";
|
|
37256
|
+
import path32 from "node:path";
|
|
37075
37257
|
|
|
37076
37258
|
// src/files/ensure-under-cwd.ts
|
|
37077
|
-
import
|
|
37259
|
+
import path31 from "node:path";
|
|
37078
37260
|
function ensureUnderCwd(relativePath, cwd = getBridgeWorkspaceDirectory()) {
|
|
37079
|
-
const normalized =
|
|
37080
|
-
const resolved =
|
|
37081
|
-
if (!resolved.startsWith(cwd +
|
|
37261
|
+
const normalized = path31.normalize(relativePath).replace(/^(\.\/)+/, "");
|
|
37262
|
+
const resolved = path31.resolve(cwd, normalized);
|
|
37263
|
+
if (!resolved.startsWith(cwd + path31.sep) && resolved !== cwd) {
|
|
37082
37264
|
return null;
|
|
37083
37265
|
}
|
|
37084
37266
|
return resolved;
|
|
@@ -37092,7 +37274,7 @@ async function listDirAsync(relativePath) {
|
|
|
37092
37274
|
return { error: "Path is outside working directory" };
|
|
37093
37275
|
}
|
|
37094
37276
|
try {
|
|
37095
|
-
const names = await
|
|
37277
|
+
const names = await fs27.promises.readdir(resolved, { withFileTypes: true });
|
|
37096
37278
|
const visible = names.filter((d) => !d.name.startsWith("."));
|
|
37097
37279
|
const entries = [];
|
|
37098
37280
|
for (let i = 0; i < visible.length; i++) {
|
|
@@ -37100,12 +37282,12 @@ async function listDirAsync(relativePath) {
|
|
|
37100
37282
|
await yieldToEventLoop();
|
|
37101
37283
|
}
|
|
37102
37284
|
const d = visible[i];
|
|
37103
|
-
const entryPath =
|
|
37104
|
-
const fullPath =
|
|
37285
|
+
const entryPath = path32.join(relativePath || ".", d.name).replace(/\\/g, "/");
|
|
37286
|
+
const fullPath = path32.join(resolved, d.name);
|
|
37105
37287
|
let isDir = d.isDirectory();
|
|
37106
37288
|
if (d.isSymbolicLink()) {
|
|
37107
37289
|
try {
|
|
37108
|
-
const targetStat = await
|
|
37290
|
+
const targetStat = await fs27.promises.stat(fullPath);
|
|
37109
37291
|
isDir = targetStat.isDirectory();
|
|
37110
37292
|
} catch {
|
|
37111
37293
|
isDir = false;
|
|
@@ -37130,25 +37312,25 @@ async function listDirAsync(relativePath) {
|
|
|
37130
37312
|
}
|
|
37131
37313
|
|
|
37132
37314
|
// src/files/read-file.ts
|
|
37133
|
-
import
|
|
37315
|
+
import fs28 from "node:fs";
|
|
37134
37316
|
import { StringDecoder } from "node:string_decoder";
|
|
37135
37317
|
function resolveFilePath(relativePath) {
|
|
37136
37318
|
const resolved = ensureUnderCwd(relativePath, getBridgeWorkspaceDirectory());
|
|
37137
37319
|
if (!resolved) return { error: "Path is outside working directory" };
|
|
37138
37320
|
let real;
|
|
37139
37321
|
try {
|
|
37140
|
-
real =
|
|
37322
|
+
real = fs28.realpathSync(resolved);
|
|
37141
37323
|
} catch {
|
|
37142
37324
|
real = resolved;
|
|
37143
37325
|
}
|
|
37144
|
-
const stat3 =
|
|
37326
|
+
const stat3 = fs28.statSync(real);
|
|
37145
37327
|
if (!stat3.isFile()) return { error: "Not a file" };
|
|
37146
37328
|
return real;
|
|
37147
37329
|
}
|
|
37148
37330
|
var LINE_CHUNK_SIZE = 64 * 1024;
|
|
37149
37331
|
function readFileRange(filePath, startLine, endLine, lineOffsetIn, lineChunkSize = LINE_CHUNK_SIZE) {
|
|
37150
|
-
const fileSize =
|
|
37151
|
-
const fd =
|
|
37332
|
+
const fileSize = fs28.statSync(filePath).size;
|
|
37333
|
+
const fd = fs28.openSync(filePath, "r");
|
|
37152
37334
|
const bufSize = 64 * 1024;
|
|
37153
37335
|
const buf = Buffer.alloc(bufSize);
|
|
37154
37336
|
const decoder = new StringDecoder("utf8");
|
|
@@ -37161,7 +37343,7 @@ function readFileRange(filePath, startLine, endLine, lineOffsetIn, lineChunkSize
|
|
|
37161
37343
|
let line0Accum = "";
|
|
37162
37344
|
try {
|
|
37163
37345
|
let bytesRead;
|
|
37164
|
-
while (!done && (bytesRead =
|
|
37346
|
+
while (!done && (bytesRead = fs28.readSync(fd, buf, 0, bufSize, null)) > 0) {
|
|
37165
37347
|
const text = partial2 + decoder.write(buf.subarray(0, bytesRead));
|
|
37166
37348
|
partial2 = "";
|
|
37167
37349
|
let lineStart = 0;
|
|
@@ -37296,7 +37478,7 @@ function readFileRange(filePath, startLine, endLine, lineOffsetIn, lineChunkSize
|
|
|
37296
37478
|
}
|
|
37297
37479
|
return { content: resultLines.join("\n"), size: fileSize };
|
|
37298
37480
|
} finally {
|
|
37299
|
-
|
|
37481
|
+
fs28.closeSync(fd);
|
|
37300
37482
|
}
|
|
37301
37483
|
}
|
|
37302
37484
|
function readFile3(relativePath, startLine, endLine, lineOffset, lineChunkSize = LINE_CHUNK_SIZE) {
|
|
@@ -37307,8 +37489,8 @@ function readFile3(relativePath, startLine, endLine, lineOffset, lineChunkSize =
|
|
|
37307
37489
|
if (hasRange) {
|
|
37308
37490
|
return readFileRange(result, startLine, endLine, lineOffset, lineChunkSize);
|
|
37309
37491
|
}
|
|
37310
|
-
const stat3 =
|
|
37311
|
-
const raw =
|
|
37492
|
+
const stat3 = fs28.statSync(result);
|
|
37493
|
+
const raw = fs28.readFileSync(result, "utf8");
|
|
37312
37494
|
const lines = raw.split(/\r?\n/);
|
|
37313
37495
|
return { content: raw, totalLines: lines.length, size: stat3.size };
|
|
37314
37496
|
} catch (err) {
|
|
@@ -37420,12 +37602,14 @@ function handleSkillLayoutRequest(msg, deps) {
|
|
|
37420
37602
|
const socket = deps.getWs();
|
|
37421
37603
|
const id = typeof msg.id === "string" ? msg.id : "";
|
|
37422
37604
|
const roots = discoverSkillLayoutRoots(getBridgeWorkspaceDirectory());
|
|
37423
|
-
socket
|
|
37605
|
+
if (socket) {
|
|
37606
|
+
sendWsMessage(socket, { type: "skill_layout_response", id, roots });
|
|
37607
|
+
}
|
|
37424
37608
|
}
|
|
37425
37609
|
|
|
37426
37610
|
// src/skills/install-remote-skills.ts
|
|
37427
|
-
import
|
|
37428
|
-
import
|
|
37611
|
+
import fs29 from "node:fs";
|
|
37612
|
+
import path33 from "node:path";
|
|
37429
37613
|
function installRemoteSkills(cwd, targetDir, items) {
|
|
37430
37614
|
const installed2 = [];
|
|
37431
37615
|
if (!Array.isArray(items)) {
|
|
@@ -37436,15 +37620,15 @@ function installRemoteSkills(cwd, targetDir, items) {
|
|
|
37436
37620
|
if (typeof item.sourceId !== "string" || typeof item.skillName !== "string" || typeof item.versionHash !== "string" || !Array.isArray(item.files)) {
|
|
37437
37621
|
continue;
|
|
37438
37622
|
}
|
|
37439
|
-
const skillDir =
|
|
37623
|
+
const skillDir = path33.join(cwd, targetDir, item.skillName);
|
|
37440
37624
|
for (const f of item.files) {
|
|
37441
37625
|
if (typeof f.path !== "string" || !f.text && !f.base64) continue;
|
|
37442
|
-
const dest =
|
|
37443
|
-
|
|
37626
|
+
const dest = path33.join(skillDir, f.path);
|
|
37627
|
+
fs29.mkdirSync(path33.dirname(dest), { recursive: true });
|
|
37444
37628
|
if (f.text !== void 0) {
|
|
37445
|
-
|
|
37629
|
+
fs29.writeFileSync(dest, f.text, "utf8");
|
|
37446
37630
|
} else if (f.base64) {
|
|
37447
|
-
|
|
37631
|
+
fs29.writeFileSync(dest, Buffer.from(f.base64, "base64"));
|
|
37448
37632
|
}
|
|
37449
37633
|
}
|
|
37450
37634
|
installed2.push({
|
|
@@ -37470,10 +37654,14 @@ var handleInstallSkillsMessage = (msg, deps) => {
|
|
|
37470
37654
|
if (!result.success) {
|
|
37471
37655
|
const err = result.error ?? "Invalid items";
|
|
37472
37656
|
deps.log(`[Bridge service] Install skills failed: ${err}`);
|
|
37473
|
-
socket
|
|
37657
|
+
if (socket) {
|
|
37658
|
+
sendWsMessage(socket, { type: "install_skills_result", id, success: false, error: err });
|
|
37659
|
+
}
|
|
37474
37660
|
return;
|
|
37475
37661
|
}
|
|
37476
|
-
socket
|
|
37662
|
+
if (socket) {
|
|
37663
|
+
sendWsMessage(socket, { type: "install_skills_result", id, success: true, installed: result.installed });
|
|
37664
|
+
}
|
|
37477
37665
|
};
|
|
37478
37666
|
|
|
37479
37667
|
// src/bridge/routing/handlers/refresh-local-skills.ts
|
|
@@ -37590,7 +37778,7 @@ var handleSessionDiscardedMessage = (msg, deps) => {
|
|
|
37590
37778
|
};
|
|
37591
37779
|
|
|
37592
37780
|
// src/bridge/routing/handlers/revert-turn-snapshot.ts
|
|
37593
|
-
import * as
|
|
37781
|
+
import * as fs30 from "node:fs";
|
|
37594
37782
|
var handleRevertTurnSnapshotMessage = (msg, deps) => {
|
|
37595
37783
|
const id = typeof msg.id === "string" ? msg.id : "";
|
|
37596
37784
|
const sessionId = typeof msg.sessionId === "string" ? msg.sessionId : "";
|
|
@@ -37602,7 +37790,7 @@ var handleRevertTurnSnapshotMessage = (msg, deps) => {
|
|
|
37602
37790
|
if (!s) return;
|
|
37603
37791
|
const agentBase = sessionWorktreeManager.getAgentCwdForSession(sessionId) ?? getBridgeWorkspaceDirectory();
|
|
37604
37792
|
const file2 = snapshotFilePath(agentBase, turnId);
|
|
37605
|
-
if (!
|
|
37793
|
+
if (!fs30.existsSync(file2)) {
|
|
37606
37794
|
sendWsMessage(s, {
|
|
37607
37795
|
type: "revert_turn_snapshot_result",
|
|
37608
37796
|
id,
|
|
@@ -37623,7 +37811,7 @@ var handleRevertTurnSnapshotMessage = (msg, deps) => {
|
|
|
37623
37811
|
|
|
37624
37812
|
// src/bridge/routing/handlers/dev-server-control.ts
|
|
37625
37813
|
var handleDevServerControl = (msg, deps) => {
|
|
37626
|
-
let wire
|
|
37814
|
+
let wire;
|
|
37627
37815
|
try {
|
|
37628
37816
|
wire = deps.e2ee ? deps.e2ee.decryptMessage(msg) : msg;
|
|
37629
37817
|
} catch (e) {
|
|
@@ -37644,9 +37832,7 @@ var handleDevServersConfig = (msg, deps) => {
|
|
|
37644
37832
|
|
|
37645
37833
|
// src/bridge/routing/dispatch-bridge-message.ts
|
|
37646
37834
|
function dispatchBridgeMessage(msg, deps) {
|
|
37647
|
-
|
|
37648
|
-
if (typeof type !== "string") return;
|
|
37649
|
-
switch (type) {
|
|
37835
|
+
switch (msg.type) {
|
|
37650
37836
|
case "auth_token":
|
|
37651
37837
|
handleAuthToken(msg, deps);
|
|
37652
37838
|
break;
|
|
@@ -37704,15 +37890,14 @@ function dispatchBridgeMessage(msg, deps) {
|
|
|
37704
37890
|
case "refresh_local_skills":
|
|
37705
37891
|
handleRefreshLocalSkills(msg, deps);
|
|
37706
37892
|
break;
|
|
37707
|
-
default:
|
|
37708
|
-
deps.log?.(`[Bridge service] unhandled message type: ${type}`);
|
|
37709
37893
|
}
|
|
37710
37894
|
}
|
|
37711
37895
|
|
|
37712
37896
|
// src/bridge/routing/handle-bridge-message.ts
|
|
37713
37897
|
function handleBridgeMessage(data, deps) {
|
|
37714
|
-
const msg = data;
|
|
37715
37898
|
if (!deps.getWs()) return;
|
|
37899
|
+
const msg = parseApiToBridgeMessage(data, deps.log);
|
|
37900
|
+
if (!msg) return;
|
|
37716
37901
|
setImmediate(() => {
|
|
37717
37902
|
dispatchBridgeMessage(msg, deps);
|
|
37718
37903
|
});
|
|
@@ -37758,7 +37943,8 @@ function createMainBridgeWebSocketLifecycle(params) {
|
|
|
37758
37943
|
tokens,
|
|
37759
37944
|
persistTokens,
|
|
37760
37945
|
onAuthInvalid,
|
|
37761
|
-
e2ee
|
|
37946
|
+
e2ee,
|
|
37947
|
+
identifyReportedPaths
|
|
37762
37948
|
} = params;
|
|
37763
37949
|
let authRefreshInFlight = false;
|
|
37764
37950
|
function handleOpen() {
|
|
@@ -37771,7 +37957,14 @@ function createMainBridgeWebSocketLifecycle(params) {
|
|
|
37771
37957
|
}
|
|
37772
37958
|
const socket = getWs();
|
|
37773
37959
|
if (socket) {
|
|
37774
|
-
sendWsMessage(socket, {
|
|
37960
|
+
sendWsMessage(socket, {
|
|
37961
|
+
type: "identify",
|
|
37962
|
+
role: "cli",
|
|
37963
|
+
cliVersion: CLI_VERSION,
|
|
37964
|
+
bridgeRootPath: identifyReportedPaths.bridgeRootPath,
|
|
37965
|
+
worktreesRootPath: identifyReportedPaths.worktreesRootPath,
|
|
37966
|
+
...e2ee ? { e: e2ee.handshake } : {}
|
|
37967
|
+
});
|
|
37775
37968
|
reportGitRepos(getWs, logFn);
|
|
37776
37969
|
}
|
|
37777
37970
|
if (justAuthenticated && socket) {
|
|
@@ -37897,7 +38090,6 @@ async function createBridgeConnection(options) {
|
|
|
37897
38090
|
const e2ee = options.e2eCertificate ? createCliE2eeRuntime(options.e2eCertificate) : void 0;
|
|
37898
38091
|
const devServerManager = new DevServerManager({ getWs, log: logFn, getBridgeCwd: getBridgeWorkspaceDirectory, e2ee });
|
|
37899
38092
|
const onBridgeIdentified = createOnBridgeIdentified({
|
|
37900
|
-
sessionWorktreeManager,
|
|
37901
38093
|
devServerManager,
|
|
37902
38094
|
firehoseServerUrl,
|
|
37903
38095
|
workspaceId,
|
|
@@ -37919,6 +38111,10 @@ async function createBridgeConnection(options) {
|
|
|
37919
38111
|
cloudApiBaseUrl: apiUrl,
|
|
37920
38112
|
getCloudAccessToken: () => tokens.accessToken
|
|
37921
38113
|
};
|
|
38114
|
+
const identifyReportedPaths = {
|
|
38115
|
+
bridgeRootPath: path34.resolve(getBridgeWorkspaceDirectory()),
|
|
38116
|
+
worktreesRootPath: path34.resolve(worktreesRootAbs)
|
|
38117
|
+
};
|
|
37922
38118
|
const { connect } = createMainBridgeWebSocketLifecycle({
|
|
37923
38119
|
state,
|
|
37924
38120
|
getWs,
|
|
@@ -37930,7 +38126,8 @@ async function createBridgeConnection(options) {
|
|
|
37930
38126
|
tokens,
|
|
37931
38127
|
persistTokens,
|
|
37932
38128
|
onAuthInvalid,
|
|
37933
|
-
e2ee
|
|
38129
|
+
e2ee,
|
|
38130
|
+
identifyReportedPaths
|
|
37934
38131
|
});
|
|
37935
38132
|
connect();
|
|
37936
38133
|
const stopFileIndexWatcher = startFileIndexWatcher(getBridgeWorkspaceDirectory());
|
|
@@ -38132,6 +38329,13 @@ async function runBridge(options) {
|
|
|
38132
38329
|
}
|
|
38133
38330
|
|
|
38134
38331
|
// src/cli/run-cli-action.ts
|
|
38332
|
+
var GOLDEN_YELLOW = "\x1B[38;5;220m";
|
|
38333
|
+
var REDDISH_ORANGE = "\x1B[38;5;208m";
|
|
38334
|
+
var RESET = "\x1B[0m";
|
|
38335
|
+
var E2EE_CERTIFICATES_OPTION = "--e2ee-certificates-dir <path>";
|
|
38336
|
+
function colorize(color, message) {
|
|
38337
|
+
return `${color}${message}${RESET}`;
|
|
38338
|
+
}
|
|
38135
38339
|
async function runCliAction(program2, opts) {
|
|
38136
38340
|
const positionalUrl = program2.args?.[0];
|
|
38137
38341
|
const urlFromPositional = typeof positionalUrl === "string" && /^https?:\/\//i.test(positionalUrl) ? positionalUrl : void 0;
|
|
@@ -38141,9 +38345,9 @@ async function runCliAction(program2, opts) {
|
|
|
38141
38345
|
let authToken = opts.token;
|
|
38142
38346
|
const firehoseServerUrl = opts.firehoseUrl ?? opts.proxyUrl ?? process.env.BUILDAUTOMATON_FIREHOSE_URL ?? process.env.BUILDAUTOMATON_PROXY_URL ?? DEFAULT_FIREHOSE_URL;
|
|
38143
38347
|
if (opts.cwd && typeof opts.cwd === "string" && opts.cwd.trim()) {
|
|
38144
|
-
const resolvedCwd =
|
|
38348
|
+
const resolvedCwd = path35.resolve(process.cwd(), opts.cwd.trim());
|
|
38145
38349
|
try {
|
|
38146
|
-
const st =
|
|
38350
|
+
const st = fs31.statSync(resolvedCwd);
|
|
38147
38351
|
if (!st.isDirectory()) {
|
|
38148
38352
|
console.error(`--cwd is not a directory: ${resolvedCwd}`);
|
|
38149
38353
|
process.exit(1);
|
|
@@ -38155,9 +38359,15 @@ async function runCliAction(program2, opts) {
|
|
|
38155
38359
|
process.chdir(resolvedCwd);
|
|
38156
38360
|
}
|
|
38157
38361
|
initBridgeWorkspaceDirectory();
|
|
38362
|
+
console.log(
|
|
38363
|
+
colorize(
|
|
38364
|
+
GOLDEN_YELLOW,
|
|
38365
|
+
`[Workspace] Using ${getBridgeWorkspaceDirectory()} as the working directory for file access and agents.`
|
|
38366
|
+
)
|
|
38367
|
+
);
|
|
38158
38368
|
let worktreesRootAbs;
|
|
38159
38369
|
if (opts.worktreesRoot && opts.worktreesRoot.trim()) {
|
|
38160
|
-
worktreesRootAbs =
|
|
38370
|
+
worktreesRootAbs = path35.resolve(opts.worktreesRoot.trim());
|
|
38161
38371
|
}
|
|
38162
38372
|
const e2eCertificates = opts.e2eeCertificatesDir?.trim() ? await loadOrCreateE2eCertificates(opts.e2eeCertificatesDir.trim()) : void 0;
|
|
38163
38373
|
if (e2eCertificates) {
|
|
@@ -38168,6 +38378,13 @@ async function runCliAction(program2, opts) {
|
|
|
38168
38378
|
console.log(
|
|
38169
38379
|
`[E2EE] Active key: ${e2eCertificates.activeCertificate.name} (${e2eCertificates.activeCertificate.id})`
|
|
38170
38380
|
);
|
|
38381
|
+
} else {
|
|
38382
|
+
console.warn(
|
|
38383
|
+
colorize(
|
|
38384
|
+
REDDISH_ORANGE,
|
|
38385
|
+
`[E2EE] Warning: this CLI session is not end-to-end encrypted. Start with ${E2EE_CERTIFICATES_OPTION} to enable end-to-end encryption.`
|
|
38386
|
+
)
|
|
38387
|
+
);
|
|
38171
38388
|
}
|
|
38172
38389
|
let refreshToken;
|
|
38173
38390
|
if ((!workspaceId || !authToken) && opts.config !== false) {
|
|
@@ -38193,7 +38410,7 @@ async function runCliAction(program2, opts) {
|
|
|
38193
38410
|
// src/cli.ts
|
|
38194
38411
|
async function main() {
|
|
38195
38412
|
const program2 = new Command();
|
|
38196
|
-
program2.name("buildautomaton").description("CLI for BuildAutomaton: ACP client, WebSocket bridge to backend, and skills (e.g. preview)").version(
|
|
38413
|
+
program2.name("buildautomaton").description("CLI for BuildAutomaton: ACP client, WebSocket bridge to backend, and skills (e.g. preview)").version(CLI_VERSION).option("-u, --api-url <url>", "Backend API URL", process.env.BUILDAUTOMATON_API_URL ?? DEFAULT_API_URL).option("-w, --workspace-id <id>", "Workspace ID (or set BUILDAUTOMATON_WORKSPACE_ID)", process.env.BUILDAUTOMATON_WORKSPACE_ID).option("-t, --token <token>", "Auth token (or set BUILDAUTOMATON_AUTH_TOKEN)", process.env.BUILDAUTOMATON_AUTH_TOKEN).option(
|
|
38197
38414
|
"--firehose-url <url>",
|
|
38198
38415
|
"Firehose server URL (default: Fly app; or BUILDAUTOMATON_FIREHOSE_URL / legacy BUILDAUTOMATON_PROXY_URL)",
|
|
38199
38416
|
process.env.BUILDAUTOMATON_FIREHOSE_URL ?? process.env.BUILDAUTOMATON_PROXY_URL ?? DEFAULT_FIREHOSE_URL
|
|
@@ -38202,7 +38419,7 @@ async function main() {
|
|
|
38202
38419
|
"Working directory for the bridge (absolute or relative to the current directory); affects skills, git, file index, and agent cwd"
|
|
38203
38420
|
).option("-n, --name <name>", "Bridge name when creating via browser (alphanumeric and underscores only)").option(
|
|
38204
38421
|
"--worktrees-root <path>",
|
|
38205
|
-
"Root directory for per-session git worktrees (default: ~/.buildautomaton/worktrees).
|
|
38422
|
+
"Root directory for per-session git worktrees (default: ~/.buildautomaton/worktrees)."
|
|
38206
38423
|
).option(
|
|
38207
38424
|
"--e2ee-certificates-dir <path>",
|
|
38208
38425
|
"Directory to load or generate E2EE keys for sessions, files, and logs",
|