@buildautomaton/cli 0.1.24 → 0.1.25
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 +867 -600
- package/dist/cli.js.map +4 -4
- package/dist/index.js +1009 -747
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -973,8 +973,8 @@ var require_command = __commonJS({
|
|
|
973
973
|
"../../node_modules/.pnpm/commander@12.1.0/node_modules/commander/lib/command.js"(exports) {
|
|
974
974
|
var EventEmitter2 = __require("node:events").EventEmitter;
|
|
975
975
|
var childProcess2 = __require("node:child_process");
|
|
976
|
-
var
|
|
977
|
-
var
|
|
976
|
+
var path37 = __require("node:path");
|
|
977
|
+
var fs36 = __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 = path37.resolve(baseDir, baseName);
|
|
1910
|
+
if (fs36.existsSync(localBin)) return localBin;
|
|
1911
|
+
if (sourceExt.includes(path37.extname(baseName))) return void 0;
|
|
1912
1912
|
const foundExt = sourceExt.find(
|
|
1913
|
-
(ext) =>
|
|
1913
|
+
(ext) => fs36.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 = fs36.realpathSync(this._scriptPath);
|
|
1926
1926
|
} catch (err) {
|
|
1927
1927
|
resolvedScriptPath = this._scriptPath;
|
|
1928
1928
|
}
|
|
1929
|
-
executableDir =
|
|
1930
|
-
|
|
1929
|
+
executableDir = path37.resolve(
|
|
1930
|
+
path37.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 = path37.basename(
|
|
1938
1938
|
this._scriptPath,
|
|
1939
|
-
|
|
1939
|
+
path37.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(path37.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 = path37.basename(filename, path37.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(path38) {
|
|
2805
|
+
if (path38 === void 0) return this._executableDir;
|
|
2806
|
+
this._executableDir = path38;
|
|
2807
2807
|
return this;
|
|
2808
2808
|
}
|
|
2809
2809
|
/**
|
|
@@ -7061,8 +7061,8 @@ var init_parseUtil = __esm({
|
|
|
7061
7061
|
init_errors();
|
|
7062
7062
|
init_en();
|
|
7063
7063
|
makeIssue = (params) => {
|
|
7064
|
-
const { data, path:
|
|
7065
|
-
const fullPath = [...
|
|
7064
|
+
const { data, path: path37, errorMaps, issueData } = params;
|
|
7065
|
+
const fullPath = [...path37, ...issueData.path || []];
|
|
7066
7066
|
const fullIssue = {
|
|
7067
7067
|
...issueData,
|
|
7068
7068
|
path: fullPath
|
|
@@ -7370,11 +7370,11 @@ var init_types = __esm({
|
|
|
7370
7370
|
init_parseUtil();
|
|
7371
7371
|
init_util();
|
|
7372
7372
|
ParseInputLazyPath = class {
|
|
7373
|
-
constructor(parent, value,
|
|
7373
|
+
constructor(parent, value, path37, key) {
|
|
7374
7374
|
this._cachedPath = [];
|
|
7375
7375
|
this.parent = parent;
|
|
7376
7376
|
this.data = value;
|
|
7377
|
-
this._path =
|
|
7377
|
+
this._path = path37;
|
|
7378
7378
|
this._key = key;
|
|
7379
7379
|
}
|
|
7380
7380
|
get path() {
|
|
@@ -11235,7 +11235,7 @@ var require_has_flag = __commonJS({
|
|
|
11235
11235
|
var require_supports_color = __commonJS({
|
|
11236
11236
|
"../../node_modules/.pnpm/supports-color@7.2.0/node_modules/supports-color/index.js"(exports, module) {
|
|
11237
11237
|
"use strict";
|
|
11238
|
-
var
|
|
11238
|
+
var os8 = __require("os");
|
|
11239
11239
|
var tty = __require("tty");
|
|
11240
11240
|
var hasFlag = require_has_flag();
|
|
11241
11241
|
var { env } = process;
|
|
@@ -11283,7 +11283,7 @@ var require_supports_color = __commonJS({
|
|
|
11283
11283
|
return min;
|
|
11284
11284
|
}
|
|
11285
11285
|
if (process.platform === "win32") {
|
|
11286
|
-
const osRelease =
|
|
11286
|
+
const osRelease = os8.release().split(".");
|
|
11287
11287
|
if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
|
|
11288
11288
|
return Number(osRelease[2]) >= 14931 ? 3 : 2;
|
|
11289
11289
|
}
|
|
@@ -11529,10 +11529,10 @@ var require_src2 = __commonJS({
|
|
|
11529
11529
|
var fs_1 = __require("fs");
|
|
11530
11530
|
var debug_1 = __importDefault(require_src());
|
|
11531
11531
|
var log2 = debug_1.default("@kwsites/file-exists");
|
|
11532
|
-
function check2(
|
|
11533
|
-
log2(`checking %s`,
|
|
11532
|
+
function check2(path37, isFile, isDirectory) {
|
|
11533
|
+
log2(`checking %s`, path37);
|
|
11534
11534
|
try {
|
|
11535
|
-
const stat3 = fs_1.statSync(
|
|
11535
|
+
const stat3 = fs_1.statSync(path37);
|
|
11536
11536
|
if (stat3.isFile() && isFile) {
|
|
11537
11537
|
log2(`[OK] path represents a file`);
|
|
11538
11538
|
return true;
|
|
@@ -11552,8 +11552,8 @@ var require_src2 = __commonJS({
|
|
|
11552
11552
|
throw e;
|
|
11553
11553
|
}
|
|
11554
11554
|
}
|
|
11555
|
-
function exists2(
|
|
11556
|
-
return check2(
|
|
11555
|
+
function exists2(path37, type = exports.READABLE) {
|
|
11556
|
+
return check2(path37, (type & exports.FILE) > 0, (type & exports.FOLDER) > 0);
|
|
11557
11557
|
}
|
|
11558
11558
|
exports.exists = exists2;
|
|
11559
11559
|
exports.FILE = 1;
|
|
@@ -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, path37) {
|
|
11854
|
+
if (!path37)
|
|
11855
11855
|
return obj;
|
|
11856
|
-
return
|
|
11856
|
+
return path37.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(path37, 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(path37);
|
|
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, path37 = []) => {
|
|
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 = [...path37, ...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(path37) {
|
|
12339
12339
|
const segs = [];
|
|
12340
|
-
for (const seg of
|
|
12340
|
+
for (const seg of path37) {
|
|
12341
12341
|
if (typeof seg === "number")
|
|
12342
12342
|
segs.push(`[${seg}]`);
|
|
12343
12343
|
else if (typeof seg === "symbol")
|
|
@@ -25064,15 +25064,15 @@ var {
|
|
|
25064
25064
|
} = import_index.default;
|
|
25065
25065
|
|
|
25066
25066
|
// src/cli-version.ts
|
|
25067
|
-
var CLI_VERSION = "0.1.
|
|
25067
|
+
var CLI_VERSION = "0.1.25".length > 0 ? "0.1.25" : "0.0.0-dev";
|
|
25068
25068
|
|
|
25069
25069
|
// src/cli/defaults.ts
|
|
25070
25070
|
var DEFAULT_API_URL = process.env.BUILDAUTOMATON_API_URL ?? "https://api.buildautomaton.com";
|
|
25071
25071
|
var DEFAULT_FIREHOSE_URL = "https://buildautomaton-firehose.fly.dev";
|
|
25072
25072
|
|
|
25073
25073
|
// src/cli/run-cli-action.ts
|
|
25074
|
-
import * as
|
|
25075
|
-
import * as
|
|
25074
|
+
import * as fs35 from "node:fs";
|
|
25075
|
+
import * as path36 from "node:path";
|
|
25076
25076
|
|
|
25077
25077
|
// src/cli-log-level.ts
|
|
25078
25078
|
var verbosity = "info";
|
|
@@ -25465,6 +25465,11 @@ function logImmediate(line) {
|
|
|
25465
25465
|
process.stdout.write(`${timestampPrefix()} ${line}
|
|
25466
25466
|
`);
|
|
25467
25467
|
}
|
|
25468
|
+
function logDebug(line) {
|
|
25469
|
+
const v = getCliLogVerbosity();
|
|
25470
|
+
if (v !== "debug" && v !== "trace") return;
|
|
25471
|
+
console.log(`${timestampPrefix()} [debug] ${line}`);
|
|
25472
|
+
}
|
|
25468
25473
|
function logTrace(line) {
|
|
25469
25474
|
if (getCliLogVerbosity() !== "trace") return;
|
|
25470
25475
|
console.log(`${timestampPrefix()} [trace] ${line}`);
|
|
@@ -27058,9 +27063,9 @@ function parseChangeSummaryJson(raw, allowedPaths, options) {
|
|
|
27058
27063
|
const rawPath = typeof o.path === "string" ? o.path.trim() : "";
|
|
27059
27064
|
const summary = typeof o.summary === "string" ? o.summary.trim() : "";
|
|
27060
27065
|
if (!rawPath || !summary) continue;
|
|
27061
|
-
const
|
|
27062
|
-
if (!
|
|
27063
|
-
rows.push({ path:
|
|
27066
|
+
const path37 = skip ? normalizeRepoRelativePath(rawPath) || rawPath : resolveChangeSummaryPathAgainstAllowed(rawPath, allowedPaths);
|
|
27067
|
+
if (!path37) continue;
|
|
27068
|
+
rows.push({ path: path37, summary: clampSummaryToAtMostTwoLines(summary) });
|
|
27064
27069
|
}
|
|
27065
27070
|
return rows;
|
|
27066
27071
|
}
|
|
@@ -27262,8 +27267,8 @@ function pathspec(...paths) {
|
|
|
27262
27267
|
cache.set(key, paths);
|
|
27263
27268
|
return key;
|
|
27264
27269
|
}
|
|
27265
|
-
function isPathSpec(
|
|
27266
|
-
return
|
|
27270
|
+
function isPathSpec(path37) {
|
|
27271
|
+
return path37 instanceof String && cache.has(path37);
|
|
27267
27272
|
}
|
|
27268
27273
|
function toPaths(pathSpec) {
|
|
27269
27274
|
return cache.get(pathSpec) || [];
|
|
@@ -27352,8 +27357,8 @@ function toLinesWithContent(input = "", trimmed2 = true, separator = "\n") {
|
|
|
27352
27357
|
function forEachLineWithContent(input, callback) {
|
|
27353
27358
|
return toLinesWithContent(input, true).map((line) => callback(line));
|
|
27354
27359
|
}
|
|
27355
|
-
function folderExists(
|
|
27356
|
-
return (0, import_file_exists.exists)(
|
|
27360
|
+
function folderExists(path37) {
|
|
27361
|
+
return (0, import_file_exists.exists)(path37, import_file_exists.FOLDER);
|
|
27357
27362
|
}
|
|
27358
27363
|
function append(target, item) {
|
|
27359
27364
|
if (Array.isArray(target)) {
|
|
@@ -27757,8 +27762,8 @@ function checkIsRepoRootTask() {
|
|
|
27757
27762
|
commands,
|
|
27758
27763
|
format: "utf-8",
|
|
27759
27764
|
onError,
|
|
27760
|
-
parser(
|
|
27761
|
-
return /^\.(git)?$/.test(
|
|
27765
|
+
parser(path37) {
|
|
27766
|
+
return /^\.(git)?$/.test(path37.trim());
|
|
27762
27767
|
}
|
|
27763
27768
|
};
|
|
27764
27769
|
}
|
|
@@ -28192,11 +28197,11 @@ function parseGrep(grep) {
|
|
|
28192
28197
|
const paths = /* @__PURE__ */ new Set();
|
|
28193
28198
|
const results = {};
|
|
28194
28199
|
forEachLineWithContent(grep, (input) => {
|
|
28195
|
-
const [
|
|
28196
|
-
paths.add(
|
|
28197
|
-
(results[
|
|
28200
|
+
const [path37, line, preview] = input.split(NULL);
|
|
28201
|
+
paths.add(path37);
|
|
28202
|
+
(results[path37] = results[path37] || []).push({
|
|
28198
28203
|
line: asNumber(line),
|
|
28199
|
-
path:
|
|
28204
|
+
path: path37,
|
|
28200
28205
|
preview
|
|
28201
28206
|
});
|
|
28202
28207
|
});
|
|
@@ -28961,14 +28966,14 @@ var init_hash_object = __esm2({
|
|
|
28961
28966
|
init_task();
|
|
28962
28967
|
}
|
|
28963
28968
|
});
|
|
28964
|
-
function parseInit(bare,
|
|
28969
|
+
function parseInit(bare, path37, text) {
|
|
28965
28970
|
const response = String(text).trim();
|
|
28966
28971
|
let result;
|
|
28967
28972
|
if (result = initResponseRegex.exec(response)) {
|
|
28968
|
-
return new InitSummary(bare,
|
|
28973
|
+
return new InitSummary(bare, path37, false, result[1]);
|
|
28969
28974
|
}
|
|
28970
28975
|
if (result = reInitResponseRegex.exec(response)) {
|
|
28971
|
-
return new InitSummary(bare,
|
|
28976
|
+
return new InitSummary(bare, path37, true, result[1]);
|
|
28972
28977
|
}
|
|
28973
28978
|
let gitDir = "";
|
|
28974
28979
|
const tokens = response.split(" ");
|
|
@@ -28979,7 +28984,7 @@ function parseInit(bare, path36, text) {
|
|
|
28979
28984
|
break;
|
|
28980
28985
|
}
|
|
28981
28986
|
}
|
|
28982
|
-
return new InitSummary(bare,
|
|
28987
|
+
return new InitSummary(bare, path37, /^re/i.test(response), gitDir);
|
|
28983
28988
|
}
|
|
28984
28989
|
var InitSummary;
|
|
28985
28990
|
var initResponseRegex;
|
|
@@ -28988,9 +28993,9 @@ var init_InitSummary = __esm2({
|
|
|
28988
28993
|
"src/lib/responses/InitSummary.ts"() {
|
|
28989
28994
|
"use strict";
|
|
28990
28995
|
InitSummary = class {
|
|
28991
|
-
constructor(bare,
|
|
28996
|
+
constructor(bare, path37, existing, gitDir) {
|
|
28992
28997
|
this.bare = bare;
|
|
28993
|
-
this.path =
|
|
28998
|
+
this.path = path37;
|
|
28994
28999
|
this.existing = existing;
|
|
28995
29000
|
this.gitDir = gitDir;
|
|
28996
29001
|
}
|
|
@@ -29002,7 +29007,7 @@ var init_InitSummary = __esm2({
|
|
|
29002
29007
|
function hasBareCommand(command) {
|
|
29003
29008
|
return command.includes(bareCommand);
|
|
29004
29009
|
}
|
|
29005
|
-
function initTask(bare = false,
|
|
29010
|
+
function initTask(bare = false, path37, customArgs) {
|
|
29006
29011
|
const commands = ["init", ...customArgs];
|
|
29007
29012
|
if (bare && !hasBareCommand(commands)) {
|
|
29008
29013
|
commands.splice(1, 0, bareCommand);
|
|
@@ -29011,7 +29016,7 @@ function initTask(bare = false, path36, customArgs) {
|
|
|
29011
29016
|
commands,
|
|
29012
29017
|
format: "utf-8",
|
|
29013
29018
|
parser(text) {
|
|
29014
|
-
return parseInit(commands.includes("--bare"),
|
|
29019
|
+
return parseInit(commands.includes("--bare"), path37, text);
|
|
29015
29020
|
}
|
|
29016
29021
|
};
|
|
29017
29022
|
}
|
|
@@ -29827,12 +29832,12 @@ var init_FileStatusSummary = __esm2({
|
|
|
29827
29832
|
"use strict";
|
|
29828
29833
|
fromPathRegex = /^(.+)\0(.+)$/;
|
|
29829
29834
|
FileStatusSummary = class {
|
|
29830
|
-
constructor(
|
|
29831
|
-
this.path =
|
|
29835
|
+
constructor(path37, index, working_dir) {
|
|
29836
|
+
this.path = path37;
|
|
29832
29837
|
this.index = index;
|
|
29833
29838
|
this.working_dir = working_dir;
|
|
29834
29839
|
if (index === "R" || working_dir === "R") {
|
|
29835
|
-
const detail = fromPathRegex.exec(
|
|
29840
|
+
const detail = fromPathRegex.exec(path37) || [null, path37, path37];
|
|
29836
29841
|
this.from = detail[2] || "";
|
|
29837
29842
|
this.path = detail[1] || "";
|
|
29838
29843
|
}
|
|
@@ -29863,14 +29868,14 @@ function splitLine(result, lineStr) {
|
|
|
29863
29868
|
default:
|
|
29864
29869
|
return;
|
|
29865
29870
|
}
|
|
29866
|
-
function data(index, workingDir,
|
|
29871
|
+
function data(index, workingDir, path37) {
|
|
29867
29872
|
const raw = `${index}${workingDir}`;
|
|
29868
29873
|
const handler = parsers6.get(raw);
|
|
29869
29874
|
if (handler) {
|
|
29870
|
-
handler(result,
|
|
29875
|
+
handler(result, path37);
|
|
29871
29876
|
}
|
|
29872
29877
|
if (raw !== "##" && raw !== "!!") {
|
|
29873
|
-
result.files.push(new FileStatusSummary(
|
|
29878
|
+
result.files.push(new FileStatusSummary(path37, index, workingDir));
|
|
29874
29879
|
}
|
|
29875
29880
|
}
|
|
29876
29881
|
}
|
|
@@ -30179,9 +30184,9 @@ var init_simple_git_api = __esm2({
|
|
|
30179
30184
|
next
|
|
30180
30185
|
);
|
|
30181
30186
|
}
|
|
30182
|
-
hashObject(
|
|
30187
|
+
hashObject(path37, write) {
|
|
30183
30188
|
return this._runTask(
|
|
30184
|
-
hashObjectTask(
|
|
30189
|
+
hashObjectTask(path37, write === true),
|
|
30185
30190
|
trailingFunctionArgument(arguments)
|
|
30186
30191
|
);
|
|
30187
30192
|
}
|
|
@@ -30534,8 +30539,8 @@ var init_branch = __esm2({
|
|
|
30534
30539
|
}
|
|
30535
30540
|
});
|
|
30536
30541
|
function toPath(input) {
|
|
30537
|
-
const
|
|
30538
|
-
return
|
|
30542
|
+
const path37 = input.trim().replace(/^["']|["']$/g, "");
|
|
30543
|
+
return path37 && normalize(path37);
|
|
30539
30544
|
}
|
|
30540
30545
|
var parseCheckIgnore;
|
|
30541
30546
|
var init_CheckIgnore = __esm2({
|
|
@@ -30849,8 +30854,8 @@ __export2(sub_module_exports, {
|
|
|
30849
30854
|
subModuleTask: () => subModuleTask,
|
|
30850
30855
|
updateSubModuleTask: () => updateSubModuleTask
|
|
30851
30856
|
});
|
|
30852
|
-
function addSubModuleTask(repo,
|
|
30853
|
-
return subModuleTask(["add", repo,
|
|
30857
|
+
function addSubModuleTask(repo, path37) {
|
|
30858
|
+
return subModuleTask(["add", repo, path37]);
|
|
30854
30859
|
}
|
|
30855
30860
|
function initSubModuleTask(customArgs) {
|
|
30856
30861
|
return subModuleTask(["init", ...customArgs]);
|
|
@@ -31183,8 +31188,8 @@ var require_git = __commonJS2({
|
|
|
31183
31188
|
}
|
|
31184
31189
|
return this._runTask(straightThroughStringTask2(command, this._trimmed), next);
|
|
31185
31190
|
};
|
|
31186
|
-
Git2.prototype.submoduleAdd = function(repo,
|
|
31187
|
-
return this._runTask(addSubModuleTask2(repo,
|
|
31191
|
+
Git2.prototype.submoduleAdd = function(repo, path37, then) {
|
|
31192
|
+
return this._runTask(addSubModuleTask2(repo, path37), trailingFunctionArgument2(arguments));
|
|
31188
31193
|
};
|
|
31189
31194
|
Git2.prototype.submoduleUpdate = function(args, then) {
|
|
31190
31195
|
return this._runTask(
|
|
@@ -32071,9 +32076,9 @@ async function collectTurnGitDiffFromPreTurnSnapshot(options) {
|
|
|
32071
32076
|
// src/agents/acp/put-summarize-change-summaries.ts
|
|
32072
32077
|
async function putEncryptedChangeSummaryRows(params) {
|
|
32073
32078
|
const base = params.apiBaseUrl.replace(/\/+$/, "");
|
|
32074
|
-
const entries = params.rows.map(({ path:
|
|
32079
|
+
const entries = params.rows.map(({ path: path37, summary }) => {
|
|
32075
32080
|
const enc = params.e2ee.encryptFields({ summary }, ["summary"]);
|
|
32076
|
-
return { path:
|
|
32081
|
+
return { path: path37, summary: JSON.stringify(enc) };
|
|
32077
32082
|
});
|
|
32078
32083
|
const res = await fetch(
|
|
32079
32084
|
`${base}/api/sessions/${encodeURIComponent(params.sessionId)}/follow-ups/summarize-changes`,
|
|
@@ -32255,8 +32260,8 @@ async function sendPromptToAgent(options) {
|
|
|
32255
32260
|
}
|
|
32256
32261
|
|
|
32257
32262
|
// src/agents/acp/ensure-acp-client.ts
|
|
32258
|
-
import * as
|
|
32259
|
-
import * as
|
|
32263
|
+
import * as fs11 from "node:fs";
|
|
32264
|
+
import * as path13 from "node:path";
|
|
32260
32265
|
|
|
32261
32266
|
// src/error-message.ts
|
|
32262
32267
|
function errorMessage(err) {
|
|
@@ -32292,76 +32297,10 @@ async function isCommandOnPath(command, timeoutMs = 4e3) {
|
|
|
32292
32297
|
}
|
|
32293
32298
|
}
|
|
32294
32299
|
|
|
32295
|
-
// src/agents/acp/clients/sdk-stdio-acp-client.ts
|
|
32300
|
+
// src/agents/acp/clients/sdk/sdk-stdio-acp-client.ts
|
|
32296
32301
|
import { spawn as spawn2 } from "node:child_process";
|
|
32297
|
-
import { mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
32298
|
-
import { dirname as dirname2 } from "node:path";
|
|
32299
32302
|
import { Readable, Writable } from "node:stream";
|
|
32300
32303
|
|
|
32301
|
-
// src/files/diff/unified-diff.ts
|
|
32302
|
-
function computeLineDiff(oldText, newText) {
|
|
32303
|
-
const oldLines = oldText.split("\n");
|
|
32304
|
-
const newLines = newText.split("\n");
|
|
32305
|
-
const m = oldLines.length;
|
|
32306
|
-
const n = newLines.length;
|
|
32307
|
-
const dp = Array(m + 1);
|
|
32308
|
-
for (let i2 = 0; i2 <= m; i2++) dp[i2] = Array(n + 1).fill(0);
|
|
32309
|
-
for (let i2 = 1; i2 <= m; i2++) {
|
|
32310
|
-
for (let j2 = 1; j2 <= n; j2++) {
|
|
32311
|
-
if (oldLines[i2 - 1] === newLines[j2 - 1]) {
|
|
32312
|
-
dp[i2][j2] = dp[i2 - 1][j2 - 1] + 1;
|
|
32313
|
-
} else {
|
|
32314
|
-
dp[i2][j2] = Math.max(dp[i2 - 1][j2], dp[i2][j2 - 1]);
|
|
32315
|
-
}
|
|
32316
|
-
}
|
|
32317
|
-
}
|
|
32318
|
-
const result = [];
|
|
32319
|
-
let i = m;
|
|
32320
|
-
let j = n;
|
|
32321
|
-
while (i > 0 || j > 0) {
|
|
32322
|
-
if (i > 0 && j > 0 && oldLines[i - 1] === newLines[j - 1]) {
|
|
32323
|
-
result.unshift({ type: "context", line: oldLines[i - 1] });
|
|
32324
|
-
i--;
|
|
32325
|
-
j--;
|
|
32326
|
-
} else if (j > 0 && (i === 0 || dp[i][j - 1] >= dp[i - 1][j])) {
|
|
32327
|
-
result.unshift({ type: "add", line: newLines[j - 1] });
|
|
32328
|
-
j--;
|
|
32329
|
-
} else {
|
|
32330
|
-
result.unshift({ type: "remove", line: oldLines[i - 1] });
|
|
32331
|
-
i--;
|
|
32332
|
-
}
|
|
32333
|
-
}
|
|
32334
|
-
return result;
|
|
32335
|
-
}
|
|
32336
|
-
function editSnippetToUnifiedDiff(filePath, oldText, newText) {
|
|
32337
|
-
const lines = computeLineDiff(oldText, newText);
|
|
32338
|
-
const out = [`--- ${filePath}`, `+++ ${filePath}`];
|
|
32339
|
-
for (const d of lines) {
|
|
32340
|
-
if (d.type === "add") out.push(`+${d.line}`);
|
|
32341
|
-
else if (d.type === "remove") out.push(`-${d.line}`);
|
|
32342
|
-
else out.push(` ${d.line}`);
|
|
32343
|
-
}
|
|
32344
|
-
return out.join("\n");
|
|
32345
|
-
}
|
|
32346
|
-
|
|
32347
|
-
// src/agents/acp/safe-fs-path.ts
|
|
32348
|
-
import * as path9 from "node:path";
|
|
32349
|
-
function resolveSafePathUnderCwd(cwd, filePath) {
|
|
32350
|
-
const trimmed2 = filePath.trim();
|
|
32351
|
-
if (!trimmed2) return null;
|
|
32352
|
-
const normalizedCwd = path9.resolve(cwd);
|
|
32353
|
-
const resolved = path9.isAbsolute(trimmed2) ? path9.normalize(trimmed2) : path9.resolve(normalizedCwd, trimmed2);
|
|
32354
|
-
const rel = path9.relative(normalizedCwd, resolved);
|
|
32355
|
-
if (rel.startsWith("..") || path9.isAbsolute(rel)) return null;
|
|
32356
|
-
return resolved;
|
|
32357
|
-
}
|
|
32358
|
-
function toDisplayPathRelativeToCwd(cwd, absolutePath) {
|
|
32359
|
-
const normalizedCwd = path9.resolve(cwd);
|
|
32360
|
-
const rel = path9.relative(normalizedCwd, path9.resolve(absolutePath));
|
|
32361
|
-
if (!rel || rel === "") return path9.basename(absolutePath);
|
|
32362
|
-
return rel.split(path9.sep).join("/");
|
|
32363
|
-
}
|
|
32364
|
-
|
|
32365
32304
|
// src/agents/acp/clients/agent-stderr-capture.ts
|
|
32366
32305
|
var STDERR_CAPTURE_MAX = 48e3;
|
|
32367
32306
|
function createStderrCapture(child) {
|
|
@@ -32426,7 +32365,7 @@ function createKiroSdkExtNotificationHandler(options) {
|
|
|
32426
32365
|
};
|
|
32427
32366
|
}
|
|
32428
32367
|
|
|
32429
|
-
// src/agents/acp/clients/sdk-stdio-ext-notifications.ts
|
|
32368
|
+
// src/agents/acp/clients/sdk/sdk-stdio-ext-notifications.ts
|
|
32430
32369
|
var noopExtNotification = async () => {
|
|
32431
32370
|
};
|
|
32432
32371
|
function createSdkStdioExtNotificationHandler(options) {
|
|
@@ -32485,23 +32424,364 @@ function enrichAcpPermissionRpcResultFromRequestParams(result, params) {
|
|
|
32485
32424
|
};
|
|
32486
32425
|
}
|
|
32487
32426
|
|
|
32488
|
-
// src/agents/acp/clients/
|
|
32489
|
-
|
|
32490
|
-
|
|
32491
|
-
|
|
32427
|
+
// src/agents/acp/clients/shared/acp-fs-read-write.ts
|
|
32428
|
+
import { mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
32429
|
+
import { dirname as dirname2 } from "node:path";
|
|
32430
|
+
|
|
32431
|
+
// src/files/diff/unified-diff.ts
|
|
32432
|
+
function computeLineDiff(oldText, newText) {
|
|
32433
|
+
const oldLines = oldText.split("\n");
|
|
32434
|
+
const newLines = newText.split("\n");
|
|
32435
|
+
const m = oldLines.length;
|
|
32436
|
+
const n = newLines.length;
|
|
32437
|
+
const dp = Array(m + 1);
|
|
32438
|
+
for (let i2 = 0; i2 <= m; i2++) dp[i2] = Array(n + 1).fill(0);
|
|
32439
|
+
for (let i2 = 1; i2 <= m; i2++) {
|
|
32440
|
+
for (let j2 = 1; j2 <= n; j2++) {
|
|
32441
|
+
if (oldLines[i2 - 1] === newLines[j2 - 1]) {
|
|
32442
|
+
dp[i2][j2] = dp[i2 - 1][j2 - 1] + 1;
|
|
32443
|
+
} else {
|
|
32444
|
+
dp[i2][j2] = Math.max(dp[i2 - 1][j2], dp[i2][j2 - 1]);
|
|
32445
|
+
}
|
|
32446
|
+
}
|
|
32492
32447
|
}
|
|
32493
|
-
|
|
32448
|
+
const result = [];
|
|
32449
|
+
let i = m;
|
|
32450
|
+
let j = n;
|
|
32451
|
+
while (i > 0 || j > 0) {
|
|
32452
|
+
if (i > 0 && j > 0 && oldLines[i - 1] === newLines[j - 1]) {
|
|
32453
|
+
result.unshift({ type: "context", line: oldLines[i - 1] });
|
|
32454
|
+
i--;
|
|
32455
|
+
j--;
|
|
32456
|
+
} else if (j > 0 && (i === 0 || dp[i][j - 1] >= dp[i - 1][j])) {
|
|
32457
|
+
result.unshift({ type: "add", line: newLines[j - 1] });
|
|
32458
|
+
j--;
|
|
32459
|
+
} else {
|
|
32460
|
+
result.unshift({ type: "remove", line: oldLines[i - 1] });
|
|
32461
|
+
i--;
|
|
32462
|
+
}
|
|
32463
|
+
}
|
|
32464
|
+
return result;
|
|
32494
32465
|
}
|
|
32495
|
-
function
|
|
32466
|
+
function editSnippetToUnifiedDiff(filePath, oldText, newText) {
|
|
32467
|
+
const lines = computeLineDiff(oldText, newText);
|
|
32468
|
+
const out = [`--- ${filePath}`, `+++ ${filePath}`];
|
|
32469
|
+
for (const d of lines) {
|
|
32470
|
+
if (d.type === "add") out.push(`+${d.line}`);
|
|
32471
|
+
else if (d.type === "remove") out.push(`-${d.line}`);
|
|
32472
|
+
else out.push(` ${d.line}`);
|
|
32473
|
+
}
|
|
32474
|
+
return out.join("\n");
|
|
32475
|
+
}
|
|
32476
|
+
|
|
32477
|
+
// src/agents/acp/safe-fs-path.ts
|
|
32478
|
+
import * as path9 from "node:path";
|
|
32479
|
+
function resolveSafePathUnderCwd(cwd, filePath) {
|
|
32480
|
+
const trimmed2 = filePath.trim();
|
|
32481
|
+
if (!trimmed2) return null;
|
|
32482
|
+
const normalizedCwd = path9.resolve(cwd);
|
|
32483
|
+
const resolved = path9.isAbsolute(trimmed2) ? path9.normalize(trimmed2) : path9.resolve(normalizedCwd, trimmed2);
|
|
32484
|
+
const rel = path9.relative(normalizedCwd, resolved);
|
|
32485
|
+
if (rel.startsWith("..") || path9.isAbsolute(rel)) return null;
|
|
32486
|
+
return resolved;
|
|
32487
|
+
}
|
|
32488
|
+
function toDisplayPathRelativeToCwd(cwd, absolutePath) {
|
|
32489
|
+
const normalizedCwd = path9.resolve(cwd);
|
|
32490
|
+
const rel = path9.relative(normalizedCwd, path9.resolve(absolutePath));
|
|
32491
|
+
if (!rel || rel === "") return path9.basename(absolutePath);
|
|
32492
|
+
return rel.split(path9.sep).join("/");
|
|
32493
|
+
}
|
|
32494
|
+
|
|
32495
|
+
// src/agents/acp/clients/shared/acp-fs-read-write.ts
|
|
32496
|
+
function sliceFileContentForAcp(content, line, limit) {
|
|
32496
32497
|
if (line == null && limit == null) return content;
|
|
32497
32498
|
const lines = content.split("\n");
|
|
32498
32499
|
const start = line != null && line > 0 ? line - 1 : 0;
|
|
32499
32500
|
const end = limit != null && limit > 0 ? start + limit : lines.length;
|
|
32500
32501
|
return lines.slice(start, end).join("\n");
|
|
32501
32502
|
}
|
|
32502
|
-
function
|
|
32503
|
+
function acpReadTextFileInProcess(ctx, filePath, line, limit) {
|
|
32504
|
+
const resolvedPath = resolveSafePathUnderCwd(ctx.cwd, filePath);
|
|
32505
|
+
if (!resolvedPath) throw new Error("Invalid or disallowed path");
|
|
32506
|
+
try {
|
|
32507
|
+
let content = readFileSync2(resolvedPath, "utf8");
|
|
32508
|
+
content = sliceFileContentForAcp(content, line, limit);
|
|
32509
|
+
return { content };
|
|
32510
|
+
} catch (e) {
|
|
32511
|
+
if (e.code === "ENOENT") return { content: "" };
|
|
32512
|
+
throw e;
|
|
32513
|
+
}
|
|
32514
|
+
}
|
|
32515
|
+
function acpWriteTextFileInProcess(ctx, filePath, newText) {
|
|
32516
|
+
const resolvedPath = resolveSafePathUnderCwd(ctx.cwd, filePath);
|
|
32517
|
+
if (!resolvedPath) throw new Error("Invalid or disallowed path");
|
|
32518
|
+
let oldText = "";
|
|
32519
|
+
try {
|
|
32520
|
+
oldText = readFileSync2(resolvedPath, "utf8");
|
|
32521
|
+
} catch (e) {
|
|
32522
|
+
if (e.code !== "ENOENT") throw e;
|
|
32523
|
+
}
|
|
32524
|
+
mkdirSync2(dirname2(resolvedPath), { recursive: true });
|
|
32525
|
+
writeFileSync2(resolvedPath, newText, "utf8");
|
|
32526
|
+
const displayPath = toDisplayPathRelativeToCwd(ctx.cwd, resolvedPath);
|
|
32527
|
+
const patchContent = editSnippetToUnifiedDiff(displayPath, oldText, newText);
|
|
32528
|
+
ctx.onFileChange?.({ path: displayPath, oldText, newText, patchContent });
|
|
32529
|
+
return {};
|
|
32530
|
+
}
|
|
32531
|
+
|
|
32532
|
+
// src/agents/acp/claude-acp-permission-from-session.ts
|
|
32533
|
+
function flattenSelectOptions(options) {
|
|
32534
|
+
if (options == null || options.length === 0) return [];
|
|
32535
|
+
const first2 = options[0];
|
|
32536
|
+
if (first2 != null && typeof first2 === "object" && "group" in first2 && first2.group != null) {
|
|
32537
|
+
return options.flatMap(
|
|
32538
|
+
(g) => Array.isArray(g.options) ? g.options : []
|
|
32539
|
+
);
|
|
32540
|
+
}
|
|
32541
|
+
return options;
|
|
32542
|
+
}
|
|
32543
|
+
function pickModeConfigOption(configOptions) {
|
|
32544
|
+
if (configOptions == null || configOptions.length === 0) return null;
|
|
32545
|
+
const byCategory = configOptions.find((o) => o.category === "mode");
|
|
32546
|
+
if (byCategory) return byCategory;
|
|
32547
|
+
return configOptions.find((o) => o.id === "mode") ?? null;
|
|
32548
|
+
}
|
|
32549
|
+
async function applyClaudePermissionFromAcpSession(params) {
|
|
32550
|
+
const { sessionId, agentConfig, configOptions, modes, setSessionConfigOption, setSessionMode, logDebug: logDebug2 } = params;
|
|
32551
|
+
const desiredMode = getClaudePermissionModeFromAgentConfig(agentConfig);
|
|
32552
|
+
if (desiredMode == null) return;
|
|
32553
|
+
const modeOpt = pickModeConfigOption(configOptions ?? null);
|
|
32554
|
+
if (modeOpt != null) {
|
|
32555
|
+
const flat = flattenSelectOptions(modeOpt.options);
|
|
32556
|
+
const allowed = flat.some((o) => o.value === desiredMode);
|
|
32557
|
+
if (allowed && modeOpt.currentValue !== desiredMode) {
|
|
32558
|
+
try {
|
|
32559
|
+
logDebug2(
|
|
32560
|
+
`[Agent] Claude Code: sending ACP session/set_config_option (permission mode) configId=${JSON.stringify(modeOpt.id)} value=${JSON.stringify(desiredMode)} was=${JSON.stringify(modeOpt.currentValue)} sessionId=${sessionId.slice(0, 8)}\u2026`
|
|
32561
|
+
);
|
|
32562
|
+
await setSessionConfigOption({ sessionId, configId: modeOpt.id, value: desiredMode });
|
|
32563
|
+
} catch (e) {
|
|
32564
|
+
logDebug2(
|
|
32565
|
+
`[Agent] Claude Code: session/set_config_option failed: ${e instanceof Error ? e.message : String(e)}`
|
|
32566
|
+
);
|
|
32567
|
+
}
|
|
32568
|
+
}
|
|
32569
|
+
return;
|
|
32570
|
+
}
|
|
32571
|
+
if (modes?.availableModes?.length) {
|
|
32572
|
+
const allowed = modes.availableModes.some((m) => m.id === desiredMode);
|
|
32573
|
+
if (allowed && desiredMode !== modes.currentModeId) {
|
|
32574
|
+
try {
|
|
32575
|
+
logDebug2(
|
|
32576
|
+
`[Agent] Claude Code: sending ACP session/set_mode (permission mode) modeId=${JSON.stringify(desiredMode)} was=${JSON.stringify(modes.currentModeId ?? null)} sessionId=${sessionId.slice(0, 8)}\u2026`
|
|
32577
|
+
);
|
|
32578
|
+
await setSessionMode({ sessionId, modeId: desiredMode });
|
|
32579
|
+
} catch (e) {
|
|
32580
|
+
logDebug2(`[Agent] Claude Code: session/set_mode failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
32581
|
+
}
|
|
32582
|
+
}
|
|
32583
|
+
}
|
|
32584
|
+
}
|
|
32585
|
+
|
|
32586
|
+
// src/agents/acp/clients/shared/config-options-for-permission.ts
|
|
32587
|
+
function configOptionsForPermission(getActive, established) {
|
|
32588
|
+
const mem = getActive?.();
|
|
32589
|
+
if (Array.isArray(mem) && mem.length > 0) return mem;
|
|
32590
|
+
return established ?? void 0;
|
|
32591
|
+
}
|
|
32592
|
+
|
|
32593
|
+
// src/agents/acp/clients/shared/establish-acp-session.ts
|
|
32594
|
+
function establishedFromResult(raw, sessionId) {
|
|
32595
|
+
const r = raw && typeof raw === "object" ? raw : {};
|
|
32596
|
+
return {
|
|
32597
|
+
sessionId,
|
|
32598
|
+
configOptions: Array.isArray(r.configOptions) ? r.configOptions : null,
|
|
32599
|
+
modes: r.modes ?? null
|
|
32600
|
+
};
|
|
32601
|
+
}
|
|
32602
|
+
function sessionIdFromNewSessionResult(raw) {
|
|
32603
|
+
const r = raw && typeof raw === "object" ? raw : {};
|
|
32604
|
+
return typeof r.sessionId === "string" ? r.sessionId : "";
|
|
32605
|
+
}
|
|
32606
|
+
async function establishAcpSessionWithTransport(transport, ctx, canResume, canLoad) {
|
|
32607
|
+
const { cwd, mcpServers, persistedAcpSessionId, agentLabel, suppressLoadReplay } = ctx;
|
|
32608
|
+
const prev = typeof persistedAcpSessionId === "string" && persistedAcpSessionId.trim() !== "" ? persistedAcpSessionId.trim() : "";
|
|
32609
|
+
if (prev) {
|
|
32610
|
+
if (canResume) {
|
|
32611
|
+
try {
|
|
32612
|
+
logDebug(`[Agent] ${agentLabel} ACP session/resume for stored session ${prev.slice(0, 8)}\u2026`);
|
|
32613
|
+
const result2 = await transport.resumeSession({ sessionId: prev, cwd, mcpServers });
|
|
32614
|
+
return establishedFromResult(result2, prev);
|
|
32615
|
+
} catch (e) {
|
|
32616
|
+
logDebug(`[Agent] ${agentLabel} ACP session/resume failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
32617
|
+
}
|
|
32618
|
+
}
|
|
32619
|
+
if (canLoad) {
|
|
32620
|
+
suppressLoadReplay.value = true;
|
|
32621
|
+
try {
|
|
32622
|
+
logDebug(`[Agent] ${agentLabel} ACP session/load for stored session ${prev.slice(0, 8)}\u2026`);
|
|
32623
|
+
const result2 = await transport.loadSession({ sessionId: prev, cwd, mcpServers });
|
|
32624
|
+
return establishedFromResult(result2, prev);
|
|
32625
|
+
} catch (e) {
|
|
32626
|
+
logDebug(`[Agent] ${agentLabel} ACP session/load failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
32627
|
+
} finally {
|
|
32628
|
+
suppressLoadReplay.value = false;
|
|
32629
|
+
}
|
|
32630
|
+
}
|
|
32631
|
+
}
|
|
32632
|
+
const result = await transport.newSession({ cwd, mcpServers });
|
|
32633
|
+
const sid = sessionIdFromNewSessionResult(result);
|
|
32634
|
+
if (!sid) throw new Error(`${agentLabel} ACP session/new did not return sessionId`);
|
|
32635
|
+
return establishedFromResult(result, sid);
|
|
32636
|
+
}
|
|
32637
|
+
|
|
32638
|
+
// src/agents/acp/clients/shared/parse-acp-init-capabilities.ts
|
|
32639
|
+
function parseAcpInitAgentCapabilities(initResult) {
|
|
32640
|
+
const agentCapabilities = initResult?.agentCapabilities;
|
|
32641
|
+
const canLoad = agentCapabilities?.loadSession === true;
|
|
32642
|
+
const sessionCaps = agentCapabilities?.sessionCapabilities;
|
|
32643
|
+
const canResume = Boolean(sessionCaps?.resume);
|
|
32644
|
+
return { canResume, canLoad };
|
|
32645
|
+
}
|
|
32646
|
+
|
|
32647
|
+
// src/agents/acp/clients/shared/bootstrap-acp-wire-session.ts
|
|
32648
|
+
async function bootstrapAcpWireSession(transport, ctx, initializeRequest) {
|
|
32649
|
+
const initResult = await transport.initialize(initializeRequest);
|
|
32650
|
+
const { canResume, canLoad } = parseAcpInitAgentCapabilities(initResult);
|
|
32651
|
+
await transport.afterInitialize?.();
|
|
32652
|
+
const established = await establishAcpSessionWithTransport(transport, ctx, canResume, canLoad);
|
|
32653
|
+
const sessionId = established.sessionId;
|
|
32654
|
+
ctx.onAcpSessionEstablished?.({
|
|
32655
|
+
acpSessionId: sessionId,
|
|
32656
|
+
configOptions: established.configOptions,
|
|
32657
|
+
modes: established.modes
|
|
32658
|
+
});
|
|
32659
|
+
if (ctx.backendAgentType === "claude-code") {
|
|
32660
|
+
const cfg = ctx.agentConfig != null && typeof ctx.agentConfig === "object" && !Array.isArray(ctx.agentConfig) ? ctx.agentConfig : null;
|
|
32661
|
+
const configOptionsTyped = established.configOptions;
|
|
32662
|
+
const modesTyped = established.modes;
|
|
32663
|
+
await applyClaudePermissionFromAcpSession({
|
|
32664
|
+
sessionId,
|
|
32665
|
+
agentConfig: cfg,
|
|
32666
|
+
configOptions: configOptionsForPermission(ctx.getActiveConfigOptions, configOptionsTyped),
|
|
32667
|
+
modes: modesTyped,
|
|
32668
|
+
setSessionConfigOption: transport.setSessionConfigOption ? (p) => transport.setSessionConfigOption(p) : async () => {
|
|
32669
|
+
},
|
|
32670
|
+
setSessionMode: transport.setSessionMode ? (p) => transport.setSessionMode(p) : async () => {
|
|
32671
|
+
},
|
|
32672
|
+
logDebug: ctx.logDebug
|
|
32673
|
+
});
|
|
32674
|
+
}
|
|
32675
|
+
return established;
|
|
32676
|
+
}
|
|
32677
|
+
|
|
32678
|
+
// src/agents/acp/clients/shared/dispatch-session-update.ts
|
|
32679
|
+
function dispatchAcpSessionUpdate(opts) {
|
|
32680
|
+
const { flatPayload, onAcpConfigOptionsUpdated, onSessionUpdate, suppressLoadReplay } = opts;
|
|
32681
|
+
const su = flatPayload.sessionUpdate ?? flatPayload.session_update;
|
|
32682
|
+
if (su === "config_option_update") {
|
|
32683
|
+
const co = flatPayload.configOptions;
|
|
32684
|
+
if (Array.isArray(co)) onAcpConfigOptionsUpdated?.(co);
|
|
32685
|
+
return;
|
|
32686
|
+
}
|
|
32687
|
+
if (suppressLoadReplay()) return;
|
|
32688
|
+
onSessionUpdate?.(flatPayload);
|
|
32689
|
+
}
|
|
32690
|
+
|
|
32691
|
+
// src/agents/acp/clients/shared/flatten-sdk-session-notification.ts
|
|
32692
|
+
function flattenSdkSessionNotificationParams(params) {
|
|
32503
32693
|
return { sessionId: params.sessionId, ...params.update };
|
|
32504
32694
|
}
|
|
32695
|
+
|
|
32696
|
+
// src/agents/acp/clients/shared/normalize-acp-prompt-result.ts
|
|
32697
|
+
function normalizeAcpPromptTurnSuccess(opts) {
|
|
32698
|
+
const { stopReason, output, stderrCaptureText, backendAgentType } = opts;
|
|
32699
|
+
const mergedOutput = output || void 0;
|
|
32700
|
+
const stop = (stopReason ?? "").toLowerCase();
|
|
32701
|
+
const cancelled = stop === "cancelled";
|
|
32702
|
+
const refusal = stop === "refusal";
|
|
32703
|
+
const stderrEvaluated = Boolean(stderrCaptureText && backendAgentType);
|
|
32704
|
+
const stderrSuggestsAuth = stderrEvaluated ? localAgentErrorSuggestsAuth(backendAgentType, stderrCaptureText) : false;
|
|
32705
|
+
if (cancelled) {
|
|
32706
|
+
return {
|
|
32707
|
+
success: false,
|
|
32708
|
+
stopReason,
|
|
32709
|
+
output: mergedOutput,
|
|
32710
|
+
error: mergeErrorWithStderr("Stopped by user", stderrCaptureText)
|
|
32711
|
+
};
|
|
32712
|
+
}
|
|
32713
|
+
if (refusal) {
|
|
32714
|
+
return {
|
|
32715
|
+
success: false,
|
|
32716
|
+
stopReason,
|
|
32717
|
+
output: mergedOutput,
|
|
32718
|
+
error: mergeErrorWithStderr("The agent refused the request.", stderrCaptureText)
|
|
32719
|
+
};
|
|
32720
|
+
}
|
|
32721
|
+
if (stderrSuggestsAuth) {
|
|
32722
|
+
return {
|
|
32723
|
+
success: false,
|
|
32724
|
+
stopReason,
|
|
32725
|
+
output: mergedOutput,
|
|
32726
|
+
error: stderrCaptureText
|
|
32727
|
+
};
|
|
32728
|
+
}
|
|
32729
|
+
return {
|
|
32730
|
+
success: true,
|
|
32731
|
+
stopReason,
|
|
32732
|
+
output: mergedOutput
|
|
32733
|
+
};
|
|
32734
|
+
}
|
|
32735
|
+
function normalizeAcpPromptTurnFailure(err, stderrCaptureText) {
|
|
32736
|
+
const merged = mergeErrorWithStderr(formatJsonRpcStyleError(err), stderrCaptureText);
|
|
32737
|
+
return { success: false, error: merged };
|
|
32738
|
+
}
|
|
32739
|
+
|
|
32740
|
+
// src/agents/acp/clients/shared/send-acp-prompt-via-transport.ts
|
|
32741
|
+
async function sendAcpPromptViaTransport(transport, ctx, sessionId, promptText) {
|
|
32742
|
+
try {
|
|
32743
|
+
const response = await transport.prompt({
|
|
32744
|
+
sessionId,
|
|
32745
|
+
prompt: [{ type: "text", text: promptText }]
|
|
32746
|
+
});
|
|
32747
|
+
await new Promise((r2) => setImmediate(r2));
|
|
32748
|
+
const r = response;
|
|
32749
|
+
return normalizeAcpPromptTurnSuccess({
|
|
32750
|
+
stopReason: r?.stopReason,
|
|
32751
|
+
output: r?.output,
|
|
32752
|
+
stderrCaptureText: ctx.getStderrText(),
|
|
32753
|
+
backendAgentType: ctx.backendAgentType
|
|
32754
|
+
});
|
|
32755
|
+
} catch (err) {
|
|
32756
|
+
await new Promise((r) => setImmediate(r));
|
|
32757
|
+
return normalizeAcpPromptTurnFailure(err, ctx.getStderrText());
|
|
32758
|
+
}
|
|
32759
|
+
}
|
|
32760
|
+
|
|
32761
|
+
// src/agents/acp/clients/sdk/sdk-acp-session-transport.ts
|
|
32762
|
+
function createSdkAcpSessionTransport(connection) {
|
|
32763
|
+
const c = connection;
|
|
32764
|
+
return {
|
|
32765
|
+
initialize: (request) => c.initialize(request),
|
|
32766
|
+
resumeSession: (p) => c.unstable_resumeSession(p),
|
|
32767
|
+
loadSession: (p) => c.loadSession(p),
|
|
32768
|
+
newSession: (p) => c.newSession(p),
|
|
32769
|
+
prompt: (p) => c.prompt(p),
|
|
32770
|
+
cancelSession: async (sessionId) => {
|
|
32771
|
+
await c.cancel({ sessionId });
|
|
32772
|
+
},
|
|
32773
|
+
setSessionConfigOption: c.setSessionConfigOption ? (p) => c.setSessionConfigOption(p) : void 0,
|
|
32774
|
+
setSessionMode: c.setSessionMode ? (p) => c.setSessionMode(p) : void 0
|
|
32775
|
+
};
|
|
32776
|
+
}
|
|
32777
|
+
|
|
32778
|
+
// src/agents/acp/clients/sdk/sdk-stdio-acp-client.ts
|
|
32779
|
+
function formatSpawnError(err, command) {
|
|
32780
|
+
if (err.code === "ENOENT") {
|
|
32781
|
+
return `Command "${command}" not found. Install the agent (e.g. Cursor CLI) or add it to PATH.`;
|
|
32782
|
+
}
|
|
32783
|
+
return err.message || String(err);
|
|
32784
|
+
}
|
|
32505
32785
|
async function createSdkStdioAcpClient(options) {
|
|
32506
32786
|
const { ClientSideConnection: ClientSideConnection2, ndJsonStream: ndJsonStream2, PROTOCOL_VERSION: PROTOCOL_VERSION2 } = await Promise.resolve().then(() => (init_acp(), acp_exports));
|
|
32507
32787
|
const {
|
|
@@ -32513,7 +32793,11 @@ async function createSdkStdioAcpClient(options) {
|
|
|
32513
32793
|
onFileChange,
|
|
32514
32794
|
killSubprocessAfterCancelMs,
|
|
32515
32795
|
onAgentSubprocessExit,
|
|
32516
|
-
agentConfig
|
|
32796
|
+
agentConfig,
|
|
32797
|
+
persistedAcpSessionId,
|
|
32798
|
+
onAcpSessionEstablished,
|
|
32799
|
+
onAcpConfigOptionsUpdated,
|
|
32800
|
+
getActiveConfigOptions
|
|
32517
32801
|
} = options;
|
|
32518
32802
|
const isWindows = process.platform === "win32";
|
|
32519
32803
|
const child = spawn2(command[0], command.slice(1), {
|
|
@@ -32562,6 +32846,22 @@ async function createSdkStdioAcpClient(options) {
|
|
|
32562
32846
|
backendAgentType,
|
|
32563
32847
|
onSessionUpdate
|
|
32564
32848
|
});
|
|
32849
|
+
const suppressLoadReplayRef = { value: false };
|
|
32850
|
+
const sessionCtx = {
|
|
32851
|
+
cwd,
|
|
32852
|
+
onFileChange,
|
|
32853
|
+
mcpServers: [],
|
|
32854
|
+
persistedAcpSessionId,
|
|
32855
|
+
agentLabel: "ACP",
|
|
32856
|
+
suppressLoadReplay: suppressLoadReplayRef,
|
|
32857
|
+
backendAgentType: backendAgentType ?? null,
|
|
32858
|
+
agentConfig,
|
|
32859
|
+
getActiveConfigOptions,
|
|
32860
|
+
onAcpSessionEstablished,
|
|
32861
|
+
onAcpConfigOptionsUpdated,
|
|
32862
|
+
logDebug,
|
|
32863
|
+
getStderrText: () => stderrCapture.getText()
|
|
32864
|
+
};
|
|
32565
32865
|
let permissionSeq = 0;
|
|
32566
32866
|
const pendingPermissionReplies = /* @__PURE__ */ new Map();
|
|
32567
32867
|
const client = (_agent) => ({
|
|
@@ -32581,35 +32881,19 @@ async function createSdkStdioAcpClient(options) {
|
|
|
32581
32881
|
});
|
|
32582
32882
|
},
|
|
32583
32883
|
async readTextFile(params) {
|
|
32584
|
-
|
|
32585
|
-
if (!resolvedPath) throw new Error("Invalid or disallowed path");
|
|
32586
|
-
try {
|
|
32587
|
-
let content = readFileSync2(resolvedPath, "utf8");
|
|
32588
|
-
content = sliceFileContentRange(content, params.line, params.limit);
|
|
32589
|
-
return { content };
|
|
32590
|
-
} catch (e) {
|
|
32591
|
-
if (e.code === "ENOENT") return { content: "" };
|
|
32592
|
-
throw e;
|
|
32593
|
-
}
|
|
32884
|
+
return acpReadTextFileInProcess(sessionCtx, params.path, params.line, params.limit);
|
|
32594
32885
|
},
|
|
32595
32886
|
async writeTextFile(params) {
|
|
32596
|
-
|
|
32597
|
-
if (!resolvedPath) throw new Error("Invalid or disallowed path");
|
|
32598
|
-
let oldText = "";
|
|
32599
|
-
try {
|
|
32600
|
-
oldText = readFileSync2(resolvedPath, "utf8");
|
|
32601
|
-
} catch (e) {
|
|
32602
|
-
if (e.code !== "ENOENT") throw e;
|
|
32603
|
-
}
|
|
32604
|
-
mkdirSync2(dirname2(resolvedPath), { recursive: true });
|
|
32605
|
-
writeFileSync2(resolvedPath, params.content, "utf8");
|
|
32606
|
-
const displayPath = toDisplayPathRelativeToCwd(cwd, resolvedPath);
|
|
32607
|
-
const patchContent = editSnippetToUnifiedDiff(displayPath, oldText, params.content);
|
|
32608
|
-
onFileChange?.({ path: displayPath, oldText, newText: params.content, patchContent });
|
|
32609
|
-
return {};
|
|
32887
|
+
return acpWriteTextFileInProcess(sessionCtx, params.path, params.content);
|
|
32610
32888
|
},
|
|
32611
32889
|
async sessionUpdate(params) {
|
|
32612
|
-
|
|
32890
|
+
const bridged = flattenSdkSessionNotificationParams(params);
|
|
32891
|
+
dispatchAcpSessionUpdate({
|
|
32892
|
+
flatPayload: bridged,
|
|
32893
|
+
onAcpConfigOptionsUpdated: sessionCtx.onAcpConfigOptionsUpdated,
|
|
32894
|
+
onSessionUpdate,
|
|
32895
|
+
suppressLoadReplay: () => sessionCtx.suppressLoadReplay.value
|
|
32896
|
+
});
|
|
32613
32897
|
},
|
|
32614
32898
|
async extNotification(method, params) {
|
|
32615
32899
|
await extNotification(method, params);
|
|
@@ -32619,84 +32903,19 @@ async function createSdkStdioAcpClient(options) {
|
|
|
32619
32903
|
connection.signal.addEventListener("abort", () => {
|
|
32620
32904
|
child.kill();
|
|
32621
32905
|
});
|
|
32622
|
-
|
|
32906
|
+
const transport = createSdkAcpSessionTransport(connection);
|
|
32907
|
+
const established = await bootstrapAcpWireSession(transport, sessionCtx, {
|
|
32623
32908
|
protocolVersion: PROTOCOL_VERSION2,
|
|
32624
32909
|
clientCapabilities: {
|
|
32625
32910
|
fs: { readTextFile: true, writeTextFile: true }
|
|
32626
32911
|
},
|
|
32627
32912
|
clientInfo: { name: "buildautomaton-cli", version: "0.1.0" }
|
|
32628
32913
|
});
|
|
32629
|
-
const
|
|
32630
|
-
const sessionId = newSessionRes.sessionId;
|
|
32631
|
-
if (backendAgentType === "claude-code") {
|
|
32632
|
-
const cfg = agentConfig != null && typeof agentConfig === "object" && !Array.isArray(agentConfig) ? agentConfig : null;
|
|
32633
|
-
const desiredMode = getClaudePermissionModeFromAgentConfig(cfg);
|
|
32634
|
-
const modes = newSessionRes.modes;
|
|
32635
|
-
if (desiredMode != null && modes?.availableModes?.length) {
|
|
32636
|
-
const allowed = modes.availableModes.some((m) => m.id === desiredMode);
|
|
32637
|
-
if (allowed && desiredMode !== modes.currentModeId) {
|
|
32638
|
-
try {
|
|
32639
|
-
await connection.setSessionMode({ sessionId, modeId: desiredMode });
|
|
32640
|
-
} catch {
|
|
32641
|
-
}
|
|
32642
|
-
}
|
|
32643
|
-
}
|
|
32644
|
-
}
|
|
32914
|
+
const sessionId = established.sessionId;
|
|
32645
32915
|
settleResolve({
|
|
32646
32916
|
sessionId,
|
|
32647
32917
|
async sendPrompt(prompt, _options) {
|
|
32648
|
-
|
|
32649
|
-
const response = await connection.prompt({
|
|
32650
|
-
sessionId,
|
|
32651
|
-
prompt: [{ type: "text", text: prompt }]
|
|
32652
|
-
});
|
|
32653
|
-
await new Promise((r2) => setImmediate(r2));
|
|
32654
|
-
const r = response;
|
|
32655
|
-
const stopReason = (r?.stopReason ?? "").toLowerCase();
|
|
32656
|
-
const cancelled = stopReason === "cancelled";
|
|
32657
|
-
const refusal = stopReason === "refusal";
|
|
32658
|
-
const stderrAfter = stderrCapture.getText();
|
|
32659
|
-
const agentType = backendAgentType ?? null;
|
|
32660
|
-
const stderrEvaluated = Boolean(stderrAfter && agentType);
|
|
32661
|
-
const stderrSuggestsAuth = stderrEvaluated ? localAgentErrorSuggestsAuth(agentType, stderrAfter) : false;
|
|
32662
|
-
if (cancelled) {
|
|
32663
|
-
return {
|
|
32664
|
-
success: false,
|
|
32665
|
-
stopReason: r?.stopReason,
|
|
32666
|
-
output: r?.output,
|
|
32667
|
-
error: mergeErrorWithStderr("Stopped by user", stderrAfter)
|
|
32668
|
-
};
|
|
32669
|
-
}
|
|
32670
|
-
if (refusal) {
|
|
32671
|
-
return {
|
|
32672
|
-
success: false,
|
|
32673
|
-
stopReason: r?.stopReason,
|
|
32674
|
-
output: r?.output,
|
|
32675
|
-
error: mergeErrorWithStderr("The agent refused the request.", stderrAfter)
|
|
32676
|
-
};
|
|
32677
|
-
}
|
|
32678
|
-
if (stderrSuggestsAuth) {
|
|
32679
|
-
return {
|
|
32680
|
-
success: false,
|
|
32681
|
-
stopReason: r?.stopReason,
|
|
32682
|
-
output: r?.output,
|
|
32683
|
-
error: stderrAfter
|
|
32684
|
-
};
|
|
32685
|
-
}
|
|
32686
|
-
return {
|
|
32687
|
-
success: true,
|
|
32688
|
-
stopReason: r?.stopReason,
|
|
32689
|
-
output: r?.output
|
|
32690
|
-
};
|
|
32691
|
-
} catch (err) {
|
|
32692
|
-
await new Promise((r) => setImmediate(r));
|
|
32693
|
-
const stderrAfter = stderrCapture.getText();
|
|
32694
|
-
const merged = mergeErrorWithStderr(formatJsonRpcStyleError(err), stderrAfter);
|
|
32695
|
-
return {
|
|
32696
|
-
success: false,
|
|
32697
|
-
error: merged
|
|
32698
|
-
};
|
|
32699
|
-
}
|
|
32918
|
+
return sendAcpPromptViaTransport(transport, sessionCtx, sessionId, prompt);
|
|
32700
32919
|
},
|
|
32701
32920
|
async cancel() {
|
|
32702
32921
|
for (const [id, entry] of [...pendingPermissionReplies.entries()]) {
|
|
@@ -32704,7 +32923,7 @@ async function createSdkStdioAcpClient(options) {
|
|
|
32704
32923
|
entry.resolve({ outcome: { outcome: "cancelled" } });
|
|
32705
32924
|
}
|
|
32706
32925
|
try {
|
|
32707
|
-
await
|
|
32926
|
+
await transport.cancelSession(sessionId);
|
|
32708
32927
|
} catch {
|
|
32709
32928
|
}
|
|
32710
32929
|
if (killSubprocessAfterCancelMs != null && killSubprocessAfterCancelMs >= 0) {
|
|
@@ -32795,7 +33014,7 @@ async function createCodexAcpClient(options) {
|
|
|
32795
33014
|
return createSdkStdioAcpClient({ ...options, command });
|
|
32796
33015
|
}
|
|
32797
33016
|
|
|
32798
|
-
// src/agents/acp/clients/cursor-acp-client.ts
|
|
33017
|
+
// src/agents/acp/clients/cursor/cursor-acp-client.ts
|
|
32799
33018
|
var cursor_acp_client_exports = {};
|
|
32800
33019
|
__export(cursor_acp_client_exports, {
|
|
32801
33020
|
BACKEND_LOCAL_AGENT_TYPE: () => BACKEND_LOCAL_AGENT_TYPE3,
|
|
@@ -32803,8 +33022,6 @@ __export(cursor_acp_client_exports, {
|
|
|
32803
33022
|
createCursorAcpClient: () => createCursorAcpClient,
|
|
32804
33023
|
detectLocalAgentPresence: () => detectLocalAgentPresence3
|
|
32805
33024
|
});
|
|
32806
|
-
import { readFileSync as readFileSync3, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3 } from "node:fs";
|
|
32807
|
-
import { dirname as dirname3 } from "node:path";
|
|
32808
33025
|
import { spawn as spawn3 } from "node:child_process";
|
|
32809
33026
|
import * as readline from "node:readline";
|
|
32810
33027
|
|
|
@@ -32821,7 +33038,23 @@ function formatSessionUpdateKindForLog(kind) {
|
|
|
32821
33038
|
return kind.split("_").filter(Boolean).map((w) => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase()).join(" ");
|
|
32822
33039
|
}
|
|
32823
33040
|
|
|
32824
|
-
// src/agents/acp/clients/cursor-acp-
|
|
33041
|
+
// src/agents/acp/clients/cursor/cursor-json-rpc-acp-transport.ts
|
|
33042
|
+
function createCursorJsonRpcAcpTransport(deps) {
|
|
33043
|
+
const { send, cancelSessionNotification } = deps;
|
|
33044
|
+
return {
|
|
33045
|
+
initialize: (request) => send("initialize", request),
|
|
33046
|
+
afterInitialize: async () => {
|
|
33047
|
+
await send("authenticate", { methodId: "cursor_login" });
|
|
33048
|
+
},
|
|
33049
|
+
resumeSession: (p) => send("session/resume", p),
|
|
33050
|
+
loadSession: (p) => send("session/load", p),
|
|
33051
|
+
newSession: (p) => send("session/new", p),
|
|
33052
|
+
prompt: (p) => send("session/prompt", p),
|
|
33053
|
+
cancelSession: (sessionId) => cancelSessionNotification(sessionId)
|
|
33054
|
+
};
|
|
33055
|
+
}
|
|
33056
|
+
|
|
33057
|
+
// src/agents/acp/clients/cursor/cursor-acp-client.ts
|
|
32825
33058
|
var FS_READ_METHODS = /* @__PURE__ */ new Set(["fs/read_text_file", "fs/readTextFile"]);
|
|
32826
33059
|
var FS_WRITE_METHODS = /* @__PURE__ */ new Set(["fs/write_text_file", "fs/writeTextFile"]);
|
|
32827
33060
|
function formatSpawnError2(err, command) {
|
|
@@ -32838,13 +33071,6 @@ function safeJsonParse(value) {
|
|
|
32838
33071
|
return null;
|
|
32839
33072
|
}
|
|
32840
33073
|
}
|
|
32841
|
-
function sliceLinesByRange(content, line, limit) {
|
|
32842
|
-
if (line == null && limit == null) return content;
|
|
32843
|
-
const lines = content.split("\n");
|
|
32844
|
-
const start = line != null && line > 0 ? line - 1 : 0;
|
|
32845
|
-
const end = limit != null && limit > 0 ? start + limit : lines.length;
|
|
32846
|
-
return lines.slice(start, end).join("\n");
|
|
32847
|
-
}
|
|
32848
33074
|
function buildCursorAcpSpawnCommand(base, sessionMode) {
|
|
32849
33075
|
if (!sessionMode) return [...base];
|
|
32850
33076
|
const m = sessionMode.trim();
|
|
@@ -32858,7 +33084,11 @@ async function createCursorAcpClient(options) {
|
|
|
32858
33084
|
backendAgentType,
|
|
32859
33085
|
onSessionUpdate,
|
|
32860
33086
|
onRequest,
|
|
32861
|
-
onFileChange
|
|
33087
|
+
onFileChange,
|
|
33088
|
+
persistedAcpSessionId,
|
|
33089
|
+
onAcpSessionEstablished,
|
|
33090
|
+
onAcpConfigOptionsUpdated,
|
|
33091
|
+
onAgentSubprocessExit
|
|
32862
33092
|
} = options;
|
|
32863
33093
|
const dbgFs = process.env.BUILDAUTOMATON_DEBUG_ACP_FS === "1";
|
|
32864
33094
|
const isWindows = process.platform === "win32";
|
|
@@ -32870,6 +33100,25 @@ async function createCursorAcpClient(options) {
|
|
|
32870
33100
|
});
|
|
32871
33101
|
const stderrCapture = createStderrCapture(child);
|
|
32872
33102
|
child.stderr?.on("data", (chunk) => stderrCapture.append(chunk));
|
|
33103
|
+
child.once("close", (code, signal) => {
|
|
33104
|
+
onAgentSubprocessExit?.({ code, signal });
|
|
33105
|
+
});
|
|
33106
|
+
const suppressLoadReplayRef = { value: false };
|
|
33107
|
+
const sessionCtx = {
|
|
33108
|
+
cwd,
|
|
33109
|
+
onFileChange,
|
|
33110
|
+
mcpServers: [],
|
|
33111
|
+
persistedAcpSessionId,
|
|
33112
|
+
agentLabel: "Cursor",
|
|
33113
|
+
suppressLoadReplay: suppressLoadReplayRef,
|
|
33114
|
+
backendAgentType: backendAgentType ?? null,
|
|
33115
|
+
agentConfig: options.agentConfig,
|
|
33116
|
+
getActiveConfigOptions: options.getActiveConfigOptions,
|
|
33117
|
+
onAcpSessionEstablished,
|
|
33118
|
+
onAcpConfigOptionsUpdated,
|
|
33119
|
+
logDebug,
|
|
33120
|
+
getStderrText: () => stderrCapture.getText()
|
|
33121
|
+
};
|
|
32873
33122
|
return new Promise((resolve18, reject) => {
|
|
32874
33123
|
child.on("error", (err) => {
|
|
32875
33124
|
child.kill();
|
|
@@ -32878,6 +33127,16 @@ async function createCursorAcpClient(options) {
|
|
|
32878
33127
|
let nextId = 1;
|
|
32879
33128
|
const pending = /* @__PURE__ */ new Map();
|
|
32880
33129
|
const pendingRequests = /* @__PURE__ */ new Map();
|
|
33130
|
+
function cancelSessionNotification(sessionId) {
|
|
33131
|
+
const line = JSON.stringify({
|
|
33132
|
+
jsonrpc: "2.0",
|
|
33133
|
+
method: "session/cancel",
|
|
33134
|
+
params: { sessionId }
|
|
33135
|
+
}) + "\n";
|
|
33136
|
+
return new Promise((res, rej) => {
|
|
33137
|
+
child.stdin.write(line, (err) => err ? rej(err) : res());
|
|
33138
|
+
});
|
|
33139
|
+
}
|
|
32881
33140
|
function send(method, params) {
|
|
32882
33141
|
const id = nextId++;
|
|
32883
33142
|
const line = JSON.stringify({ jsonrpc: "2.0", id, method, params }) + "\n";
|
|
@@ -32901,7 +33160,6 @@ async function createCursorAcpClient(options) {
|
|
|
32901
33160
|
respond(requestId, payload);
|
|
32902
33161
|
pendingRequests.delete(requestId);
|
|
32903
33162
|
}
|
|
32904
|
-
let promptOutputBuffer = "";
|
|
32905
33163
|
const rl = readline.createInterface({ input: child.stdout });
|
|
32906
33164
|
rl.on("line", (line) => {
|
|
32907
33165
|
const msg = safeJsonParse(line);
|
|
@@ -32930,11 +33188,12 @@ async function createCursorAcpClient(options) {
|
|
|
32930
33188
|
`[acp] Received session update (${kindLabel}) tool=${toolName || "(none)"}`
|
|
32931
33189
|
);
|
|
32932
33190
|
}
|
|
32933
|
-
|
|
32934
|
-
|
|
32935
|
-
|
|
32936
|
-
|
|
32937
|
-
|
|
33191
|
+
dispatchAcpSessionUpdate({
|
|
33192
|
+
flatPayload: update,
|
|
33193
|
+
onAcpConfigOptionsUpdated: sessionCtx.onAcpConfigOptionsUpdated,
|
|
33194
|
+
onSessionUpdate,
|
|
33195
|
+
suppressLoadReplay: () => sessionCtx.suppressLoadReplay.value
|
|
33196
|
+
});
|
|
32938
33197
|
return;
|
|
32939
33198
|
}
|
|
32940
33199
|
if (method === "session/request_permission" && typeof id === "number") {
|
|
@@ -32954,21 +33213,13 @@ async function createCursorAcpClient(options) {
|
|
|
32954
33213
|
if (dbgFs) {
|
|
32955
33214
|
console.error(`[acp-fs] ${method} path=${filePath.slice(0, 200)}${filePath.length > 200 ? "\u2026" : ""}`);
|
|
32956
33215
|
}
|
|
32957
|
-
const resolvedPath = resolveSafePathUnderCwd(cwd, filePath);
|
|
32958
|
-
if (!resolvedPath) {
|
|
32959
|
-
if (dbgFs) console.error(`[acp-fs] ${method} rejected path (outside cwd or empty)`);
|
|
32960
|
-
respondJsonRpcError(id, -32602, "Invalid or disallowed path");
|
|
32961
|
-
return;
|
|
32962
|
-
}
|
|
32963
33216
|
try {
|
|
32964
|
-
|
|
32965
|
-
const
|
|
32966
|
-
const
|
|
32967
|
-
|
|
32968
|
-
respond(id, { content });
|
|
33217
|
+
const lineNum = typeof params.line === "number" ? params.line : void 0;
|
|
33218
|
+
const limitNum = typeof params.limit === "number" ? params.limit : void 0;
|
|
33219
|
+
const out = acpReadTextFileInProcess(sessionCtx, filePath, lineNum, limitNum);
|
|
33220
|
+
respond(id, out);
|
|
32969
33221
|
} catch (e) {
|
|
32970
|
-
|
|
32971
|
-
if (code === "ENOENT") {
|
|
33222
|
+
if (e?.code === "ENOENT") {
|
|
32972
33223
|
respond(id, { content: "" });
|
|
32973
33224
|
} else {
|
|
32974
33225
|
respondJsonRpcError(id, -32e3, e instanceof Error ? e.message : String(e));
|
|
@@ -32985,32 +33236,17 @@ async function createCursorAcpClient(options) {
|
|
|
32985
33236
|
`[acp-fs] ${method} path=${filePath.slice(0, 200)}${filePath.length > 200 ? "\u2026" : ""} newBytes=${newText.length}`
|
|
32986
33237
|
);
|
|
32987
33238
|
}
|
|
32988
|
-
const resolvedPath = resolveSafePathUnderCwd(cwd, filePath);
|
|
32989
|
-
if (!resolvedPath) {
|
|
32990
|
-
if (dbgFs) console.error(`[acp-fs] ${method} rejected path (outside cwd or empty): ${filePath.slice(0, 120)}`);
|
|
32991
|
-
respondJsonRpcError(id, -32602, "Invalid or disallowed path");
|
|
32992
|
-
return;
|
|
32993
|
-
}
|
|
32994
|
-
let oldText = "";
|
|
32995
33239
|
try {
|
|
32996
|
-
|
|
33240
|
+
acpWriteTextFileInProcess(sessionCtx, filePath, newText);
|
|
33241
|
+
respond(id, null);
|
|
32997
33242
|
} catch (e) {
|
|
32998
|
-
if (e.
|
|
33243
|
+
if (e.message === "Invalid or disallowed path") {
|
|
33244
|
+
if (dbgFs) console.error(`[acp-fs] ${method} rejected path (outside cwd or empty): ${filePath.slice(0, 120)}`);
|
|
33245
|
+
respondJsonRpcError(id, -32602, "Invalid or disallowed path");
|
|
33246
|
+
} else {
|
|
32999
33247
|
respondJsonRpcError(id, -32e3, e instanceof Error ? e.message : String(e));
|
|
33000
|
-
return;
|
|
33001
33248
|
}
|
|
33002
33249
|
}
|
|
33003
|
-
try {
|
|
33004
|
-
mkdirSync3(dirname3(resolvedPath), { recursive: true });
|
|
33005
|
-
writeFileSync3(resolvedPath, newText, "utf8");
|
|
33006
|
-
} catch (e) {
|
|
33007
|
-
respondJsonRpcError(id, -32e3, e instanceof Error ? e.message : String(e));
|
|
33008
|
-
return;
|
|
33009
|
-
}
|
|
33010
|
-
const displayPath = toDisplayPathRelativeToCwd(cwd, resolvedPath);
|
|
33011
|
-
const patchContent = editSnippetToUnifiedDiff(displayPath, oldText, newText);
|
|
33012
|
-
onFileChange?.({ path: displayPath, oldText, newText, patchContent });
|
|
33013
|
-
respond(id, null);
|
|
33014
33250
|
return;
|
|
33015
33251
|
}
|
|
33016
33252
|
if (method === "cursor/create_plan" || method === "cursor/ask_question") {
|
|
@@ -33032,16 +33268,7 @@ async function createCursorAcpClient(options) {
|
|
|
33032
33268
|
});
|
|
33033
33269
|
(async () => {
|
|
33034
33270
|
try {
|
|
33035
|
-
let
|
|
33036
|
-
const line = JSON.stringify({
|
|
33037
|
-
jsonrpc: "2.0",
|
|
33038
|
-
method: "session/cancel",
|
|
33039
|
-
params: { sessionId }
|
|
33040
|
-
}) + "\n";
|
|
33041
|
-
return new Promise((res, rej) => {
|
|
33042
|
-
child.stdin.write(line, (err) => err ? rej(err) : res());
|
|
33043
|
-
});
|
|
33044
|
-
}, cancelPendingPermissionRequests2 = function() {
|
|
33271
|
+
let cancelPendingPermissionRequests2 = function() {
|
|
33045
33272
|
for (const [reqId, pending2] of [...pendingRequests.entries()]) {
|
|
33046
33273
|
if (pending2.method === "session/request_permission") {
|
|
33047
33274
|
respond(reqId, { outcome: { outcome: "cancelled" } });
|
|
@@ -33049,76 +33276,25 @@ async function createCursorAcpClient(options) {
|
|
|
33049
33276
|
}
|
|
33050
33277
|
}
|
|
33051
33278
|
};
|
|
33052
|
-
var
|
|
33053
|
-
|
|
33279
|
+
var cancelPendingPermissionRequests = cancelPendingPermissionRequests2;
|
|
33280
|
+
const transport = createCursorJsonRpcAcpTransport({
|
|
33281
|
+
send,
|
|
33282
|
+
cancelSessionNotification
|
|
33283
|
+
});
|
|
33284
|
+
const established = await bootstrapAcpWireSession(transport, sessionCtx, {
|
|
33054
33285
|
protocolVersion: 1,
|
|
33055
33286
|
clientCapabilities: { fs: { readTextFile: true, writeTextFile: true }, terminal: false },
|
|
33056
33287
|
clientInfo: { name: "buildautomaton-cli", version: "0.1.0" }
|
|
33057
33288
|
});
|
|
33058
|
-
|
|
33059
|
-
const newResult = await send("session/new", { cwd, mcpServers: [] });
|
|
33060
|
-
const sessionId = newResult?.sessionId ?? "";
|
|
33061
|
-
if (!sessionId) throw new Error("Cursor ACP session/new did not return sessionId");
|
|
33289
|
+
const sessionId = established.sessionId;
|
|
33062
33290
|
resolve18({
|
|
33063
33291
|
sessionId,
|
|
33064
33292
|
async sendPrompt(prompt, _options) {
|
|
33065
|
-
|
|
33066
|
-
try {
|
|
33067
|
-
const result = await send("session/prompt", {
|
|
33068
|
-
sessionId,
|
|
33069
|
-
prompt: [{ type: "text", text: prompt }]
|
|
33070
|
-
});
|
|
33071
|
-
await new Promise((r) => setImmediate(r));
|
|
33072
|
-
const output = (result?.output ?? promptOutputBuffer) || void 0;
|
|
33073
|
-
const stopReason = (result?.stopReason ?? "").toLowerCase();
|
|
33074
|
-
const cancelled = stopReason === "cancelled";
|
|
33075
|
-
const refusal = stopReason === "refusal";
|
|
33076
|
-
const stderrAfter = stderrCapture.getText();
|
|
33077
|
-
const agentType = backendAgentType ?? null;
|
|
33078
|
-
const stderrEvaluated = Boolean(stderrAfter && agentType);
|
|
33079
|
-
const stderrSuggestsAuth = stderrEvaluated ? localAgentErrorSuggestsAuth(agentType, stderrAfter) : false;
|
|
33080
|
-
if (cancelled) {
|
|
33081
|
-
return {
|
|
33082
|
-
success: false,
|
|
33083
|
-
stopReason: result?.stopReason,
|
|
33084
|
-
output: output || void 0,
|
|
33085
|
-
error: mergeErrorWithStderr("Stopped by user", stderrAfter)
|
|
33086
|
-
};
|
|
33087
|
-
}
|
|
33088
|
-
if (refusal) {
|
|
33089
|
-
return {
|
|
33090
|
-
success: false,
|
|
33091
|
-
stopReason: result?.stopReason,
|
|
33092
|
-
output: output || void 0,
|
|
33093
|
-
error: mergeErrorWithStderr("The agent refused the request.", stderrAfter)
|
|
33094
|
-
};
|
|
33095
|
-
}
|
|
33096
|
-
if (stderrSuggestsAuth) {
|
|
33097
|
-
return {
|
|
33098
|
-
success: false,
|
|
33099
|
-
stopReason: result?.stopReason,
|
|
33100
|
-
output: output || void 0,
|
|
33101
|
-
error: stderrAfter
|
|
33102
|
-
};
|
|
33103
|
-
}
|
|
33104
|
-
return {
|
|
33105
|
-
success: true,
|
|
33106
|
-
stopReason: result?.stopReason,
|
|
33107
|
-
output: output || void 0
|
|
33108
|
-
};
|
|
33109
|
-
} catch (err) {
|
|
33110
|
-
await new Promise((r) => setImmediate(r));
|
|
33111
|
-
const stderrAfter = stderrCapture.getText();
|
|
33112
|
-
const merged = mergeErrorWithStderr(formatJsonRpcStyleError(err), stderrAfter);
|
|
33113
|
-
return {
|
|
33114
|
-
success: false,
|
|
33115
|
-
error: merged
|
|
33116
|
-
};
|
|
33117
|
-
}
|
|
33293
|
+
return sendAcpPromptViaTransport(transport, sessionCtx, sessionId, prompt);
|
|
33118
33294
|
},
|
|
33119
33295
|
async cancel() {
|
|
33120
33296
|
cancelPendingPermissionRequests2();
|
|
33121
|
-
await
|
|
33297
|
+
await transport.cancelSession(sessionId);
|
|
33122
33298
|
},
|
|
33123
33299
|
resolveRequest(requestId, result) {
|
|
33124
33300
|
const numericId = Number(requestId);
|
|
@@ -33266,7 +33442,7 @@ function getGitRepoRootSync(startDir) {
|
|
|
33266
33442
|
|
|
33267
33443
|
// src/agents/acp/workspace-files.ts
|
|
33268
33444
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
33269
|
-
import { readFileSync as
|
|
33445
|
+
import { readFileSync as readFileSync3 } from "node:fs";
|
|
33270
33446
|
import * as path11 from "node:path";
|
|
33271
33447
|
function resolveWorkspaceFilePath(sessionParentPath, rawPath) {
|
|
33272
33448
|
const trimmed2 = rawPath.trim();
|
|
@@ -33298,7 +33474,7 @@ function readUtf8WorkspaceFile(sessionParentPath, displayPath) {
|
|
|
33298
33474
|
const rel = path11.relative(gitRoot, resolvedPath2);
|
|
33299
33475
|
if (!rel.startsWith("..") && !path11.isAbsolute(rel)) {
|
|
33300
33476
|
try {
|
|
33301
|
-
return
|
|
33477
|
+
return readFileSync3(resolvedPath2, "utf8");
|
|
33302
33478
|
} catch {
|
|
33303
33479
|
}
|
|
33304
33480
|
}
|
|
@@ -33306,7 +33482,7 @@ function readUtf8WorkspaceFile(sessionParentPath, displayPath) {
|
|
|
33306
33482
|
const resolvedPath = resolveSafePathUnderCwd(sessionParentPath, displayPath);
|
|
33307
33483
|
if (!resolvedPath) return "";
|
|
33308
33484
|
try {
|
|
33309
|
-
return
|
|
33485
|
+
return readFileSync3(resolvedPath, "utf8");
|
|
33310
33486
|
} catch {
|
|
33311
33487
|
return "";
|
|
33312
33488
|
}
|
|
@@ -33810,6 +33986,9 @@ function createBridgeOnSessionUpdate(opts) {
|
|
|
33810
33986
|
const sentFileChangePaths = /* @__PURE__ */ new Set();
|
|
33811
33987
|
const p = params;
|
|
33812
33988
|
const updateKind = p.sessionUpdate ?? p.session_update ?? p.type ?? "update";
|
|
33989
|
+
if (updateKind === "config_option_update") {
|
|
33990
|
+
return;
|
|
33991
|
+
}
|
|
33813
33992
|
const isCompletedToolCallUpdate = updateKind === "tool_call_update" && isCompletedToolStatus(p.status);
|
|
33814
33993
|
const toolName = p.toolCall?.name ?? p.tool_call?.name ?? "";
|
|
33815
33994
|
const isToolUpdate = updateKind === "tool_call" || updateKind === "tool_call_update" || typeof toolName === "string" && toolName.length > 0;
|
|
@@ -33896,14 +34075,72 @@ function buildAcpSessionBridgeHooks(opts) {
|
|
|
33896
34075
|
};
|
|
33897
34076
|
}
|
|
33898
34077
|
|
|
34078
|
+
// src/agents/acp/local-agent-session-file.ts
|
|
34079
|
+
import fs10 from "node:fs";
|
|
34080
|
+
import os3 from "node:os";
|
|
34081
|
+
import path12 from "node:path";
|
|
34082
|
+
var LOCAL_AGENT_SESSION_DIR = path12.join(os3.homedir(), ".buildautomaton", "agent-sessions");
|
|
34083
|
+
function safeFileSlug(cloudSessionId) {
|
|
34084
|
+
const t = cloudSessionId.replace(/[^a-zA-Z0-9_-]+/g, "_").slice(0, 220);
|
|
34085
|
+
return t.length > 0 ? t : "session";
|
|
34086
|
+
}
|
|
34087
|
+
function localAgentSessionFilePath(cloudSessionId) {
|
|
34088
|
+
return path12.join(LOCAL_AGENT_SESSION_DIR, `${safeFileSlug(cloudSessionId)}.json`);
|
|
34089
|
+
}
|
|
34090
|
+
function readLocalAgentSessionFile(cloudSessionId) {
|
|
34091
|
+
try {
|
|
34092
|
+
const p = localAgentSessionFilePath(cloudSessionId);
|
|
34093
|
+
const raw = fs10.readFileSync(p, "utf8");
|
|
34094
|
+
const parsed = JSON.parse(raw);
|
|
34095
|
+
if (parsed.v !== 1) return null;
|
|
34096
|
+
return {
|
|
34097
|
+
v: 1,
|
|
34098
|
+
acpSessionId: typeof parsed.acpSessionId === "string" ? parsed.acpSessionId : null,
|
|
34099
|
+
backendAgentType: typeof parsed.backendAgentType === "string" ? parsed.backendAgentType : null,
|
|
34100
|
+
configOptions: Array.isArray(parsed.configOptions) ? parsed.configOptions : null,
|
|
34101
|
+
updatedAt: typeof parsed.updatedAt === "string" ? parsed.updatedAt : (/* @__PURE__ */ new Date()).toISOString()
|
|
34102
|
+
};
|
|
34103
|
+
} catch {
|
|
34104
|
+
return null;
|
|
34105
|
+
}
|
|
34106
|
+
}
|
|
34107
|
+
function writeLocalAgentSessionFile(cloudSessionId, patch) {
|
|
34108
|
+
try {
|
|
34109
|
+
const dir = LOCAL_AGENT_SESSION_DIR;
|
|
34110
|
+
if (!fs10.existsSync(dir)) fs10.mkdirSync(dir, { recursive: true });
|
|
34111
|
+
const p = localAgentSessionFilePath(cloudSessionId);
|
|
34112
|
+
const prev = readLocalAgentSessionFile(cloudSessionId);
|
|
34113
|
+
const next = {
|
|
34114
|
+
v: 1,
|
|
34115
|
+
acpSessionId: patch.acpSessionId !== void 0 ? patch.acpSessionId : prev?.acpSessionId ?? null,
|
|
34116
|
+
backendAgentType: patch.backendAgentType !== void 0 ? patch.backendAgentType : prev?.backendAgentType ?? null,
|
|
34117
|
+
configOptions: patch.configOptions !== void 0 ? patch.configOptions : prev?.configOptions ?? null,
|
|
34118
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
34119
|
+
};
|
|
34120
|
+
fs10.writeFileSync(p, JSON.stringify(next, null, 2), "utf8");
|
|
34121
|
+
} catch {
|
|
34122
|
+
}
|
|
34123
|
+
}
|
|
34124
|
+
|
|
33899
34125
|
// src/agents/acp/ensure-acp-client.ts
|
|
33900
34126
|
async function ensureAcpClient(options) {
|
|
33901
|
-
const {
|
|
34127
|
+
const {
|
|
34128
|
+
state,
|
|
34129
|
+
preferredAgentType,
|
|
34130
|
+
mode,
|
|
34131
|
+
agentConfig,
|
|
34132
|
+
sessionParentPath,
|
|
34133
|
+
routing,
|
|
34134
|
+
cloudSessionId,
|
|
34135
|
+
sendSessionUpdate,
|
|
34136
|
+
sendRequest,
|
|
34137
|
+
log: log2
|
|
34138
|
+
} = options;
|
|
33902
34139
|
const targetSessionParentPath = resolveSessionParentPathForAgentProcess(sessionParentPath);
|
|
33903
34140
|
if (state.acpStartPromise && !state.acpHandle) {
|
|
33904
34141
|
await state.acpStartPromise;
|
|
33905
34142
|
}
|
|
33906
|
-
if (state.acpHandle && state.lastAcpCwd != null &&
|
|
34143
|
+
if (state.acpHandle && state.lastAcpCwd != null && path13.resolve(state.lastAcpCwd) !== path13.resolve(targetSessionParentPath)) {
|
|
33907
34144
|
try {
|
|
33908
34145
|
state.acpHandle.disconnect();
|
|
33909
34146
|
} catch {
|
|
@@ -33911,6 +34148,7 @@ async function ensureAcpClient(options) {
|
|
|
33911
34148
|
state.acpHandle = null;
|
|
33912
34149
|
state.acpStartPromise = null;
|
|
33913
34150
|
state.acpAgentKey = null;
|
|
34151
|
+
state.activeSessionConfigOptions = null;
|
|
33914
34152
|
}
|
|
33915
34153
|
const resolved = resolveAgentCommand(preferredAgentType);
|
|
33916
34154
|
if (!resolved) {
|
|
@@ -33931,12 +34169,13 @@ async function ensureAcpClient(options) {
|
|
|
33931
34169
|
state.acpHandle = null;
|
|
33932
34170
|
state.acpStartPromise = null;
|
|
33933
34171
|
state.acpAgentKey = null;
|
|
34172
|
+
state.activeSessionConfigOptions = null;
|
|
33934
34173
|
}
|
|
33935
34174
|
if (state.acpHandle) return state.acpHandle;
|
|
33936
34175
|
if (!state.acpStartPromise) {
|
|
33937
34176
|
let statOk = false;
|
|
33938
34177
|
try {
|
|
33939
|
-
const st =
|
|
34178
|
+
const st = fs11.statSync(targetSessionParentPath);
|
|
33940
34179
|
statOk = st.isDirectory();
|
|
33941
34180
|
if (!statOk) {
|
|
33942
34181
|
state.lastAcpStartError = `Agent cwd is not a directory: ${targetSessionParentPath}`;
|
|
@@ -33956,15 +34195,40 @@ async function ensureAcpClient(options) {
|
|
|
33956
34195
|
getSendRequest: () => sendRequest,
|
|
33957
34196
|
log: log2
|
|
33958
34197
|
});
|
|
34198
|
+
const persisted = cloudSessionId != null && cloudSessionId !== "" && preferredAgentType != null && preferredAgentType !== "" ? readLocalAgentSessionFile(cloudSessionId) : null;
|
|
34199
|
+
const persistedAcpSessionId = persisted && persisted.backendAgentType === preferredAgentType && typeof persisted.acpSessionId === "string" && persisted.acpSessionId.trim() !== "" ? persisted.acpSessionId.trim() : null;
|
|
34200
|
+
state.activeSessionConfigOptions = Array.isArray(persisted?.configOptions) ? persisted.configOptions : null;
|
|
33959
34201
|
state.acpStartPromise = resolved.createClient({
|
|
33960
34202
|
command: resolved.command,
|
|
33961
34203
|
sessionMode: mode,
|
|
33962
34204
|
agentConfig: agentConfig ?? null,
|
|
33963
34205
|
backendAgentType: preferredAgentType,
|
|
34206
|
+
persistedAcpSessionId,
|
|
34207
|
+
getActiveConfigOptions: () => state.activeSessionConfigOptions,
|
|
34208
|
+
onAcpSessionEstablished: (info) => {
|
|
34209
|
+
state.activeSessionConfigOptions = info.configOptions ?? state.activeSessionConfigOptions;
|
|
34210
|
+
if (cloudSessionId != null && cloudSessionId !== "" && preferredAgentType != null && preferredAgentType !== "") {
|
|
34211
|
+
writeLocalAgentSessionFile(cloudSessionId, {
|
|
34212
|
+
acpSessionId: info.acpSessionId,
|
|
34213
|
+
configOptions: info.configOptions,
|
|
34214
|
+
backendAgentType: preferredAgentType
|
|
34215
|
+
});
|
|
34216
|
+
}
|
|
34217
|
+
},
|
|
34218
|
+
onAcpConfigOptionsUpdated: (configOptions) => {
|
|
34219
|
+
state.activeSessionConfigOptions = configOptions;
|
|
34220
|
+
if (cloudSessionId != null && cloudSessionId !== "" && preferredAgentType != null && preferredAgentType !== "") {
|
|
34221
|
+
writeLocalAgentSessionFile(cloudSessionId, {
|
|
34222
|
+
configOptions,
|
|
34223
|
+
backendAgentType: preferredAgentType
|
|
34224
|
+
});
|
|
34225
|
+
}
|
|
34226
|
+
},
|
|
33964
34227
|
onAgentSubprocessExit: () => {
|
|
33965
34228
|
state.acpHandle = null;
|
|
33966
34229
|
state.acpStartPromise = null;
|
|
33967
34230
|
state.acpAgentKey = null;
|
|
34231
|
+
state.activeSessionConfigOptions = null;
|
|
33968
34232
|
state.lastAcpStartError = "Agent subprocess exited";
|
|
33969
34233
|
},
|
|
33970
34234
|
...hooks,
|
|
@@ -33994,7 +34258,8 @@ async function createAcpManager(options) {
|
|
|
33994
34258
|
acpStartPromise: null,
|
|
33995
34259
|
lastAcpStartError: null,
|
|
33996
34260
|
lastAcpCwd: null,
|
|
33997
|
-
acpAgentKey: null
|
|
34261
|
+
acpAgentKey: null,
|
|
34262
|
+
activeSessionConfigOptions: null
|
|
33998
34263
|
};
|
|
33999
34264
|
let backendFallbackAgentType = null;
|
|
34000
34265
|
const promptRouting = {};
|
|
@@ -34044,6 +34309,7 @@ async function createAcpManager(options) {
|
|
|
34044
34309
|
agentConfig: agentConfig ?? null,
|
|
34045
34310
|
sessionParentPath,
|
|
34046
34311
|
routing: promptRouting,
|
|
34312
|
+
cloudSessionId: sessionId,
|
|
34047
34313
|
sendSessionUpdate,
|
|
34048
34314
|
sendRequest: sendSessionUpdate,
|
|
34049
34315
|
log: log2
|
|
@@ -34134,6 +34400,7 @@ async function createAcpManager(options) {
|
|
|
34134
34400
|
state.acpHandle = null;
|
|
34135
34401
|
state.acpStartPromise = null;
|
|
34136
34402
|
state.acpAgentKey = null;
|
|
34403
|
+
state.activeSessionConfigOptions = null;
|
|
34137
34404
|
}
|
|
34138
34405
|
return {
|
|
34139
34406
|
setPreferredAgentType,
|
|
@@ -34146,12 +34413,12 @@ async function createAcpManager(options) {
|
|
|
34146
34413
|
}
|
|
34147
34414
|
|
|
34148
34415
|
// src/worktrees/session-worktree-manager.ts
|
|
34149
|
-
import * as
|
|
34150
|
-
import
|
|
34416
|
+
import * as path20 from "node:path";
|
|
34417
|
+
import os5 from "node:os";
|
|
34151
34418
|
|
|
34152
34419
|
// src/worktrees/prepare-new-session-worktrees.ts
|
|
34153
|
-
import * as
|
|
34154
|
-
import * as
|
|
34420
|
+
import * as fs13 from "node:fs";
|
|
34421
|
+
import * as path15 from "node:path";
|
|
34155
34422
|
|
|
34156
34423
|
// src/git/worktree-add.ts
|
|
34157
34424
|
async function gitWorktreeAddBranch(mainRepoPath, worktreePath, branch) {
|
|
@@ -34160,12 +34427,12 @@ async function gitWorktreeAddBranch(mainRepoPath, worktreePath, branch) {
|
|
|
34160
34427
|
}
|
|
34161
34428
|
|
|
34162
34429
|
// src/worktrees/worktree-layout-file.ts
|
|
34163
|
-
import * as
|
|
34164
|
-
import * as
|
|
34165
|
-
import
|
|
34430
|
+
import * as fs12 from "node:fs";
|
|
34431
|
+
import * as path14 from "node:path";
|
|
34432
|
+
import os4 from "node:os";
|
|
34166
34433
|
var LAYOUT_FILENAME = "worktree-launcher-layout.json";
|
|
34167
34434
|
function defaultWorktreeLayoutPath() {
|
|
34168
|
-
return
|
|
34435
|
+
return path14.join(os4.homedir(), ".buildautomaton", LAYOUT_FILENAME);
|
|
34169
34436
|
}
|
|
34170
34437
|
function normalizeLoadedLayout(raw) {
|
|
34171
34438
|
if (raw && typeof raw === "object" && "launcherCwds" in raw) {
|
|
@@ -34177,8 +34444,8 @@ function normalizeLoadedLayout(raw) {
|
|
|
34177
34444
|
function loadWorktreeLayout() {
|
|
34178
34445
|
try {
|
|
34179
34446
|
const p = defaultWorktreeLayoutPath();
|
|
34180
|
-
if (!
|
|
34181
|
-
const raw = JSON.parse(
|
|
34447
|
+
if (!fs12.existsSync(p)) return { launcherCwds: [] };
|
|
34448
|
+
const raw = JSON.parse(fs12.readFileSync(p, "utf8"));
|
|
34182
34449
|
return normalizeLoadedLayout(raw);
|
|
34183
34450
|
} catch {
|
|
34184
34451
|
return { launcherCwds: [] };
|
|
@@ -34186,24 +34453,24 @@ function loadWorktreeLayout() {
|
|
|
34186
34453
|
}
|
|
34187
34454
|
function saveWorktreeLayout(layout) {
|
|
34188
34455
|
try {
|
|
34189
|
-
const dir =
|
|
34190
|
-
|
|
34191
|
-
|
|
34456
|
+
const dir = path14.dirname(defaultWorktreeLayoutPath());
|
|
34457
|
+
fs12.mkdirSync(dir, { recursive: true });
|
|
34458
|
+
fs12.writeFileSync(defaultWorktreeLayoutPath(), JSON.stringify(layout, null, 2), "utf8");
|
|
34192
34459
|
} catch {
|
|
34193
34460
|
}
|
|
34194
34461
|
}
|
|
34195
34462
|
function baseNameSafe(pathString) {
|
|
34196
|
-
return
|
|
34463
|
+
return path14.basename(pathString).replace(/[^a-zA-Z0-9._-]+/g, "-") || "cwd";
|
|
34197
34464
|
}
|
|
34198
34465
|
function getLauncherDirNameIfPresent(layout, bridgeRootPath2) {
|
|
34199
|
-
const norm =
|
|
34200
|
-
const existing = layout.launcherCwds.find((e) =>
|
|
34466
|
+
const norm = path14.resolve(bridgeRootPath2);
|
|
34467
|
+
const existing = layout.launcherCwds.find((e) => path14.resolve(e.absolutePath) === norm);
|
|
34201
34468
|
return existing?.dirName;
|
|
34202
34469
|
}
|
|
34203
34470
|
function allocateDirNameForLauncherCwd(layout, bridgeRootPath2) {
|
|
34204
34471
|
const existing = getLauncherDirNameIfPresent(layout, bridgeRootPath2);
|
|
34205
34472
|
if (existing) return existing;
|
|
34206
|
-
const norm =
|
|
34473
|
+
const norm = path14.resolve(bridgeRootPath2);
|
|
34207
34474
|
const base = baseNameSafe(norm);
|
|
34208
34475
|
const used = new Set(layout.launcherCwds.map((e) => e.dirName));
|
|
34209
34476
|
let name = base;
|
|
@@ -34220,10 +34487,10 @@ function allocateDirNameForLauncherCwd(layout, bridgeRootPath2) {
|
|
|
34220
34487
|
// src/worktrees/prepare-new-session-worktrees.ts
|
|
34221
34488
|
async function prepareNewSessionWorktrees(options) {
|
|
34222
34489
|
const { worktreesRootPath, bridgeRoot, sessionId, layout, log: log2 } = options;
|
|
34223
|
-
const bridgeResolved =
|
|
34490
|
+
const bridgeResolved = path15.resolve(bridgeRoot);
|
|
34224
34491
|
const cwdKey = allocateDirNameForLauncherCwd(layout, bridgeResolved);
|
|
34225
|
-
const bridgeKeyDir =
|
|
34226
|
-
const sessionDir =
|
|
34492
|
+
const bridgeKeyDir = path15.join(worktreesRootPath, cwdKey);
|
|
34493
|
+
const sessionDir = path15.join(bridgeKeyDir, sessionId);
|
|
34227
34494
|
const repos = await discoverGitReposUnderRoot(bridgeResolved);
|
|
34228
34495
|
if (repos.length === 0) {
|
|
34229
34496
|
log2("[worktrees] No Git repositories under bridge root; skipping worktree creation.");
|
|
@@ -34231,14 +34498,14 @@ async function prepareNewSessionWorktrees(options) {
|
|
|
34231
34498
|
}
|
|
34232
34499
|
const branch = `session-${sessionId}`;
|
|
34233
34500
|
const worktreePaths = [];
|
|
34234
|
-
|
|
34501
|
+
fs13.mkdirSync(sessionDir, { recursive: true });
|
|
34235
34502
|
for (const repo of repos) {
|
|
34236
|
-
let rel =
|
|
34237
|
-
if (rel.startsWith("..") ||
|
|
34503
|
+
let rel = path15.relative(bridgeResolved, repo.absolutePath);
|
|
34504
|
+
if (rel.startsWith("..") || path15.isAbsolute(rel)) continue;
|
|
34238
34505
|
const relNorm = rel === "" ? "." : rel;
|
|
34239
|
-
const wtPath = relNorm === "." ? sessionDir :
|
|
34506
|
+
const wtPath = relNorm === "." ? sessionDir : path15.join(sessionDir, relNorm);
|
|
34240
34507
|
if (relNorm !== ".") {
|
|
34241
|
-
|
|
34508
|
+
fs13.mkdirSync(path15.dirname(wtPath), { recursive: true });
|
|
34242
34509
|
}
|
|
34243
34510
|
try {
|
|
34244
34511
|
await gitWorktreeAddBranch(repo.absolutePath, wtPath, branch);
|
|
@@ -34280,23 +34547,23 @@ async function renameSessionWorktreeBranches(paths, newBranch, log2) {
|
|
|
34280
34547
|
}
|
|
34281
34548
|
|
|
34282
34549
|
// src/worktrees/remove-session-worktrees.ts
|
|
34283
|
-
import * as
|
|
34550
|
+
import * as fs16 from "node:fs";
|
|
34284
34551
|
|
|
34285
34552
|
// src/git/worktree-remove.ts
|
|
34286
|
-
import * as
|
|
34553
|
+
import * as fs15 from "node:fs";
|
|
34287
34554
|
|
|
34288
34555
|
// src/git/resolve-main-repo-from-git-file.ts
|
|
34289
|
-
import * as
|
|
34290
|
-
import * as
|
|
34556
|
+
import * as fs14 from "node:fs";
|
|
34557
|
+
import * as path16 from "node:path";
|
|
34291
34558
|
function resolveMainRepoFromWorktreeGitFile(wt) {
|
|
34292
|
-
const gitDirFile =
|
|
34293
|
-
if (!
|
|
34294
|
-
const first2 =
|
|
34559
|
+
const gitDirFile = path16.join(wt, ".git");
|
|
34560
|
+
if (!fs14.existsSync(gitDirFile) || !fs14.statSync(gitDirFile).isFile()) return "";
|
|
34561
|
+
const first2 = fs14.readFileSync(gitDirFile, "utf8").trim();
|
|
34295
34562
|
const m = first2.match(/^gitdir:\s*(.+)$/im);
|
|
34296
34563
|
if (!m) return "";
|
|
34297
|
-
const gitWorktreePath =
|
|
34298
|
-
const gitDir =
|
|
34299
|
-
return
|
|
34564
|
+
const gitWorktreePath = path16.resolve(wt, m[1].trim());
|
|
34565
|
+
const gitDir = path16.dirname(path16.dirname(gitWorktreePath));
|
|
34566
|
+
return path16.dirname(gitDir);
|
|
34300
34567
|
}
|
|
34301
34568
|
|
|
34302
34569
|
// src/git/worktree-remove.ts
|
|
@@ -34305,7 +34572,7 @@ async function gitWorktreeRemoveForce(worktreePath) {
|
|
|
34305
34572
|
if (mainRepo) {
|
|
34306
34573
|
await cliSimpleGit(mainRepo).raw(["worktree", "remove", "--force", worktreePath]);
|
|
34307
34574
|
} else {
|
|
34308
|
-
|
|
34575
|
+
fs15.rmSync(worktreePath, { recursive: true, force: true });
|
|
34309
34576
|
}
|
|
34310
34577
|
}
|
|
34311
34578
|
|
|
@@ -34318,7 +34585,7 @@ async function removeSessionWorktrees(paths, log2) {
|
|
|
34318
34585
|
} catch (e) {
|
|
34319
34586
|
log2(`[worktrees] Remove failed for ${wt}: ${e instanceof Error ? e.message : String(e)}`);
|
|
34320
34587
|
try {
|
|
34321
|
-
|
|
34588
|
+
fs16.rmSync(wt, { recursive: true, force: true });
|
|
34322
34589
|
} catch {
|
|
34323
34590
|
}
|
|
34324
34591
|
}
|
|
@@ -34538,7 +34805,7 @@ function formatRemoteDisplayLabel(remoteUrl) {
|
|
|
34538
34805
|
}
|
|
34539
34806
|
|
|
34540
34807
|
// src/git/working-directory/changes/get-working-tree-change-repo-details.ts
|
|
34541
|
-
import * as
|
|
34808
|
+
import * as path18 from "node:path";
|
|
34542
34809
|
|
|
34543
34810
|
// src/git/working-directory/changes/parse-git-status.ts
|
|
34544
34811
|
function parseNameStatusLines(lines) {
|
|
@@ -34658,8 +34925,8 @@ async function listChangedFilesForCommit(repoGitCwd, repoRelPath, commitSha) {
|
|
|
34658
34925
|
}
|
|
34659
34926
|
|
|
34660
34927
|
// src/git/working-directory/changes/list-changed-files-for-repo.ts
|
|
34661
|
-
import * as
|
|
34662
|
-
import * as
|
|
34928
|
+
import * as fs18 from "node:fs";
|
|
34929
|
+
import * as path17 from "node:path";
|
|
34663
34930
|
|
|
34664
34931
|
// src/git/working-directory/changes/count-lines.ts
|
|
34665
34932
|
import { createReadStream } from "node:fs";
|
|
@@ -34683,7 +34950,7 @@ async function countTextFileLines(filePath) {
|
|
|
34683
34950
|
}
|
|
34684
34951
|
|
|
34685
34952
|
// src/git/working-directory/changes/hydrate-patch.ts
|
|
34686
|
-
import * as
|
|
34953
|
+
import * as fs17 from "node:fs";
|
|
34687
34954
|
var UNIFIED_HUNK_HEADER_RE = /^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/;
|
|
34688
34955
|
var MAX_HYDRATE_LINES_PER_GAP = 8e3;
|
|
34689
34956
|
var MAX_HYDRATE_LINES_PER_FILE = 8e4;
|
|
@@ -34698,7 +34965,7 @@ async function readGitBlobLines(repoCwd, pathInRepo) {
|
|
|
34698
34965
|
}
|
|
34699
34966
|
async function readWorktreeFileLines(filePath) {
|
|
34700
34967
|
try {
|
|
34701
|
-
const raw = await
|
|
34968
|
+
const raw = await fs17.promises.readFile(filePath, "utf8");
|
|
34702
34969
|
return raw.split(/\r?\n/);
|
|
34703
34970
|
} catch {
|
|
34704
34971
|
return null;
|
|
@@ -34833,7 +35100,7 @@ async function listChangedFilesForRepo(repoGitCwd, repoRelPath) {
|
|
|
34833
35100
|
const rows = [];
|
|
34834
35101
|
for (const pathInRepo of paths) {
|
|
34835
35102
|
const relLauncher = posixJoinDirFile(repoRelPath, pathInRepo.replace(/\\/g, "/"));
|
|
34836
|
-
const repoFilePath =
|
|
35103
|
+
const repoFilePath = path17.join(repoGitCwd, pathInRepo);
|
|
34837
35104
|
const nums = numByPath.get(pathInRepo);
|
|
34838
35105
|
let additions = nums?.additions ?? 0;
|
|
34839
35106
|
let deletions = nums?.deletions ?? 0;
|
|
@@ -34846,7 +35113,7 @@ async function listChangedFilesForRepo(repoGitCwd, repoRelPath) {
|
|
|
34846
35113
|
deletions = fromGit.deletions;
|
|
34847
35114
|
} else {
|
|
34848
35115
|
try {
|
|
34849
|
-
const st = await
|
|
35116
|
+
const st = await fs18.promises.stat(repoFilePath);
|
|
34850
35117
|
if (st.isFile()) additions = await countTextFileLines(repoFilePath);
|
|
34851
35118
|
else additions = 0;
|
|
34852
35119
|
} catch {
|
|
@@ -34872,7 +35139,7 @@ async function listChangedFilesForRepo(repoGitCwd, repoRelPath) {
|
|
|
34872
35139
|
} else {
|
|
34873
35140
|
pathInRepo = row.pathRelLauncher;
|
|
34874
35141
|
}
|
|
34875
|
-
const filePath =
|
|
35142
|
+
const filePath = path17.join(repoGitCwd, pathInRepo);
|
|
34876
35143
|
let patch = await unifiedDiffForFile(repoGitCwd, pathInRepo, row.change);
|
|
34877
35144
|
if (patch) {
|
|
34878
35145
|
patch = await hydrateUnifiedPatchWithFileContext(patch, filePath, repoGitCwd, pathInRepo, row.change);
|
|
@@ -34888,8 +35155,8 @@ function normRepoRel(p) {
|
|
|
34888
35155
|
return x === "" ? "." : x;
|
|
34889
35156
|
}
|
|
34890
35157
|
async function getWorkingTreeChangeRepoDetails(options) {
|
|
34891
|
-
const bridgeRoot =
|
|
34892
|
-
const sessionWtRoot = options.sessionWorktreeRootPath ?
|
|
35158
|
+
const bridgeRoot = path18.resolve(getBridgeRoot());
|
|
35159
|
+
const sessionWtRoot = options.sessionWorktreeRootPath ? path18.resolve(options.sessionWorktreeRootPath) : null;
|
|
34893
35160
|
const legacyNested = options.legacyRepoNestedSessionLayout === true;
|
|
34894
35161
|
const out = [];
|
|
34895
35162
|
const filter = options.repoFilterRelPath != null ? normRepoRel(options.repoFilterRelPath) : null;
|
|
@@ -34902,7 +35169,7 @@ async function getWorkingTreeChangeRepoDetails(options) {
|
|
|
34902
35169
|
}
|
|
34903
35170
|
const basis = filter == null && basisInput.kind === "commit" ? { kind: "working" } : basisInput;
|
|
34904
35171
|
for (const target of options.commitTargetPaths) {
|
|
34905
|
-
const t =
|
|
35172
|
+
const t = path18.resolve(target);
|
|
34906
35173
|
if (!await isGitRepoDirectory(t)) continue;
|
|
34907
35174
|
const g = cliSimpleGit(t);
|
|
34908
35175
|
let branch = "HEAD";
|
|
@@ -34915,8 +35182,8 @@ async function getWorkingTreeChangeRepoDetails(options) {
|
|
|
34915
35182
|
const remoteDisplay = formatRemoteDisplayLabel(remoteUrl);
|
|
34916
35183
|
let repoRelPath;
|
|
34917
35184
|
if (sessionWtRoot) {
|
|
34918
|
-
const anchor = legacyNested ?
|
|
34919
|
-
const relNorm =
|
|
35185
|
+
const anchor = legacyNested ? path18.dirname(t) : t;
|
|
35186
|
+
const relNorm = path18.relative(sessionWtRoot, anchor);
|
|
34920
35187
|
repoRelPath = relNorm === "" ? "." : relNorm.replace(/\\/g, "/");
|
|
34921
35188
|
} else {
|
|
34922
35189
|
let top = t;
|
|
@@ -34925,8 +35192,8 @@ async function getWorkingTreeChangeRepoDetails(options) {
|
|
|
34925
35192
|
} catch {
|
|
34926
35193
|
top = t;
|
|
34927
35194
|
}
|
|
34928
|
-
const rel =
|
|
34929
|
-
repoRelPath = rel.startsWith("..") ?
|
|
35195
|
+
const rel = path18.relative(bridgeRoot, path18.resolve(top)).replace(/\\/g, "/") || ".";
|
|
35196
|
+
repoRelPath = rel.startsWith("..") ? path18.basename(path18.resolve(top)) : rel;
|
|
34930
35197
|
}
|
|
34931
35198
|
const norm = normRepoRel(repoRelPath === "" ? "." : repoRelPath);
|
|
34932
35199
|
if (filter && norm !== filter) continue;
|
|
@@ -34991,11 +35258,11 @@ async function commitSessionWorktrees(options) {
|
|
|
34991
35258
|
}
|
|
34992
35259
|
|
|
34993
35260
|
// src/worktrees/discover-session-worktree-on-disk.ts
|
|
34994
|
-
import * as
|
|
34995
|
-
import * as
|
|
35261
|
+
import * as fs19 from "node:fs";
|
|
35262
|
+
import * as path19 from "node:path";
|
|
34996
35263
|
function isGitDir(dirPath) {
|
|
34997
35264
|
try {
|
|
34998
|
-
return
|
|
35265
|
+
return fs19.existsSync(path19.join(dirPath, ".git"));
|
|
34999
35266
|
} catch {
|
|
35000
35267
|
return false;
|
|
35001
35268
|
}
|
|
@@ -35004,23 +35271,23 @@ function collectGitRepoRootsUnderDirectory(rootPath) {
|
|
|
35004
35271
|
const out = [];
|
|
35005
35272
|
const walk = (dir) => {
|
|
35006
35273
|
if (isGitDir(dir)) {
|
|
35007
|
-
out.push(
|
|
35274
|
+
out.push(path19.resolve(dir));
|
|
35008
35275
|
return;
|
|
35009
35276
|
}
|
|
35010
35277
|
let entries;
|
|
35011
35278
|
try {
|
|
35012
|
-
entries =
|
|
35279
|
+
entries = fs19.readdirSync(dir, { withFileTypes: true });
|
|
35013
35280
|
} catch {
|
|
35014
35281
|
return;
|
|
35015
35282
|
}
|
|
35016
35283
|
for (const e of entries) {
|
|
35017
35284
|
if (e.name.startsWith(".")) continue;
|
|
35018
|
-
const full =
|
|
35285
|
+
const full = path19.join(dir, e.name);
|
|
35019
35286
|
if (!e.isDirectory()) continue;
|
|
35020
35287
|
walk(full);
|
|
35021
35288
|
}
|
|
35022
35289
|
};
|
|
35023
|
-
walk(
|
|
35290
|
+
walk(path19.resolve(rootPath));
|
|
35024
35291
|
return [...new Set(out)];
|
|
35025
35292
|
}
|
|
35026
35293
|
function collectWorktreeRootsNamed(root, sessionId, maxDepth) {
|
|
@@ -35029,16 +35296,16 @@ function collectWorktreeRootsNamed(root, sessionId, maxDepth) {
|
|
|
35029
35296
|
if (depth > maxDepth) return;
|
|
35030
35297
|
let entries;
|
|
35031
35298
|
try {
|
|
35032
|
-
entries =
|
|
35299
|
+
entries = fs19.readdirSync(dir, { withFileTypes: true });
|
|
35033
35300
|
} catch {
|
|
35034
35301
|
return;
|
|
35035
35302
|
}
|
|
35036
35303
|
for (const e of entries) {
|
|
35037
35304
|
if (e.name.startsWith(".")) continue;
|
|
35038
|
-
const full =
|
|
35305
|
+
const full = path19.join(dir, e.name);
|
|
35039
35306
|
if (!e.isDirectory()) continue;
|
|
35040
35307
|
if (e.name === sessionId) {
|
|
35041
|
-
if (isGitDir(full)) out.push(
|
|
35308
|
+
if (isGitDir(full)) out.push(path19.resolve(full));
|
|
35042
35309
|
} else {
|
|
35043
35310
|
walk(full, depth + 1);
|
|
35044
35311
|
}
|
|
@@ -35050,14 +35317,14 @@ function collectWorktreeRootsNamed(root, sessionId, maxDepth) {
|
|
|
35050
35317
|
function tryBindingFromSessionDirectory(sessionDir) {
|
|
35051
35318
|
let st;
|
|
35052
35319
|
try {
|
|
35053
|
-
st =
|
|
35320
|
+
st = fs19.statSync(sessionDir);
|
|
35054
35321
|
} catch {
|
|
35055
35322
|
return null;
|
|
35056
35323
|
}
|
|
35057
35324
|
if (!st.isDirectory()) return null;
|
|
35058
35325
|
const worktreePaths = collectGitRepoRootsUnderDirectory(sessionDir);
|
|
35059
35326
|
if (worktreePaths.length === 0) return null;
|
|
35060
|
-
const abs =
|
|
35327
|
+
const abs = path19.resolve(sessionDir);
|
|
35061
35328
|
return {
|
|
35062
35329
|
sessionParentPath: abs,
|
|
35063
35330
|
workingTreeRelRoot: abs,
|
|
@@ -35067,20 +35334,20 @@ function tryBindingFromSessionDirectory(sessionDir) {
|
|
|
35067
35334
|
function discoverLegacyBindingAscendingFromCheckout(sessionId, checkoutPath) {
|
|
35068
35335
|
const sid = sessionId.trim();
|
|
35069
35336
|
if (!sid) return null;
|
|
35070
|
-
const hintR =
|
|
35337
|
+
const hintR = path19.resolve(checkoutPath);
|
|
35071
35338
|
let best = null;
|
|
35072
|
-
let cur =
|
|
35339
|
+
let cur = path19.dirname(hintR);
|
|
35073
35340
|
for (let i = 0; i < 40; i++) {
|
|
35074
35341
|
const paths = collectWorktreeRootsNamed(cur, sid, 24);
|
|
35075
|
-
if (paths.some((p) =>
|
|
35076
|
-
const isolated = resolveIsolatedSessionParentPathFromCheckouts(paths) ??
|
|
35342
|
+
if (paths.some((p) => path19.resolve(p) === hintR)) {
|
|
35343
|
+
const isolated = resolveIsolatedSessionParentPathFromCheckouts(paths) ?? path19.resolve(paths[0]);
|
|
35077
35344
|
best = {
|
|
35078
|
-
sessionParentPath:
|
|
35079
|
-
workingTreeRelRoot:
|
|
35080
|
-
repoCheckoutPaths: paths.map((p) =>
|
|
35345
|
+
sessionParentPath: path19.resolve(isolated),
|
|
35346
|
+
workingTreeRelRoot: path19.resolve(cur),
|
|
35347
|
+
repoCheckoutPaths: paths.map((p) => path19.resolve(p))
|
|
35081
35348
|
};
|
|
35082
35349
|
}
|
|
35083
|
-
const next =
|
|
35350
|
+
const next = path19.dirname(cur);
|
|
35084
35351
|
if (next === cur) break;
|
|
35085
35352
|
cur = next;
|
|
35086
35353
|
}
|
|
@@ -35088,33 +35355,33 @@ function discoverLegacyBindingAscendingFromCheckout(sessionId, checkoutPath) {
|
|
|
35088
35355
|
}
|
|
35089
35356
|
function discoverSessionWorktreeOnDisk(options) {
|
|
35090
35357
|
const { sessionId, worktreesRootPath, layout, bridgeRoot } = options;
|
|
35091
|
-
if (!sessionId.trim() || !
|
|
35358
|
+
if (!sessionId.trim() || !fs19.existsSync(worktreesRootPath)) return null;
|
|
35092
35359
|
const preferredKey = getLauncherDirNameIfPresent(layout, bridgeRoot);
|
|
35093
35360
|
const keys = [];
|
|
35094
35361
|
if (preferredKey) keys.push(preferredKey);
|
|
35095
35362
|
try {
|
|
35096
|
-
for (const name of
|
|
35363
|
+
for (const name of fs19.readdirSync(worktreesRootPath)) {
|
|
35097
35364
|
if (name.startsWith(".")) continue;
|
|
35098
|
-
const p =
|
|
35099
|
-
if (!
|
|
35365
|
+
const p = path19.join(worktreesRootPath, name);
|
|
35366
|
+
if (!fs19.statSync(p).isDirectory()) continue;
|
|
35100
35367
|
if (name !== preferredKey) keys.push(name);
|
|
35101
35368
|
}
|
|
35102
35369
|
} catch {
|
|
35103
35370
|
return null;
|
|
35104
35371
|
}
|
|
35105
35372
|
for (const key of keys) {
|
|
35106
|
-
const layoutRoot =
|
|
35107
|
-
if (!
|
|
35108
|
-
const sessionDir =
|
|
35373
|
+
const layoutRoot = path19.join(worktreesRootPath, key);
|
|
35374
|
+
if (!fs19.existsSync(layoutRoot) || !fs19.statSync(layoutRoot).isDirectory()) continue;
|
|
35375
|
+
const sessionDir = path19.join(layoutRoot, sessionId);
|
|
35109
35376
|
const nested = tryBindingFromSessionDirectory(sessionDir);
|
|
35110
35377
|
if (nested) return nested;
|
|
35111
35378
|
const legacyPaths = collectWorktreeRootsNamed(layoutRoot, sessionId, 24);
|
|
35112
35379
|
if (legacyPaths.length > 0) {
|
|
35113
|
-
const isolated = resolveIsolatedSessionParentPathFromCheckouts(legacyPaths) ??
|
|
35380
|
+
const isolated = resolveIsolatedSessionParentPathFromCheckouts(legacyPaths) ?? path19.resolve(legacyPaths[0]);
|
|
35114
35381
|
return {
|
|
35115
|
-
sessionParentPath:
|
|
35116
|
-
workingTreeRelRoot:
|
|
35117
|
-
repoCheckoutPaths: legacyPaths.map((p) =>
|
|
35382
|
+
sessionParentPath: path19.resolve(isolated),
|
|
35383
|
+
workingTreeRelRoot: path19.resolve(layoutRoot),
|
|
35384
|
+
repoCheckoutPaths: legacyPaths.map((p) => path19.resolve(p))
|
|
35118
35385
|
};
|
|
35119
35386
|
}
|
|
35120
35387
|
}
|
|
@@ -35123,12 +35390,12 @@ function discoverSessionWorktreeOnDisk(options) {
|
|
|
35123
35390
|
function discoverSessionWorktreesUnderSessionWorktreeRoot(sessionWorktreeRootPathOrHint, sessionId) {
|
|
35124
35391
|
const sid = sessionId.trim();
|
|
35125
35392
|
if (!sid) return null;
|
|
35126
|
-
const hint =
|
|
35127
|
-
const underHint = tryBindingFromSessionDirectory(
|
|
35393
|
+
const hint = path19.resolve(sessionWorktreeRootPathOrHint);
|
|
35394
|
+
const underHint = tryBindingFromSessionDirectory(path19.join(hint, sid));
|
|
35128
35395
|
if (underHint) return underHint;
|
|
35129
35396
|
const direct = tryBindingFromSessionDirectory(hint);
|
|
35130
35397
|
if (direct) {
|
|
35131
|
-
if (
|
|
35398
|
+
if (path19.basename(hint) === sid && isGitDir(hint)) {
|
|
35132
35399
|
const legacyFromCheckout = discoverLegacyBindingAscendingFromCheckout(sid, hint);
|
|
35133
35400
|
if (legacyFromCheckout && legacyFromCheckout.repoCheckoutPaths.length > direct.repoCheckoutPaths.length) {
|
|
35134
35401
|
return legacyFromCheckout;
|
|
@@ -35136,24 +35403,24 @@ function discoverSessionWorktreesUnderSessionWorktreeRoot(sessionWorktreeRootPat
|
|
|
35136
35403
|
}
|
|
35137
35404
|
return direct;
|
|
35138
35405
|
}
|
|
35139
|
-
if (
|
|
35406
|
+
if (path19.basename(hint) === sid && isGitDir(hint)) {
|
|
35140
35407
|
const legacyFromCheckout = discoverLegacyBindingAscendingFromCheckout(sid, hint);
|
|
35141
35408
|
if (legacyFromCheckout) return legacyFromCheckout;
|
|
35142
35409
|
}
|
|
35143
35410
|
let st;
|
|
35144
35411
|
try {
|
|
35145
|
-
st =
|
|
35412
|
+
st = fs19.statSync(hint);
|
|
35146
35413
|
} catch {
|
|
35147
35414
|
return null;
|
|
35148
35415
|
}
|
|
35149
35416
|
if (!st.isDirectory()) return null;
|
|
35150
35417
|
const legacyPaths = collectWorktreeRootsNamed(hint, sid, 24);
|
|
35151
35418
|
if (legacyPaths.length === 0) return null;
|
|
35152
|
-
const isolated = resolveIsolatedSessionParentPathFromCheckouts(legacyPaths) ??
|
|
35419
|
+
const isolated = resolveIsolatedSessionParentPathFromCheckouts(legacyPaths) ?? path19.resolve(legacyPaths[0]);
|
|
35153
35420
|
return {
|
|
35154
|
-
sessionParentPath:
|
|
35421
|
+
sessionParentPath: path19.resolve(isolated),
|
|
35155
35422
|
workingTreeRelRoot: hint,
|
|
35156
|
-
repoCheckoutPaths: legacyPaths.map((p) =>
|
|
35423
|
+
repoCheckoutPaths: legacyPaths.map((p) => path19.resolve(p))
|
|
35157
35424
|
};
|
|
35158
35425
|
}
|
|
35159
35426
|
|
|
@@ -35176,10 +35443,10 @@ var SessionWorktreeManager = class {
|
|
|
35176
35443
|
this.layout = loadWorktreeLayout();
|
|
35177
35444
|
}
|
|
35178
35445
|
rememberSessionWorktrees(sessionId, binding) {
|
|
35179
|
-
const paths = binding.repoCheckoutPaths.map((p) =>
|
|
35446
|
+
const paths = binding.repoCheckoutPaths.map((p) => path20.resolve(p));
|
|
35180
35447
|
this.sessionRepoCheckoutPaths.set(sessionId, paths);
|
|
35181
|
-
this.sessionParentPathBySession.set(sessionId,
|
|
35182
|
-
this.sessionWorkingTreeRelRootBySession.set(sessionId,
|
|
35448
|
+
this.sessionParentPathBySession.set(sessionId, path20.resolve(binding.sessionParentPath));
|
|
35449
|
+
this.sessionWorkingTreeRelRootBySession.set(sessionId, path20.resolve(binding.workingTreeRelRoot));
|
|
35183
35450
|
}
|
|
35184
35451
|
sessionParentPathAfterRemember(sessionId) {
|
|
35185
35452
|
return this.sessionParentPathBySession.get(sessionId);
|
|
@@ -35196,7 +35463,7 @@ var SessionWorktreeManager = class {
|
|
|
35196
35463
|
const parent = this.sessionParentPathBySession.get(sessionId);
|
|
35197
35464
|
const relRoot = this.sessionWorkingTreeRelRootBySession.get(sessionId);
|
|
35198
35465
|
if (!parent || !relRoot) return false;
|
|
35199
|
-
return
|
|
35466
|
+
return path20.resolve(parent) !== path20.resolve(relRoot);
|
|
35200
35467
|
}
|
|
35201
35468
|
/**
|
|
35202
35469
|
* Session parent path for `worktrees_root`: the per-session directory (new layout) or primary checkout (legacy).
|
|
@@ -35205,7 +35472,7 @@ var SessionWorktreeManager = class {
|
|
|
35205
35472
|
if (!sessionId) return null;
|
|
35206
35473
|
const sid = sessionId.trim();
|
|
35207
35474
|
const cached2 = this.sessionParentPathBySession.get(sid);
|
|
35208
|
-
if (cached2) return
|
|
35475
|
+
if (cached2) return path20.resolve(cached2);
|
|
35209
35476
|
const paths = this.ensureRepoCheckoutPathsForSession(sid) ?? this.getRepoCheckoutPathsForSession(sid);
|
|
35210
35477
|
if (!paths?.length) return null;
|
|
35211
35478
|
return resolveIsolatedSessionParentPathFromCheckouts(paths);
|
|
@@ -35219,7 +35486,7 @@ var SessionWorktreeManager = class {
|
|
|
35219
35486
|
const sid = sessionId.trim();
|
|
35220
35487
|
const parentPathRaw = opts.sessionParentPath?.trim();
|
|
35221
35488
|
if (parentPathRaw) {
|
|
35222
|
-
const resolved =
|
|
35489
|
+
const resolved = path20.resolve(parentPathRaw);
|
|
35223
35490
|
if (sid && parseSessionParent(opts.sessionParent) === "worktrees_root") {
|
|
35224
35491
|
const diskFirst = this.tryDiscoverFromDisk(sid);
|
|
35225
35492
|
if (diskFirst) {
|
|
@@ -35238,7 +35505,7 @@ var SessionWorktreeManager = class {
|
|
|
35238
35505
|
this.rememberSessionWorktrees(sid, tryRoot);
|
|
35239
35506
|
return this.sessionParentPathAfterRemember(sid);
|
|
35240
35507
|
}
|
|
35241
|
-
const next =
|
|
35508
|
+
const next = path20.dirname(cur);
|
|
35242
35509
|
if (next === cur) break;
|
|
35243
35510
|
cur = next;
|
|
35244
35511
|
}
|
|
@@ -35391,15 +35658,15 @@ var SessionWorktreeManager = class {
|
|
|
35391
35658
|
}
|
|
35392
35659
|
};
|
|
35393
35660
|
function defaultWorktreesRootPath() {
|
|
35394
|
-
return
|
|
35661
|
+
return path20.join(os5.homedir(), ".buildautomaton", "worktrees");
|
|
35395
35662
|
}
|
|
35396
35663
|
|
|
35397
35664
|
// src/files/watch-file-index.ts
|
|
35398
35665
|
import { watch } from "node:fs";
|
|
35399
|
-
import
|
|
35666
|
+
import path27 from "node:path";
|
|
35400
35667
|
|
|
35401
35668
|
// src/files/index/build-file-index.ts
|
|
35402
|
-
import
|
|
35669
|
+
import path24 from "node:path";
|
|
35403
35670
|
|
|
35404
35671
|
// src/runtime/yield-to-event-loop.ts
|
|
35405
35672
|
function yieldToEventLoop() {
|
|
@@ -35407,14 +35674,14 @@ function yieldToEventLoop() {
|
|
|
35407
35674
|
}
|
|
35408
35675
|
|
|
35409
35676
|
// src/files/index/walk-workspace-tree.ts
|
|
35410
|
-
import
|
|
35411
|
-
import
|
|
35677
|
+
import fs20 from "node:fs";
|
|
35678
|
+
import path22 from "node:path";
|
|
35412
35679
|
|
|
35413
35680
|
// src/files/index/constants.ts
|
|
35414
|
-
import
|
|
35415
|
-
import
|
|
35681
|
+
import path21 from "node:path";
|
|
35682
|
+
import os6 from "node:os";
|
|
35416
35683
|
var INDEX_WORK_YIELD_EVERY = 256;
|
|
35417
|
-
var INDEX_DIR =
|
|
35684
|
+
var INDEX_DIR = path21.join(os6.homedir(), ".buildautomaton");
|
|
35418
35685
|
var INDEX_HASH_LEN = 16;
|
|
35419
35686
|
var INDEX_VERSION = 2;
|
|
35420
35687
|
var INDEX_LOG_PREFIX = "[file-index]";
|
|
@@ -35423,20 +35690,20 @@ var INDEX_LOG_PREFIX = "[file-index]";
|
|
|
35423
35690
|
function walkWorkspaceTreeSync(dir, baseDir, out) {
|
|
35424
35691
|
let names;
|
|
35425
35692
|
try {
|
|
35426
|
-
names =
|
|
35693
|
+
names = fs20.readdirSync(dir);
|
|
35427
35694
|
} catch {
|
|
35428
35695
|
return;
|
|
35429
35696
|
}
|
|
35430
35697
|
for (const name of names) {
|
|
35431
35698
|
if (name.startsWith(".")) continue;
|
|
35432
|
-
const full =
|
|
35699
|
+
const full = path22.join(dir, name);
|
|
35433
35700
|
let stat3;
|
|
35434
35701
|
try {
|
|
35435
|
-
stat3 =
|
|
35702
|
+
stat3 = fs20.statSync(full);
|
|
35436
35703
|
} catch {
|
|
35437
35704
|
continue;
|
|
35438
35705
|
}
|
|
35439
|
-
const relative5 =
|
|
35706
|
+
const relative5 = path22.relative(baseDir, full).replace(/\\/g, "/");
|
|
35440
35707
|
if (stat3.isDirectory()) {
|
|
35441
35708
|
walkWorkspaceTreeSync(full, baseDir, out);
|
|
35442
35709
|
} else if (stat3.isFile()) {
|
|
@@ -35447,7 +35714,7 @@ function walkWorkspaceTreeSync(dir, baseDir, out) {
|
|
|
35447
35714
|
async function walkWorkspaceTreeAsync(dir, baseDir, out, state) {
|
|
35448
35715
|
let names;
|
|
35449
35716
|
try {
|
|
35450
|
-
names = await
|
|
35717
|
+
names = await fs20.promises.readdir(dir);
|
|
35451
35718
|
} catch {
|
|
35452
35719
|
return;
|
|
35453
35720
|
}
|
|
@@ -35457,14 +35724,14 @@ async function walkWorkspaceTreeAsync(dir, baseDir, out, state) {
|
|
|
35457
35724
|
await yieldToEventLoop();
|
|
35458
35725
|
}
|
|
35459
35726
|
state.n++;
|
|
35460
|
-
const full =
|
|
35727
|
+
const full = path22.join(dir, name);
|
|
35461
35728
|
let stat3;
|
|
35462
35729
|
try {
|
|
35463
|
-
stat3 = await
|
|
35730
|
+
stat3 = await fs20.promises.stat(full);
|
|
35464
35731
|
} catch {
|
|
35465
35732
|
continue;
|
|
35466
35733
|
}
|
|
35467
|
-
const relative5 =
|
|
35734
|
+
const relative5 = path22.relative(baseDir, full).replace(/\\/g, "/");
|
|
35468
35735
|
if (stat3.isDirectory()) {
|
|
35469
35736
|
await walkWorkspaceTreeAsync(full, baseDir, out, state);
|
|
35470
35737
|
} else if (stat3.isFile()) {
|
|
@@ -35545,22 +35812,22 @@ async function buildTrigramMapForPathsAsync(paths) {
|
|
|
35545
35812
|
}
|
|
35546
35813
|
|
|
35547
35814
|
// src/files/index/write-index-file.ts
|
|
35548
|
-
import
|
|
35815
|
+
import fs21 from "node:fs";
|
|
35549
35816
|
|
|
35550
35817
|
// src/files/index/paths.ts
|
|
35551
|
-
import
|
|
35818
|
+
import path23 from "node:path";
|
|
35552
35819
|
import crypto2 from "node:crypto";
|
|
35553
35820
|
function getIndexPathForCwd(resolvedCwd) {
|
|
35554
35821
|
const hash = crypto2.createHash("sha256").update(resolvedCwd).digest("hex").slice(0, INDEX_HASH_LEN);
|
|
35555
|
-
return
|
|
35822
|
+
return path23.join(INDEX_DIR, `.file-index-${hash}.json`);
|
|
35556
35823
|
}
|
|
35557
35824
|
|
|
35558
35825
|
// src/files/index/write-index-file.ts
|
|
35559
35826
|
function writeIndexFileSync(resolvedCwd, data) {
|
|
35560
35827
|
const indexPath = getIndexPathForCwd(resolvedCwd);
|
|
35561
35828
|
try {
|
|
35562
|
-
if (!
|
|
35563
|
-
|
|
35829
|
+
if (!fs21.existsSync(INDEX_DIR)) fs21.mkdirSync(INDEX_DIR, { recursive: true });
|
|
35830
|
+
fs21.writeFileSync(indexPath, JSON.stringify(data), "utf8");
|
|
35564
35831
|
} catch (e) {
|
|
35565
35832
|
console.error(`${INDEX_LOG_PREFIX} Failed to write index:`, e);
|
|
35566
35833
|
}
|
|
@@ -35568,8 +35835,8 @@ function writeIndexFileSync(resolvedCwd, data) {
|
|
|
35568
35835
|
async function writeIndexFileAsync(resolvedCwd, data) {
|
|
35569
35836
|
const indexPath = getIndexPathForCwd(resolvedCwd);
|
|
35570
35837
|
try {
|
|
35571
|
-
await
|
|
35572
|
-
await
|
|
35838
|
+
await fs21.promises.mkdir(INDEX_DIR, { recursive: true });
|
|
35839
|
+
await fs21.promises.writeFile(indexPath, JSON.stringify(data), "utf8");
|
|
35573
35840
|
} catch (e) {
|
|
35574
35841
|
console.error(`${INDEX_LOG_PREFIX} Failed to write index:`, e);
|
|
35575
35842
|
}
|
|
@@ -35583,7 +35850,7 @@ function sortPaths(paths) {
|
|
|
35583
35850
|
paths.sort((a, b) => a.localeCompare(b, void 0, { sensitivity: "base" }));
|
|
35584
35851
|
}
|
|
35585
35852
|
function buildFileIndex(cwd) {
|
|
35586
|
-
const resolved =
|
|
35853
|
+
const resolved = path24.resolve(cwd);
|
|
35587
35854
|
const paths = [];
|
|
35588
35855
|
walkWorkspaceTreeSync(resolved, resolved, paths);
|
|
35589
35856
|
sortPaths(paths);
|
|
@@ -35593,7 +35860,7 @@ function buildFileIndex(cwd) {
|
|
|
35593
35860
|
return data;
|
|
35594
35861
|
}
|
|
35595
35862
|
async function buildFileIndexAsync(cwd) {
|
|
35596
|
-
const resolved =
|
|
35863
|
+
const resolved = path24.resolve(cwd);
|
|
35597
35864
|
const paths = [];
|
|
35598
35865
|
await walkWorkspaceTreeAsync(resolved, resolved, paths, createWalkYieldState());
|
|
35599
35866
|
await yieldToEventLoop();
|
|
@@ -35605,13 +35872,13 @@ async function buildFileIndexAsync(cwd) {
|
|
|
35605
35872
|
}
|
|
35606
35873
|
|
|
35607
35874
|
// src/files/index/load-file-index.ts
|
|
35608
|
-
import
|
|
35609
|
-
import
|
|
35875
|
+
import fs22 from "node:fs";
|
|
35876
|
+
import path25 from "node:path";
|
|
35610
35877
|
function loadFileIndex(cwd) {
|
|
35611
|
-
const resolved =
|
|
35878
|
+
const resolved = path25.resolve(cwd);
|
|
35612
35879
|
const indexPath = getIndexPathForCwd(resolved);
|
|
35613
35880
|
try {
|
|
35614
|
-
const raw =
|
|
35881
|
+
const raw = fs22.readFileSync(indexPath, "utf8");
|
|
35615
35882
|
const parsed = JSON.parse(raw);
|
|
35616
35883
|
if (parsed !== null && typeof parsed === "object" && Array.isArray(parsed.paths)) {
|
|
35617
35884
|
const obj = parsed;
|
|
@@ -35630,9 +35897,9 @@ function loadFileIndex(cwd) {
|
|
|
35630
35897
|
}
|
|
35631
35898
|
|
|
35632
35899
|
// src/files/index/ensure-file-index.ts
|
|
35633
|
-
import
|
|
35900
|
+
import path26 from "node:path";
|
|
35634
35901
|
async function ensureFileIndexAsync(cwd) {
|
|
35635
|
-
const resolved =
|
|
35902
|
+
const resolved = path26.resolve(cwd);
|
|
35636
35903
|
const cached2 = loadFileIndex(resolved);
|
|
35637
35904
|
if (cached2 !== null) return { data: cached2, fromCache: true };
|
|
35638
35905
|
const data = await buildFileIndexAsync(resolved);
|
|
@@ -35715,7 +35982,7 @@ function createFsWatcher(resolved, schedule) {
|
|
|
35715
35982
|
}
|
|
35716
35983
|
}
|
|
35717
35984
|
function startFileIndexWatcher(cwd = getBridgeRoot()) {
|
|
35718
|
-
const resolved =
|
|
35985
|
+
const resolved = path27.resolve(cwd);
|
|
35719
35986
|
void buildFileIndexAsync(resolved).catch((e) => {
|
|
35720
35987
|
console.error("[file-index] Initial index build failed:", e);
|
|
35721
35988
|
});
|
|
@@ -35743,7 +36010,7 @@ function startFileIndexWatcher(cwd = getBridgeRoot()) {
|
|
|
35743
36010
|
}
|
|
35744
36011
|
|
|
35745
36012
|
// src/connection/create-bridge-connection.ts
|
|
35746
|
-
import * as
|
|
36013
|
+
import * as path35 from "node:path";
|
|
35747
36014
|
|
|
35748
36015
|
// src/dev-servers/manager/dev-server-manager.ts
|
|
35749
36016
|
import { rm as rm2 } from "node:fs/promises";
|
|
@@ -35787,7 +36054,7 @@ function forceKillChild(proc, log2, shortId, graceMs) {
|
|
|
35787
36054
|
}
|
|
35788
36055
|
|
|
35789
36056
|
// src/dev-servers/process/wire-dev-server-child-process.ts
|
|
35790
|
-
import
|
|
36057
|
+
import fs23 from "node:fs";
|
|
35791
36058
|
|
|
35792
36059
|
// src/dev-servers/manager/forward-pipe.ts
|
|
35793
36060
|
function forwardChildPipe(childReadable, terminal, onData) {
|
|
@@ -35823,7 +36090,7 @@ function wireDevServerChildProcess(d) {
|
|
|
35823
36090
|
d.setPollInterval(void 0);
|
|
35824
36091
|
return;
|
|
35825
36092
|
}
|
|
35826
|
-
|
|
36093
|
+
fs23.readFile(d.mergedLogPath, (err, buf) => {
|
|
35827
36094
|
if (err || (d.getSpawnGeneration() ?? 0) !== d.scheduledGen) return;
|
|
35828
36095
|
if (buf.length <= d.mergedReadPos.value) return;
|
|
35829
36096
|
const chunk = Buffer.from(buf.subarray(d.mergedReadPos.value));
|
|
@@ -35861,7 +36128,7 @@ ${errTail}` : ""}`);
|
|
|
35861
36128
|
d.sendStatus(code === 0 || code == null ? "stopped" : "error", detail, tails);
|
|
35862
36129
|
};
|
|
35863
36130
|
if (mergedPath) {
|
|
35864
|
-
|
|
36131
|
+
fs23.readFile(mergedPath, (err, buf) => {
|
|
35865
36132
|
if (!err && buf.length > d.mergedReadPos.value) {
|
|
35866
36133
|
const chunk = Buffer.from(buf.subarray(d.mergedReadPos.value));
|
|
35867
36134
|
if (chunk.length > 0) {
|
|
@@ -35963,13 +36230,13 @@ function parseDevServerDefs(servers) {
|
|
|
35963
36230
|
}
|
|
35964
36231
|
|
|
35965
36232
|
// src/dev-servers/manager/shell-spawn/utils.ts
|
|
35966
|
-
import
|
|
36233
|
+
import fs24 from "node:fs";
|
|
35967
36234
|
function isSpawnEbadf(e) {
|
|
35968
36235
|
return typeof e === "object" && e !== null && "code" in e && e.code === "EBADF";
|
|
35969
36236
|
}
|
|
35970
36237
|
function rmDirQuiet(dir) {
|
|
35971
36238
|
try {
|
|
35972
|
-
|
|
36239
|
+
fs24.rmSync(dir, { recursive: true, force: true });
|
|
35973
36240
|
} catch {
|
|
35974
36241
|
}
|
|
35975
36242
|
}
|
|
@@ -35977,7 +36244,7 @@ var cachedDevNullReadFd;
|
|
|
35977
36244
|
function devNullReadFd() {
|
|
35978
36245
|
if (cachedDevNullReadFd === void 0) {
|
|
35979
36246
|
const devPath = process.platform === "win32" ? "nul" : "/dev/null";
|
|
35980
|
-
cachedDevNullReadFd =
|
|
36247
|
+
cachedDevNullReadFd = fs24.openSync(devPath, "r");
|
|
35981
36248
|
}
|
|
35982
36249
|
return cachedDevNullReadFd;
|
|
35983
36250
|
}
|
|
@@ -36051,15 +36318,15 @@ function trySpawnShellTruePiped(command, env, cwd, devNullFd, signal) {
|
|
|
36051
36318
|
|
|
36052
36319
|
// src/dev-servers/manager/shell-spawn/try-spawn-merged-log-file.ts
|
|
36053
36320
|
import { spawn as spawn6 } from "node:child_process";
|
|
36054
|
-
import
|
|
36321
|
+
import fs25 from "node:fs";
|
|
36055
36322
|
import { tmpdir } from "node:os";
|
|
36056
|
-
import
|
|
36323
|
+
import path28 from "node:path";
|
|
36057
36324
|
function trySpawnMergedLogFile(command, env, cwd, signal) {
|
|
36058
|
-
const tmpRoot =
|
|
36059
|
-
const logPath =
|
|
36325
|
+
const tmpRoot = fs25.mkdtempSync(path28.join(tmpdir(), "ba-devsrv-log-"));
|
|
36326
|
+
const logPath = path28.join(tmpRoot, "combined.log");
|
|
36060
36327
|
let logFd;
|
|
36061
36328
|
try {
|
|
36062
|
-
logFd =
|
|
36329
|
+
logFd = fs25.openSync(logPath, "a");
|
|
36063
36330
|
} catch {
|
|
36064
36331
|
rmDirQuiet(tmpRoot);
|
|
36065
36332
|
return null;
|
|
@@ -36078,7 +36345,7 @@ function trySpawnMergedLogFile(command, env, cwd, signal) {
|
|
|
36078
36345
|
} else {
|
|
36079
36346
|
proc = spawn6("/bin/sh", ["-c", command], { env, cwd, stdio, ...signal ? { signal } : {} });
|
|
36080
36347
|
}
|
|
36081
|
-
|
|
36348
|
+
fs25.closeSync(logFd);
|
|
36082
36349
|
return {
|
|
36083
36350
|
proc,
|
|
36084
36351
|
pipedStdoutStderr: true,
|
|
@@ -36087,7 +36354,7 @@ function trySpawnMergedLogFile(command, env, cwd, signal) {
|
|
|
36087
36354
|
};
|
|
36088
36355
|
} catch (e) {
|
|
36089
36356
|
try {
|
|
36090
|
-
|
|
36357
|
+
fs25.closeSync(logFd);
|
|
36091
36358
|
} catch {
|
|
36092
36359
|
}
|
|
36093
36360
|
rmDirQuiet(tmpRoot);
|
|
@@ -36098,22 +36365,22 @@ function trySpawnMergedLogFile(command, env, cwd, signal) {
|
|
|
36098
36365
|
|
|
36099
36366
|
// src/dev-servers/manager/shell-spawn/try-spawn-shell-script-log-redirect.ts
|
|
36100
36367
|
import { spawn as spawn7 } from "node:child_process";
|
|
36101
|
-
import
|
|
36368
|
+
import fs26 from "node:fs";
|
|
36102
36369
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
36103
|
-
import
|
|
36370
|
+
import path29 from "node:path";
|
|
36104
36371
|
function shSingleQuote(s) {
|
|
36105
36372
|
return `'${s.replace(/'/g, `'\\''`)}'`;
|
|
36106
36373
|
}
|
|
36107
36374
|
function trySpawnShellScriptLogRedirectUnix(command, env, cwd, signal) {
|
|
36108
|
-
const tmpRoot =
|
|
36109
|
-
const logPath =
|
|
36110
|
-
const innerPath =
|
|
36111
|
-
const runnerPath =
|
|
36375
|
+
const tmpRoot = fs26.mkdtempSync(path29.join(tmpdir2(), "ba-devsrv-sh-"));
|
|
36376
|
+
const logPath = path29.join(tmpRoot, "combined.log");
|
|
36377
|
+
const innerPath = path29.join(tmpRoot, "_cmd.sh");
|
|
36378
|
+
const runnerPath = path29.join(tmpRoot, "_run.sh");
|
|
36112
36379
|
try {
|
|
36113
|
-
|
|
36380
|
+
fs26.writeFileSync(innerPath, `#!/bin/sh
|
|
36114
36381
|
${command}
|
|
36115
36382
|
`);
|
|
36116
|
-
|
|
36383
|
+
fs26.writeFileSync(
|
|
36117
36384
|
runnerPath,
|
|
36118
36385
|
`#!/bin/sh
|
|
36119
36386
|
cd ${shSingleQuote(cwd)}
|
|
@@ -36139,13 +36406,13 @@ cd ${shSingleQuote(cwd)}
|
|
|
36139
36406
|
}
|
|
36140
36407
|
}
|
|
36141
36408
|
function trySpawnShellScriptLogRedirectWin(command, env, cwd, signal) {
|
|
36142
|
-
const tmpRoot =
|
|
36143
|
-
const logPath =
|
|
36144
|
-
const runnerPath =
|
|
36409
|
+
const tmpRoot = fs26.mkdtempSync(path29.join(tmpdir2(), "ba-devsrv-sh-"));
|
|
36410
|
+
const logPath = path29.join(tmpRoot, "combined.log");
|
|
36411
|
+
const runnerPath = path29.join(tmpRoot, "_run.bat");
|
|
36145
36412
|
const q = (p) => `"${p.replace(/"/g, '""')}"`;
|
|
36146
36413
|
const com = process.env.ComSpec || "cmd.exe";
|
|
36147
36414
|
try {
|
|
36148
|
-
|
|
36415
|
+
fs26.writeFileSync(
|
|
36149
36416
|
runnerPath,
|
|
36150
36417
|
`@ECHO OFF\r
|
|
36151
36418
|
CD /D ${q(cwd)}\r
|
|
@@ -37082,30 +37349,30 @@ function createOnBridgeIdentified(opts) {
|
|
|
37082
37349
|
}
|
|
37083
37350
|
|
|
37084
37351
|
// src/skills/discover-local-agent-skills.ts
|
|
37085
|
-
import
|
|
37086
|
-
import
|
|
37352
|
+
import fs27 from "node:fs";
|
|
37353
|
+
import path30 from "node:path";
|
|
37087
37354
|
var SKILL_DISCOVERY_ROOTS = [".agents/skills", ".claude/skills", ".cursor/skills", "skills"];
|
|
37088
37355
|
function discoverLocalSkills(cwd) {
|
|
37089
37356
|
const out = [];
|
|
37090
37357
|
const seenKeys = /* @__PURE__ */ new Set();
|
|
37091
37358
|
for (const rel of SKILL_DISCOVERY_ROOTS) {
|
|
37092
|
-
const base =
|
|
37093
|
-
if (!
|
|
37359
|
+
const base = path30.join(cwd, rel);
|
|
37360
|
+
if (!fs27.existsSync(base) || !fs27.statSync(base).isDirectory()) continue;
|
|
37094
37361
|
let entries = [];
|
|
37095
37362
|
try {
|
|
37096
|
-
entries =
|
|
37363
|
+
entries = fs27.readdirSync(base);
|
|
37097
37364
|
} catch {
|
|
37098
37365
|
continue;
|
|
37099
37366
|
}
|
|
37100
37367
|
for (const name of entries) {
|
|
37101
|
-
const dir =
|
|
37368
|
+
const dir = path30.join(base, name);
|
|
37102
37369
|
try {
|
|
37103
|
-
if (!
|
|
37370
|
+
if (!fs27.statSync(dir).isDirectory()) continue;
|
|
37104
37371
|
} catch {
|
|
37105
37372
|
continue;
|
|
37106
37373
|
}
|
|
37107
|
-
const skillMd =
|
|
37108
|
-
if (!
|
|
37374
|
+
const skillMd = path30.join(dir, "SKILL.md");
|
|
37375
|
+
if (!fs27.existsSync(skillMd)) continue;
|
|
37109
37376
|
const key = `${rel}/${name}`;
|
|
37110
37377
|
if (seenKeys.has(key)) continue;
|
|
37111
37378
|
seenKeys.add(key);
|
|
@@ -37117,23 +37384,23 @@ function discoverLocalSkills(cwd) {
|
|
|
37117
37384
|
function discoverSkillLayoutRoots(cwd) {
|
|
37118
37385
|
const roots = [];
|
|
37119
37386
|
for (const rel of SKILL_DISCOVERY_ROOTS) {
|
|
37120
|
-
const base =
|
|
37121
|
-
if (!
|
|
37387
|
+
const base = path30.join(cwd, rel);
|
|
37388
|
+
if (!fs27.existsSync(base) || !fs27.statSync(base).isDirectory()) continue;
|
|
37122
37389
|
let entries = [];
|
|
37123
37390
|
try {
|
|
37124
|
-
entries =
|
|
37391
|
+
entries = fs27.readdirSync(base);
|
|
37125
37392
|
} catch {
|
|
37126
37393
|
continue;
|
|
37127
37394
|
}
|
|
37128
37395
|
const skills2 = [];
|
|
37129
37396
|
for (const name of entries) {
|
|
37130
|
-
const dir =
|
|
37397
|
+
const dir = path30.join(base, name);
|
|
37131
37398
|
try {
|
|
37132
|
-
if (!
|
|
37399
|
+
if (!fs27.statSync(dir).isDirectory()) continue;
|
|
37133
37400
|
} catch {
|
|
37134
37401
|
continue;
|
|
37135
37402
|
}
|
|
37136
|
-
if (!
|
|
37403
|
+
if (!fs27.existsSync(path30.join(dir, "SKILL.md"))) continue;
|
|
37137
37404
|
const relPath = `${rel}/${name}`.replace(/\\/g, "/");
|
|
37138
37405
|
skills2.push({ name, relPath });
|
|
37139
37406
|
}
|
|
@@ -37315,7 +37582,7 @@ var handleAgentConfigMessage = (msg, deps) => {
|
|
|
37315
37582
|
};
|
|
37316
37583
|
|
|
37317
37584
|
// src/prompt-turn-queue/runner.ts
|
|
37318
|
-
import
|
|
37585
|
+
import fs30 from "node:fs";
|
|
37319
37586
|
|
|
37320
37587
|
// src/prompt-turn-queue/client-report.ts
|
|
37321
37588
|
function sendPromptQueueClientReport(ws, queues) {
|
|
@@ -37325,13 +37592,13 @@ function sendPromptQueueClientReport(ws, queues) {
|
|
|
37325
37592
|
}
|
|
37326
37593
|
|
|
37327
37594
|
// src/prompt-turn-queue/disk-store.ts
|
|
37328
|
-
import
|
|
37595
|
+
import fs29 from "node:fs";
|
|
37329
37596
|
|
|
37330
37597
|
// src/prompt-turn-queue/paths.ts
|
|
37331
37598
|
import crypto3 from "node:crypto";
|
|
37332
|
-
import
|
|
37333
|
-
import
|
|
37334
|
-
import
|
|
37599
|
+
import fs28 from "node:fs";
|
|
37600
|
+
import path31 from "node:path";
|
|
37601
|
+
import os7 from "node:os";
|
|
37335
37602
|
var QUEUE_KEY_HEX_64 = /^[a-f0-9]{64}$/i;
|
|
37336
37603
|
function queueStateFileSlug(queueKey) {
|
|
37337
37604
|
if (QUEUE_KEY_HEX_64.test(queueKey)) return queueKey.toLowerCase();
|
|
@@ -37339,15 +37606,15 @@ function queueStateFileSlug(queueKey) {
|
|
|
37339
37606
|
}
|
|
37340
37607
|
function getPromptQueuesDirectory() {
|
|
37341
37608
|
const override = process.env.BUILDAMATON_PROMPT_QUEUES_DIR?.trim();
|
|
37342
|
-
if (override) return
|
|
37343
|
-
return
|
|
37609
|
+
if (override) return path31.resolve(override);
|
|
37610
|
+
return path31.join(os7.homedir(), ".buildautomaton", "queues");
|
|
37344
37611
|
}
|
|
37345
37612
|
function ensurePromptQueuesDirectory() {
|
|
37346
37613
|
const dir = getPromptQueuesDirectory();
|
|
37347
|
-
if (!
|
|
37614
|
+
if (!fs28.existsSync(dir)) fs28.mkdirSync(dir, { recursive: true });
|
|
37348
37615
|
}
|
|
37349
37616
|
function queueStateFilePath(queueKey) {
|
|
37350
|
-
return
|
|
37617
|
+
return path31.join(getPromptQueuesDirectory(), `${queueStateFileSlug(queueKey)}.json`);
|
|
37351
37618
|
}
|
|
37352
37619
|
|
|
37353
37620
|
// src/prompt-turn-queue/disk-store.ts
|
|
@@ -37372,7 +37639,7 @@ function parsePersistedQueueFile(raw) {
|
|
|
37372
37639
|
function readPersistedQueue(queueKey) {
|
|
37373
37640
|
const p = queueStateFilePath(queueKey);
|
|
37374
37641
|
try {
|
|
37375
|
-
return parsePersistedQueueFile(
|
|
37642
|
+
return parsePersistedQueueFile(fs29.readFileSync(p, "utf8"));
|
|
37376
37643
|
} catch {
|
|
37377
37644
|
return null;
|
|
37378
37645
|
}
|
|
@@ -37380,7 +37647,7 @@ function readPersistedQueue(queueKey) {
|
|
|
37380
37647
|
function writePersistedQueue(file2) {
|
|
37381
37648
|
ensurePromptQueuesDirectory();
|
|
37382
37649
|
const p = queueStateFilePath(file2.queueKey);
|
|
37383
|
-
|
|
37650
|
+
fs29.writeFileSync(p, JSON.stringify(file2, null, 2), "utf8");
|
|
37384
37651
|
}
|
|
37385
37652
|
function mergeServerQueueSnapshot(queueKey, serverTurns) {
|
|
37386
37653
|
const prev = readPersistedQueue(queueKey);
|
|
@@ -37438,7 +37705,7 @@ async function runLocalRevertBeforeQueuedPrompt(next, deps) {
|
|
|
37438
37705
|
const tid = typeof pl.snapshotRevertTurnId === "string" && pl.snapshotRevertTurnId.trim() !== "" ? pl.snapshotRevertTurnId.trim() : next.turnId;
|
|
37439
37706
|
const agentBase = deps.sessionWorktreeManager.getSessionWorktreeRootForSession(sid) ?? getBridgeRoot();
|
|
37440
37707
|
const file2 = snapshotFilePath(agentBase, tid);
|
|
37441
|
-
if (!
|
|
37708
|
+
if (!fs30.existsSync(file2)) {
|
|
37442
37709
|
deps.log(
|
|
37443
37710
|
`[Queue] requeued_with_revert: no pre-turn snapshot for ${tid.slice(0, 8)}\u2026; continuing without revert.`
|
|
37444
37711
|
);
|
|
@@ -37661,9 +37928,9 @@ function parseChangeSummarySnapshots(raw) {
|
|
|
37661
37928
|
for (const item of raw) {
|
|
37662
37929
|
if (!item || typeof item !== "object") continue;
|
|
37663
37930
|
const o = item;
|
|
37664
|
-
const
|
|
37665
|
-
if (!
|
|
37666
|
-
const row = { path:
|
|
37931
|
+
const path37 = typeof o.path === "string" && o.path.trim() !== "" ? o.path.trim() : "";
|
|
37932
|
+
if (!path37) continue;
|
|
37933
|
+
const row = { path: path37 };
|
|
37667
37934
|
if (typeof o.patchContent === "string") row.patchContent = o.patchContent;
|
|
37668
37935
|
if (typeof o.oldText === "string") row.oldText = o.oldText;
|
|
37669
37936
|
if (typeof o.newText === "string") row.newText = o.newText;
|
|
@@ -37864,8 +38131,8 @@ function randomSecret() {
|
|
|
37864
38131
|
}
|
|
37865
38132
|
return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
37866
38133
|
}
|
|
37867
|
-
async function requestPreviewApi(port, secret, method,
|
|
37868
|
-
const url2 = `http://127.0.0.1:${port}${
|
|
38134
|
+
async function requestPreviewApi(port, secret, method, path37, body) {
|
|
38135
|
+
const url2 = `http://127.0.0.1:${port}${path37}`;
|
|
37869
38136
|
const headers = {
|
|
37870
38137
|
[PREVIEW_SECRET_HEADER]: secret,
|
|
37871
38138
|
"Content-Type": "application/json"
|
|
@@ -37877,7 +38144,7 @@ async function requestPreviewApi(port, secret, method, path36, body) {
|
|
|
37877
38144
|
});
|
|
37878
38145
|
const data = await res.json().catch(() => ({}));
|
|
37879
38146
|
if (!res.ok) {
|
|
37880
|
-
throw new Error(data?.error ?? `Preview API ${method} ${
|
|
38147
|
+
throw new Error(data?.error ?? `Preview API ${method} ${path37}: ${res.status}`);
|
|
37881
38148
|
}
|
|
37882
38149
|
return data;
|
|
37883
38150
|
}
|
|
@@ -38042,15 +38309,15 @@ var handleSkillCallMessage = (msg, { getWs, log: log2 }) => {
|
|
|
38042
38309
|
};
|
|
38043
38310
|
|
|
38044
38311
|
// src/files/list-dir.ts
|
|
38045
|
-
import
|
|
38046
|
-
import
|
|
38312
|
+
import fs31 from "node:fs";
|
|
38313
|
+
import path33 from "node:path";
|
|
38047
38314
|
|
|
38048
38315
|
// src/files/ensure-under-cwd.ts
|
|
38049
|
-
import
|
|
38316
|
+
import path32 from "node:path";
|
|
38050
38317
|
function ensureUnderCwd(relativePath, cwd = getBridgeRoot()) {
|
|
38051
|
-
const normalized =
|
|
38052
|
-
const resolved =
|
|
38053
|
-
if (!resolved.startsWith(cwd +
|
|
38318
|
+
const normalized = path32.normalize(relativePath).replace(/^(\.\/)+/, "");
|
|
38319
|
+
const resolved = path32.resolve(cwd, normalized);
|
|
38320
|
+
if (!resolved.startsWith(cwd + path32.sep) && resolved !== cwd) {
|
|
38054
38321
|
return null;
|
|
38055
38322
|
}
|
|
38056
38323
|
return resolved;
|
|
@@ -38064,7 +38331,7 @@ async function listDirAsync(relativePath) {
|
|
|
38064
38331
|
return { error: "Path is outside working directory" };
|
|
38065
38332
|
}
|
|
38066
38333
|
try {
|
|
38067
|
-
const names = await
|
|
38334
|
+
const names = await fs31.promises.readdir(resolved, { withFileTypes: true });
|
|
38068
38335
|
const visible = names.filter((d) => !d.name.startsWith("."));
|
|
38069
38336
|
const entries = [];
|
|
38070
38337
|
for (let i = 0; i < visible.length; i++) {
|
|
@@ -38072,12 +38339,12 @@ async function listDirAsync(relativePath) {
|
|
|
38072
38339
|
await yieldToEventLoop();
|
|
38073
38340
|
}
|
|
38074
38341
|
const d = visible[i];
|
|
38075
|
-
const entryPath =
|
|
38076
|
-
const fullPath =
|
|
38342
|
+
const entryPath = path33.join(relativePath || ".", d.name).replace(/\\/g, "/");
|
|
38343
|
+
const fullPath = path33.join(resolved, d.name);
|
|
38077
38344
|
let isDir = d.isDirectory();
|
|
38078
38345
|
if (d.isSymbolicLink()) {
|
|
38079
38346
|
try {
|
|
38080
|
-
const targetStat = await
|
|
38347
|
+
const targetStat = await fs31.promises.stat(fullPath);
|
|
38081
38348
|
isDir = targetStat.isDirectory();
|
|
38082
38349
|
} catch {
|
|
38083
38350
|
isDir = false;
|
|
@@ -38102,25 +38369,25 @@ async function listDirAsync(relativePath) {
|
|
|
38102
38369
|
}
|
|
38103
38370
|
|
|
38104
38371
|
// src/files/read-file.ts
|
|
38105
|
-
import
|
|
38372
|
+
import fs32 from "node:fs";
|
|
38106
38373
|
import { StringDecoder } from "node:string_decoder";
|
|
38107
38374
|
function resolveFilePath(relativePath) {
|
|
38108
38375
|
const resolved = ensureUnderCwd(relativePath, getBridgeRoot());
|
|
38109
38376
|
if (!resolved) return { error: "Path is outside working directory" };
|
|
38110
38377
|
let real;
|
|
38111
38378
|
try {
|
|
38112
|
-
real =
|
|
38379
|
+
real = fs32.realpathSync(resolved);
|
|
38113
38380
|
} catch {
|
|
38114
38381
|
real = resolved;
|
|
38115
38382
|
}
|
|
38116
|
-
const stat3 =
|
|
38383
|
+
const stat3 = fs32.statSync(real);
|
|
38117
38384
|
if (!stat3.isFile()) return { error: "Not a file" };
|
|
38118
38385
|
return real;
|
|
38119
38386
|
}
|
|
38120
38387
|
var LINE_CHUNK_SIZE = 64 * 1024;
|
|
38121
38388
|
function readFileRange(filePath, startLine, endLine, lineOffsetIn, lineChunkSize = LINE_CHUNK_SIZE) {
|
|
38122
|
-
const fileSize =
|
|
38123
|
-
const fd =
|
|
38389
|
+
const fileSize = fs32.statSync(filePath).size;
|
|
38390
|
+
const fd = fs32.openSync(filePath, "r");
|
|
38124
38391
|
const bufSize = 64 * 1024;
|
|
38125
38392
|
const buf = Buffer.alloc(bufSize);
|
|
38126
38393
|
const decoder = new StringDecoder("utf8");
|
|
@@ -38133,7 +38400,7 @@ function readFileRange(filePath, startLine, endLine, lineOffsetIn, lineChunkSize
|
|
|
38133
38400
|
let line0Accum = "";
|
|
38134
38401
|
try {
|
|
38135
38402
|
let bytesRead;
|
|
38136
|
-
while (!done && (bytesRead =
|
|
38403
|
+
while (!done && (bytesRead = fs32.readSync(fd, buf, 0, bufSize, null)) > 0) {
|
|
38137
38404
|
const text = partial2 + decoder.write(buf.subarray(0, bytesRead));
|
|
38138
38405
|
partial2 = "";
|
|
38139
38406
|
let lineStart = 0;
|
|
@@ -38268,7 +38535,7 @@ function readFileRange(filePath, startLine, endLine, lineOffsetIn, lineChunkSize
|
|
|
38268
38535
|
}
|
|
38269
38536
|
return { content: resultLines.join("\n"), size: fileSize };
|
|
38270
38537
|
} finally {
|
|
38271
|
-
|
|
38538
|
+
fs32.closeSync(fd);
|
|
38272
38539
|
}
|
|
38273
38540
|
}
|
|
38274
38541
|
function readFile3(relativePath, startLine, endLine, lineOffset, lineChunkSize = LINE_CHUNK_SIZE) {
|
|
@@ -38279,8 +38546,8 @@ function readFile3(relativePath, startLine, endLine, lineOffset, lineChunkSize =
|
|
|
38279
38546
|
if (hasRange) {
|
|
38280
38547
|
return readFileRange(result, startLine, endLine, lineOffset, lineChunkSize);
|
|
38281
38548
|
}
|
|
38282
|
-
const stat3 =
|
|
38283
|
-
const raw =
|
|
38549
|
+
const stat3 = fs32.statSync(result);
|
|
38550
|
+
const raw = fs32.readFileSync(result, "utf8");
|
|
38284
38551
|
const lines = raw.split(/\r?\n/);
|
|
38285
38552
|
return { content: raw, totalLines: lines.length, size: stat3.size };
|
|
38286
38553
|
} catch (err) {
|
|
@@ -38398,8 +38665,8 @@ function handleSkillLayoutRequest(msg, deps) {
|
|
|
38398
38665
|
}
|
|
38399
38666
|
|
|
38400
38667
|
// src/skills/install-remote-skills.ts
|
|
38401
|
-
import
|
|
38402
|
-
import
|
|
38668
|
+
import fs33 from "node:fs";
|
|
38669
|
+
import path34 from "node:path";
|
|
38403
38670
|
function installRemoteSkills(cwd, targetDir, items) {
|
|
38404
38671
|
const installed2 = [];
|
|
38405
38672
|
if (!Array.isArray(items)) {
|
|
@@ -38410,15 +38677,15 @@ function installRemoteSkills(cwd, targetDir, items) {
|
|
|
38410
38677
|
if (typeof item.sourceId !== "string" || typeof item.skillName !== "string" || typeof item.versionHash !== "string" || !Array.isArray(item.files)) {
|
|
38411
38678
|
continue;
|
|
38412
38679
|
}
|
|
38413
|
-
const skillDir =
|
|
38680
|
+
const skillDir = path34.join(cwd, targetDir, item.skillName);
|
|
38414
38681
|
for (const f of item.files) {
|
|
38415
38682
|
if (typeof f.path !== "string" || !f.text && !f.base64) continue;
|
|
38416
|
-
const dest =
|
|
38417
|
-
|
|
38683
|
+
const dest = path34.join(skillDir, f.path);
|
|
38684
|
+
fs33.mkdirSync(path34.dirname(dest), { recursive: true });
|
|
38418
38685
|
if (f.text !== void 0) {
|
|
38419
|
-
|
|
38686
|
+
fs33.writeFileSync(dest, f.text, "utf8");
|
|
38420
38687
|
} else if (f.base64) {
|
|
38421
|
-
|
|
38688
|
+
fs33.writeFileSync(dest, Buffer.from(f.base64, "base64"));
|
|
38422
38689
|
}
|
|
38423
38690
|
}
|
|
38424
38691
|
installed2.push({
|
|
@@ -38568,7 +38835,7 @@ var handleSessionDiscardedMessage = (msg, deps) => {
|
|
|
38568
38835
|
};
|
|
38569
38836
|
|
|
38570
38837
|
// src/routing/handlers/revert-turn-snapshot.ts
|
|
38571
|
-
import * as
|
|
38838
|
+
import * as fs34 from "node:fs";
|
|
38572
38839
|
var handleRevertTurnSnapshotMessage = (msg, deps) => {
|
|
38573
38840
|
const id = typeof msg.id === "string" ? msg.id : "";
|
|
38574
38841
|
const sessionId = typeof msg.sessionId === "string" ? msg.sessionId : "";
|
|
@@ -38580,7 +38847,7 @@ var handleRevertTurnSnapshotMessage = (msg, deps) => {
|
|
|
38580
38847
|
if (!s) return;
|
|
38581
38848
|
const agentBase = sessionWorktreeManager.getSessionWorktreeRootForSession(sessionId) ?? getBridgeRoot();
|
|
38582
38849
|
const file2 = snapshotFilePath(agentBase, turnId);
|
|
38583
|
-
if (!
|
|
38850
|
+
if (!fs34.existsSync(file2)) {
|
|
38584
38851
|
sendWsMessage(s, {
|
|
38585
38852
|
type: "revert_turn_snapshot_result",
|
|
38586
38853
|
id,
|
|
@@ -38953,8 +39220,8 @@ async function createBridgeConnection(options) {
|
|
|
38953
39220
|
getCloudAccessToken: () => tokens.accessToken
|
|
38954
39221
|
};
|
|
38955
39222
|
const identifyReportedPaths = {
|
|
38956
|
-
bridgeRootPath:
|
|
38957
|
-
worktreesRootPath:
|
|
39223
|
+
bridgeRootPath: path35.resolve(getBridgeRoot()),
|
|
39224
|
+
worktreesRootPath: path35.resolve(worktreesRootPath)
|
|
38958
39225
|
};
|
|
38959
39226
|
const { connect } = createMainBridgeWebSocketLifecycle({
|
|
38960
39227
|
state,
|
|
@@ -39190,9 +39457,9 @@ async function runCliAction(program2, opts) {
|
|
|
39190
39457
|
const firehoseServerUrl = opts.firehoseUrl ?? opts.proxyUrl ?? process.env.BUILDAUTOMATON_FIREHOSE_URL ?? process.env.BUILDAUTOMATON_PROXY_URL ?? DEFAULT_FIREHOSE_URL;
|
|
39191
39458
|
const bridgeRootOpt = (opts.bridgeRoot && typeof opts.bridgeRoot === "string" && opts.bridgeRoot.trim() ? opts.bridgeRoot.trim() : null) ?? (opts.cwd && typeof opts.cwd === "string" && opts.cwd.trim() ? opts.cwd.trim() : null);
|
|
39192
39459
|
if (bridgeRootOpt) {
|
|
39193
|
-
const resolvedBridgeRoot =
|
|
39460
|
+
const resolvedBridgeRoot = path36.resolve(process.cwd(), bridgeRootOpt);
|
|
39194
39461
|
try {
|
|
39195
|
-
const st =
|
|
39462
|
+
const st = fs35.statSync(resolvedBridgeRoot);
|
|
39196
39463
|
if (!st.isDirectory()) {
|
|
39197
39464
|
console.error(`Bridge root is not a directory: ${resolvedBridgeRoot}`);
|
|
39198
39465
|
process.exit(1);
|
|
@@ -39212,7 +39479,7 @@ async function runCliAction(program2, opts) {
|
|
|
39212
39479
|
);
|
|
39213
39480
|
let worktreesRootPath;
|
|
39214
39481
|
if (opts.worktreesRoot && opts.worktreesRoot.trim()) {
|
|
39215
|
-
worktreesRootPath =
|
|
39482
|
+
worktreesRootPath = path36.resolve(opts.worktreesRoot.trim());
|
|
39216
39483
|
}
|
|
39217
39484
|
const e2eCertificates = opts.e2eeCertificatesDir?.trim() ? await loadOrCreateE2eCertificates(opts.e2eeCertificatesDir.trim()) : void 0;
|
|
39218
39485
|
if (e2eCertificates) {
|