@buildautomaton/cli 0.1.28 → 0.1.29
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 +809 -611
- package/dist/cli.js.map +4 -4
- package/dist/index.js +774 -576
- package/dist/index.js.map +4 -4
- package/dist/migrations/000_bootstrap_migrations_table.sql +4 -0
- package/dist/migrations/001_cli_sqlite_checkpoint_v1.sql +20 -0
- package/package.json +3 -2
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 path41 = __require("node:path");
|
|
977
|
+
var fs38 = __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 = path41.resolve(baseDir, baseName);
|
|
1910
|
+
if (fs38.existsSync(localBin)) return localBin;
|
|
1911
|
+
if (sourceExt.includes(path41.extname(baseName))) return void 0;
|
|
1912
1912
|
const foundExt = sourceExt.find(
|
|
1913
|
-
(ext) =>
|
|
1913
|
+
(ext) => fs38.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 = fs38.realpathSync(this._scriptPath);
|
|
1926
1926
|
} catch (err) {
|
|
1927
1927
|
resolvedScriptPath = this._scriptPath;
|
|
1928
1928
|
}
|
|
1929
|
-
executableDir =
|
|
1930
|
-
|
|
1929
|
+
executableDir = path41.resolve(
|
|
1930
|
+
path41.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 = path41.basename(
|
|
1938
1938
|
this._scriptPath,
|
|
1939
|
-
|
|
1939
|
+
path41.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(path41.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 = path41.basename(filename, path41.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(path42) {
|
|
2805
|
+
if (path42 === void 0) return this._executableDir;
|
|
2806
|
+
this._executableDir = path42;
|
|
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: path41, errorMaps, issueData } = params;
|
|
7065
|
+
const fullPath = [...path41, ...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, path41, key) {
|
|
7374
7374
|
this._cachedPath = [];
|
|
7375
7375
|
this.parent = parent;
|
|
7376
7376
|
this.data = value;
|
|
7377
|
-
this._path =
|
|
7377
|
+
this._path = path41;
|
|
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 os9 = __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 = os9.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(path41, isFile, isDirectory) {
|
|
11533
|
+
log2(`checking %s`, path41);
|
|
11534
11534
|
try {
|
|
11535
|
-
const stat3 = fs_1.statSync(
|
|
11535
|
+
const stat3 = fs_1.statSync(path41);
|
|
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(path41, type = exports.READABLE) {
|
|
11556
|
+
return check2(path41, (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, path41) {
|
|
11854
|
+
if (!path41)
|
|
11855
11855
|
return obj;
|
|
11856
|
-
return
|
|
11856
|
+
return path41.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(path41, 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(path41);
|
|
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, path41 = []) => {
|
|
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 = [...path41, ...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(path41) {
|
|
12339
12339
|
const segs = [];
|
|
12340
|
-
for (const seg of
|
|
12340
|
+
for (const seg of path41) {
|
|
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.29".length > 0 ? "0.1.29" : "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 fs37 from "node:fs";
|
|
25075
|
+
import * as path40 from "node:path";
|
|
25076
25076
|
|
|
25077
25077
|
// src/cli-log-level.ts
|
|
25078
25078
|
var verbosity = "info";
|
|
@@ -26696,6 +26696,321 @@ function runPendingAuth(options) {
|
|
|
26696
26696
|
};
|
|
26697
26697
|
}
|
|
26698
26698
|
|
|
26699
|
+
// src/sqlite/cli-database.ts
|
|
26700
|
+
import sqliteWasm from "node-sqlite3-wasm";
|
|
26701
|
+
|
|
26702
|
+
// src/sqlite/cli-sqlite-paths.ts
|
|
26703
|
+
import fs8 from "node:fs";
|
|
26704
|
+
import path5 from "node:path";
|
|
26705
|
+
import os3 from "node:os";
|
|
26706
|
+
function getCliSqlitePath() {
|
|
26707
|
+
const override = process.env.BUILDAMATON_CLI_SQLITE_PATH?.trim();
|
|
26708
|
+
if (override) return path5.resolve(override);
|
|
26709
|
+
return path5.join(os3.homedir(), ".buildautomaton", "cli.sqlite");
|
|
26710
|
+
}
|
|
26711
|
+
function ensureCliSqliteParentDir(sqlitePath) {
|
|
26712
|
+
const dir = path5.dirname(sqlitePath);
|
|
26713
|
+
if (!fs8.existsSync(dir)) fs8.mkdirSync(dir, { recursive: true });
|
|
26714
|
+
}
|
|
26715
|
+
|
|
26716
|
+
// src/sqlite/legacy_migration/import-cli-legacy-disk-data.ts
|
|
26717
|
+
import fs13 from "node:fs";
|
|
26718
|
+
|
|
26719
|
+
// src/files/index/constants.ts
|
|
26720
|
+
import path6 from "node:path";
|
|
26721
|
+
import os4 from "node:os";
|
|
26722
|
+
var INDEX_WORK_YIELD_EVERY = 256;
|
|
26723
|
+
var INDEX_DIR = path6.join(os4.homedir(), ".buildautomaton");
|
|
26724
|
+
var INDEX_HASH_LEN = 16;
|
|
26725
|
+
|
|
26726
|
+
// src/prompt-turn-queue/paths.ts
|
|
26727
|
+
import path7 from "node:path";
|
|
26728
|
+
import os5 from "node:os";
|
|
26729
|
+
function getPromptQueuesDirectory() {
|
|
26730
|
+
const override = process.env.BUILDAMATON_PROMPT_QUEUES_DIR?.trim();
|
|
26731
|
+
if (override) return path7.resolve(override);
|
|
26732
|
+
return path7.join(os5.homedir(), ".buildautomaton", "queues");
|
|
26733
|
+
}
|
|
26734
|
+
|
|
26735
|
+
// src/sqlite/legacy_migration/archive-file-index-json.ts
|
|
26736
|
+
import fs10 from "node:fs";
|
|
26737
|
+
import path9 from "node:path";
|
|
26738
|
+
|
|
26739
|
+
// src/sqlite/legacy_migration/archive-to-old-version.ts
|
|
26740
|
+
import fs9 from "node:fs";
|
|
26741
|
+
import path8 from "node:path";
|
|
26742
|
+
var OLD_VERSION_DIR = path8.join(INDEX_DIR, "old-version");
|
|
26743
|
+
function moveLegacyFileToOldVersionBackup(category, sourcePath) {
|
|
26744
|
+
const destDir = path8.join(OLD_VERSION_DIR, category);
|
|
26745
|
+
fs9.mkdirSync(destDir, { recursive: true });
|
|
26746
|
+
const base = path8.basename(sourcePath);
|
|
26747
|
+
let dest = path8.join(destDir, base);
|
|
26748
|
+
if (fs9.existsSync(dest)) {
|
|
26749
|
+
const ext = path8.extname(base);
|
|
26750
|
+
const stem = ext ? base.slice(0, -ext.length) : base;
|
|
26751
|
+
dest = path8.join(destDir, `${stem}-${Date.now()}${ext}`);
|
|
26752
|
+
}
|
|
26753
|
+
fs9.renameSync(sourcePath, dest);
|
|
26754
|
+
}
|
|
26755
|
+
|
|
26756
|
+
// src/sqlite/legacy_migration/archive-file-index-json.ts
|
|
26757
|
+
function archiveLegacyFileIndexJsonFiles() {
|
|
26758
|
+
try {
|
|
26759
|
+
if (!fs10.existsSync(INDEX_DIR)) return;
|
|
26760
|
+
for (const name of fs10.readdirSync(INDEX_DIR)) {
|
|
26761
|
+
if (name.startsWith(".file-index-") && name.endsWith(".json")) {
|
|
26762
|
+
const full = path9.join(INDEX_DIR, name);
|
|
26763
|
+
try {
|
|
26764
|
+
moveLegacyFileToOldVersionBackup("file-index", full);
|
|
26765
|
+
} catch (err) {
|
|
26766
|
+
console.error(`[cli-sqlite] legacy import: could not archive ${name}`, err);
|
|
26767
|
+
}
|
|
26768
|
+
}
|
|
26769
|
+
}
|
|
26770
|
+
} catch (e) {
|
|
26771
|
+
console.error("[cli-sqlite] legacy import: archive file-index json failed", e);
|
|
26772
|
+
}
|
|
26773
|
+
}
|
|
26774
|
+
|
|
26775
|
+
// src/sqlite/legacy_migration/import-agent-sessions-from-disk.ts
|
|
26776
|
+
import fs11 from "node:fs";
|
|
26777
|
+
import path10 from "node:path";
|
|
26778
|
+
import os6 from "node:os";
|
|
26779
|
+
var LEGACY_AGENT_SESSION_DIR = path10.join(os6.homedir(), ".buildautomaton", "agent-sessions");
|
|
26780
|
+
function importLegacyAgentSessionsFromDisk(db) {
|
|
26781
|
+
try {
|
|
26782
|
+
if (!fs11.existsSync(LEGACY_AGENT_SESSION_DIR)) return;
|
|
26783
|
+
const names = fs11.readdirSync(LEGACY_AGENT_SESSION_DIR).filter((n) => n.endsWith(".json"));
|
|
26784
|
+
for (const name of names) {
|
|
26785
|
+
const sessionKey = name.slice(0, -".json".length);
|
|
26786
|
+
const full = path10.join(LEGACY_AGENT_SESSION_DIR, name);
|
|
26787
|
+
let raw;
|
|
26788
|
+
try {
|
|
26789
|
+
raw = fs11.readFileSync(full, "utf8");
|
|
26790
|
+
} catch {
|
|
26791
|
+
continue;
|
|
26792
|
+
}
|
|
26793
|
+
let parsed;
|
|
26794
|
+
try {
|
|
26795
|
+
parsed = JSON.parse(raw);
|
|
26796
|
+
} catch {
|
|
26797
|
+
continue;
|
|
26798
|
+
}
|
|
26799
|
+
if (parsed.v !== 1) continue;
|
|
26800
|
+
const acpSessionId = typeof parsed.acpSessionId === "string" ? parsed.acpSessionId : null;
|
|
26801
|
+
const backendAgentType = typeof parsed.backendAgentType === "string" ? parsed.backendAgentType : null;
|
|
26802
|
+
const configOptionsJson = Array.isArray(parsed.configOptions) ? JSON.stringify(parsed.configOptions) : null;
|
|
26803
|
+
const updatedAt = typeof parsed.updatedAt === "string" ? parsed.updatedAt : (/* @__PURE__ */ new Date()).toISOString();
|
|
26804
|
+
db.run(
|
|
26805
|
+
`INSERT OR REPLACE INTO agent_session (session_key, acp_session_id, backend_agent_type, config_options_json, updated_at)
|
|
26806
|
+
VALUES (?, ?, ?, ?, ?)`,
|
|
26807
|
+
[sessionKey, acpSessionId, backendAgentType, configOptionsJson, updatedAt]
|
|
26808
|
+
);
|
|
26809
|
+
try {
|
|
26810
|
+
moveLegacyFileToOldVersionBackup("agent-sessions", full);
|
|
26811
|
+
} catch {
|
|
26812
|
+
}
|
|
26813
|
+
}
|
|
26814
|
+
} catch (e) {
|
|
26815
|
+
console.error("[cli-sqlite] legacy import: agent_sessions from disk failed", e);
|
|
26816
|
+
}
|
|
26817
|
+
}
|
|
26818
|
+
|
|
26819
|
+
// src/sqlite/legacy_migration/import-prompt-queues-from-disk.ts
|
|
26820
|
+
import fs12 from "node:fs";
|
|
26821
|
+
import path11 from "node:path";
|
|
26822
|
+
|
|
26823
|
+
// src/sqlite/legacy_migration/parse-persisted-queue-json.ts
|
|
26824
|
+
function parsePersistedQueueFromJson(raw) {
|
|
26825
|
+
try {
|
|
26826
|
+
const o = JSON.parse(raw);
|
|
26827
|
+
const queueKey = typeof o.queueKey === "string" ? o.queueKey : typeof o.queueKeyHash === "string" ? o.queueKeyHash : null;
|
|
26828
|
+
if (!queueKey || typeof o.updatedAt !== "string" || !Array.isArray(o.turns)) return null;
|
|
26829
|
+
return { queueKey, updatedAt: o.updatedAt, turns: o.turns };
|
|
26830
|
+
} catch {
|
|
26831
|
+
return null;
|
|
26832
|
+
}
|
|
26833
|
+
}
|
|
26834
|
+
|
|
26835
|
+
// src/sqlite/legacy_migration/import-prompt-queues-from-disk.ts
|
|
26836
|
+
function importLegacyPromptQueuesFromDisk(db) {
|
|
26837
|
+
try {
|
|
26838
|
+
const dir = getPromptQueuesDirectory();
|
|
26839
|
+
if (!fs12.existsSync(dir)) return;
|
|
26840
|
+
for (const name of fs12.readdirSync(dir)) {
|
|
26841
|
+
if (!name.endsWith(".json")) continue;
|
|
26842
|
+
const full = path11.join(dir, name);
|
|
26843
|
+
let raw;
|
|
26844
|
+
try {
|
|
26845
|
+
raw = fs12.readFileSync(full, "utf8");
|
|
26846
|
+
} catch {
|
|
26847
|
+
continue;
|
|
26848
|
+
}
|
|
26849
|
+
const file2 = parsePersistedQueueFromJson(raw);
|
|
26850
|
+
if (!file2) continue;
|
|
26851
|
+
db.run(
|
|
26852
|
+
`INSERT OR REPLACE INTO prompt_queue (queue_key, updated_at, turns_json) VALUES (?, ?, ?)`,
|
|
26853
|
+
[file2.queueKey, file2.updatedAt, JSON.stringify(file2.turns)]
|
|
26854
|
+
);
|
|
26855
|
+
try {
|
|
26856
|
+
moveLegacyFileToOldVersionBackup("queues", full);
|
|
26857
|
+
} catch {
|
|
26858
|
+
}
|
|
26859
|
+
}
|
|
26860
|
+
} catch (e) {
|
|
26861
|
+
console.error("[cli-sqlite] legacy import: prompt queues from disk failed", e);
|
|
26862
|
+
}
|
|
26863
|
+
}
|
|
26864
|
+
|
|
26865
|
+
// src/sqlite/legacy_migration/import-cli-legacy-disk-data.ts
|
|
26866
|
+
function legacyCliDiskMigrationIsPending() {
|
|
26867
|
+
try {
|
|
26868
|
+
if (fs13.existsSync(INDEX_DIR)) {
|
|
26869
|
+
for (const name of fs13.readdirSync(INDEX_DIR)) {
|
|
26870
|
+
if (name.startsWith(".file-index-") && name.endsWith(".json")) return true;
|
|
26871
|
+
}
|
|
26872
|
+
}
|
|
26873
|
+
} catch {
|
|
26874
|
+
}
|
|
26875
|
+
try {
|
|
26876
|
+
if (fs13.existsSync(LEGACY_AGENT_SESSION_DIR)) {
|
|
26877
|
+
if (fs13.readdirSync(LEGACY_AGENT_SESSION_DIR).some((n) => n.endsWith(".json"))) return true;
|
|
26878
|
+
}
|
|
26879
|
+
} catch {
|
|
26880
|
+
}
|
|
26881
|
+
try {
|
|
26882
|
+
const dir = getPromptQueuesDirectory();
|
|
26883
|
+
if (fs13.existsSync(dir) && fs13.readdirSync(dir).some((n) => n.endsWith(".json"))) return true;
|
|
26884
|
+
} catch {
|
|
26885
|
+
}
|
|
26886
|
+
return false;
|
|
26887
|
+
}
|
|
26888
|
+
function importCliSqliteLegacyDiskData(db, log2) {
|
|
26889
|
+
const pending = legacyCliDiskMigrationIsPending();
|
|
26890
|
+
if (pending && log2) {
|
|
26891
|
+
log2("Migrating legacy on-disk CLI data to SQLite\u2026");
|
|
26892
|
+
}
|
|
26893
|
+
archiveLegacyFileIndexJsonFiles();
|
|
26894
|
+
importLegacyAgentSessionsFromDisk(db);
|
|
26895
|
+
importLegacyPromptQueuesFromDisk(db);
|
|
26896
|
+
if (pending && log2) {
|
|
26897
|
+
log2("Legacy on-disk CLI data migration finished.");
|
|
26898
|
+
}
|
|
26899
|
+
}
|
|
26900
|
+
|
|
26901
|
+
// src/sqlite/load-cli-migration-sql.ts
|
|
26902
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
26903
|
+
import { dirname, join as join2 } from "node:path";
|
|
26904
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
26905
|
+
function readCliSqliteMigrationSql(filename) {
|
|
26906
|
+
const dir = dirname(fileURLToPath2(import.meta.url));
|
|
26907
|
+
const resolved = join2(dir, "migrations", filename);
|
|
26908
|
+
if (!existsSync(resolved)) {
|
|
26909
|
+
throw new Error(`Missing CLI SQLite migration SQL: ${resolved}`);
|
|
26910
|
+
}
|
|
26911
|
+
return readFileSync(resolved, "utf8");
|
|
26912
|
+
}
|
|
26913
|
+
|
|
26914
|
+
// src/sqlite/migrate-cli-sqlite.ts
|
|
26915
|
+
function checkpointSatisfiedByLegacyChain(applied2, replacesLegacyMigrations) {
|
|
26916
|
+
return Array.isArray(replacesLegacyMigrations) && replacesLegacyMigrations.length > 0 && replacesLegacyMigrations.every((n) => applied2.has(n));
|
|
26917
|
+
}
|
|
26918
|
+
function recordMigrationAndPruneCheckpointLegacy(db, migration, applied2) {
|
|
26919
|
+
db.run("INSERT INTO __migrations (name) VALUES (?)", [migration.name]);
|
|
26920
|
+
applied2.add(migration.name);
|
|
26921
|
+
if (migration.checkpoint !== true) return;
|
|
26922
|
+
const legacy = migration.replacesLegacyMigrations;
|
|
26923
|
+
if (!legacy?.length) return;
|
|
26924
|
+
for (const legacyName of legacy) {
|
|
26925
|
+
if (legacyName === migration.name) continue;
|
|
26926
|
+
db.run("DELETE FROM __migrations WHERE name = ?", [legacyName]);
|
|
26927
|
+
applied2.delete(legacyName);
|
|
26928
|
+
}
|
|
26929
|
+
}
|
|
26930
|
+
var CHECKPOINT_V1 = "001_cli_sqlite_checkpoint_v1";
|
|
26931
|
+
var CHECKPOINT_V1_SQL = readCliSqliteMigrationSql("001_cli_sqlite_checkpoint_v1.sql");
|
|
26932
|
+
var CLI_SQLITE_MIGRATIONS = [
|
|
26933
|
+
{
|
|
26934
|
+
name: CHECKPOINT_V1,
|
|
26935
|
+
checkpoint: true,
|
|
26936
|
+
migrate: (db) => {
|
|
26937
|
+
db.exec(CHECKPOINT_V1_SQL);
|
|
26938
|
+
}
|
|
26939
|
+
}
|
|
26940
|
+
];
|
|
26941
|
+
function migrateCliSqlite(db) {
|
|
26942
|
+
db.exec(readCliSqliteMigrationSql("000_bootstrap_migrations_table.sql"));
|
|
26943
|
+
const appliedRows = db.all("SELECT name FROM __migrations");
|
|
26944
|
+
const applied2 = new Set(appliedRows.map((r) => r.name));
|
|
26945
|
+
for (const migration of CLI_SQLITE_MIGRATIONS) {
|
|
26946
|
+
if (applied2.has(migration.name)) continue;
|
|
26947
|
+
if (migration.checkpoint === true && checkpointSatisfiedByLegacyChain(applied2, migration.replacesLegacyMigrations)) {
|
|
26948
|
+
recordMigrationAndPruneCheckpointLegacy(db, migration, applied2);
|
|
26949
|
+
continue;
|
|
26950
|
+
}
|
|
26951
|
+
if (migration.alreadyApplied?.(db)) {
|
|
26952
|
+
recordMigrationAndPruneCheckpointLegacy(db, migration, applied2);
|
|
26953
|
+
continue;
|
|
26954
|
+
}
|
|
26955
|
+
try {
|
|
26956
|
+
migration.migrate(db);
|
|
26957
|
+
recordMigrationAndPruneCheckpointLegacy(db, migration, applied2);
|
|
26958
|
+
} catch (e) {
|
|
26959
|
+
console.error(`[cli-sqlite] Migration failed: ${migration.name}`, e);
|
|
26960
|
+
throw e;
|
|
26961
|
+
}
|
|
26962
|
+
}
|
|
26963
|
+
}
|
|
26964
|
+
|
|
26965
|
+
// src/sqlite/cli-database.ts
|
|
26966
|
+
var { Database: SqliteDatabase } = sqliteWasm;
|
|
26967
|
+
var openDatabases = /* @__PURE__ */ new Map();
|
|
26968
|
+
var processExitCloseRegistered = false;
|
|
26969
|
+
function registerProcessExitSqliteClose() {
|
|
26970
|
+
if (processExitCloseRegistered) return;
|
|
26971
|
+
processExitCloseRegistered = true;
|
|
26972
|
+
process.once("exit", () => {
|
|
26973
|
+
for (const db of openDatabases.values()) {
|
|
26974
|
+
safeCloseCliSqliteDatabase(db);
|
|
26975
|
+
}
|
|
26976
|
+
openDatabases.clear();
|
|
26977
|
+
});
|
|
26978
|
+
}
|
|
26979
|
+
function safeCloseCliSqliteDatabase(db) {
|
|
26980
|
+
if (db == null) return;
|
|
26981
|
+
try {
|
|
26982
|
+
if (db.isOpen) db.close();
|
|
26983
|
+
} catch {
|
|
26984
|
+
}
|
|
26985
|
+
}
|
|
26986
|
+
function closeAllCliSqliteConnections() {
|
|
26987
|
+
for (const db of openDatabases.values()) {
|
|
26988
|
+
safeCloseCliSqliteDatabase(db);
|
|
26989
|
+
}
|
|
26990
|
+
openDatabases.clear();
|
|
26991
|
+
}
|
|
26992
|
+
function getCliDatabase(options) {
|
|
26993
|
+
const sqlitePath = getCliSqlitePath();
|
|
26994
|
+
const existing = openDatabases.get(sqlitePath);
|
|
26995
|
+
if (existing?.isOpen) return existing;
|
|
26996
|
+
if (existing && !existing.isOpen) {
|
|
26997
|
+
safeCloseCliSqliteDatabase(existing);
|
|
26998
|
+
openDatabases.delete(sqlitePath);
|
|
26999
|
+
}
|
|
27000
|
+
ensureCliSqliteParentDir(sqlitePath);
|
|
27001
|
+
const db = new SqliteDatabase(sqlitePath);
|
|
27002
|
+
try {
|
|
27003
|
+
migrateCliSqlite(db);
|
|
27004
|
+
importCliSqliteLegacyDiskData(db, options?.logLegacyMigration);
|
|
27005
|
+
} catch (e) {
|
|
27006
|
+
safeCloseCliSqliteDatabase(db);
|
|
27007
|
+
throw e;
|
|
27008
|
+
}
|
|
27009
|
+
openDatabases.set(sqlitePath, db);
|
|
27010
|
+
registerProcessExitSqliteClose();
|
|
27011
|
+
return db;
|
|
27012
|
+
}
|
|
27013
|
+
|
|
26699
27014
|
// src/connection/close-bridge-connection.ts
|
|
26700
27015
|
async function closeBridgeConnection(state, acpManager, devServerManager, log2) {
|
|
26701
27016
|
const say = log2 ?? logImmediate;
|
|
@@ -26739,20 +27054,24 @@ async function closeBridgeConnection(state, acpManager, devServerManager, log2)
|
|
|
26739
27054
|
say("Stopping local dev server processes\u2026");
|
|
26740
27055
|
await devServerManager.shutdownAllGraceful();
|
|
26741
27056
|
}
|
|
27057
|
+
try {
|
|
27058
|
+
closeAllCliSqliteConnections();
|
|
27059
|
+
} catch {
|
|
27060
|
+
}
|
|
26742
27061
|
say("Shutdown complete.");
|
|
26743
27062
|
}
|
|
26744
27063
|
|
|
26745
27064
|
// src/paths/session-layout-paths.ts
|
|
26746
|
-
import * as
|
|
27065
|
+
import * as path12 from "node:path";
|
|
26747
27066
|
function resolveIsolatedSessionParentPathFromCheckouts(worktreePaths) {
|
|
26748
|
-
const resolved = worktreePaths.map((p) =>
|
|
27067
|
+
const resolved = worktreePaths.map((p) => path12.resolve(p)).filter(Boolean);
|
|
26749
27068
|
if (resolved.length === 0) return null;
|
|
26750
27069
|
resolved.sort();
|
|
26751
27070
|
return resolved[0];
|
|
26752
27071
|
}
|
|
26753
27072
|
function resolveSessionParentPathForAgentProcess(resolvedSessionParentPath) {
|
|
26754
27073
|
if (resolvedSessionParentPath != null && String(resolvedSessionParentPath).trim() !== "") {
|
|
26755
|
-
return
|
|
27074
|
+
return path12.resolve(String(resolvedSessionParentPath).trim());
|
|
26756
27075
|
}
|
|
26757
27076
|
return getBridgeRoot();
|
|
26758
27077
|
}
|
|
@@ -27084,9 +27403,9 @@ function parseChangeSummaryJson(raw, allowedPaths, options) {
|
|
|
27084
27403
|
const rawPath = typeof o.path === "string" ? o.path.trim() : "";
|
|
27085
27404
|
const summary = typeof o.summary === "string" ? o.summary.trim() : "";
|
|
27086
27405
|
if (!rawPath || !summary) continue;
|
|
27087
|
-
const
|
|
27088
|
-
if (!
|
|
27089
|
-
rows.push({ path:
|
|
27406
|
+
const path41 = skip ? normalizeRepoRelativePath(rawPath) || rawPath : resolveChangeSummaryPathAgainstAllowed(rawPath, allowedPaths);
|
|
27407
|
+
if (!path41) continue;
|
|
27408
|
+
rows.push({ path: path41, summary: clampSummaryToAtMostTwoLines(summary) });
|
|
27090
27409
|
}
|
|
27091
27410
|
return rows;
|
|
27092
27411
|
}
|
|
@@ -27312,17 +27631,17 @@ function getCliPermissionModeFromAgentConfig(config2) {
|
|
|
27312
27631
|
import { execFile as execFile7 } from "node:child_process";
|
|
27313
27632
|
import { readFile as readFile2, stat as stat2 } from "node:fs/promises";
|
|
27314
27633
|
import { promisify as promisify7 } from "node:util";
|
|
27315
|
-
import * as
|
|
27634
|
+
import * as path15 from "node:path";
|
|
27316
27635
|
|
|
27317
27636
|
// src/git/pre-turn-snapshot.ts
|
|
27318
|
-
import * as
|
|
27319
|
-
import * as
|
|
27637
|
+
import * as fs15 from "node:fs";
|
|
27638
|
+
import * as path14 from "node:path";
|
|
27320
27639
|
import { execFile as execFile6 } from "node:child_process";
|
|
27321
27640
|
import { promisify as promisify6 } from "node:util";
|
|
27322
27641
|
|
|
27323
27642
|
// src/git/discover-repos.ts
|
|
27324
|
-
import * as
|
|
27325
|
-
import * as
|
|
27643
|
+
import * as fs14 from "node:fs";
|
|
27644
|
+
import * as path13 from "node:path";
|
|
27326
27645
|
|
|
27327
27646
|
// ../../node_modules/.pnpm/simple-git@3.32.3/node_modules/simple-git/dist/esm/index.js
|
|
27328
27647
|
var import_file_exists = __toESM(require_dist(), 1);
|
|
@@ -27361,8 +27680,8 @@ function pathspec(...paths) {
|
|
|
27361
27680
|
cache.set(key, paths);
|
|
27362
27681
|
return key;
|
|
27363
27682
|
}
|
|
27364
|
-
function isPathSpec(
|
|
27365
|
-
return
|
|
27683
|
+
function isPathSpec(path41) {
|
|
27684
|
+
return path41 instanceof String && cache.has(path41);
|
|
27366
27685
|
}
|
|
27367
27686
|
function toPaths(pathSpec) {
|
|
27368
27687
|
return cache.get(pathSpec) || [];
|
|
@@ -27451,8 +27770,8 @@ function toLinesWithContent(input = "", trimmed2 = true, separator = "\n") {
|
|
|
27451
27770
|
function forEachLineWithContent(input, callback) {
|
|
27452
27771
|
return toLinesWithContent(input, true).map((line) => callback(line));
|
|
27453
27772
|
}
|
|
27454
|
-
function folderExists(
|
|
27455
|
-
return (0, import_file_exists.exists)(
|
|
27773
|
+
function folderExists(path41) {
|
|
27774
|
+
return (0, import_file_exists.exists)(path41, import_file_exists.FOLDER);
|
|
27456
27775
|
}
|
|
27457
27776
|
function append(target, item) {
|
|
27458
27777
|
if (Array.isArray(target)) {
|
|
@@ -27856,8 +28175,8 @@ function checkIsRepoRootTask() {
|
|
|
27856
28175
|
commands,
|
|
27857
28176
|
format: "utf-8",
|
|
27858
28177
|
onError,
|
|
27859
|
-
parser(
|
|
27860
|
-
return /^\.(git)?$/.test(
|
|
28178
|
+
parser(path41) {
|
|
28179
|
+
return /^\.(git)?$/.test(path41.trim());
|
|
27861
28180
|
}
|
|
27862
28181
|
};
|
|
27863
28182
|
}
|
|
@@ -28291,11 +28610,11 @@ function parseGrep(grep) {
|
|
|
28291
28610
|
const paths = /* @__PURE__ */ new Set();
|
|
28292
28611
|
const results = {};
|
|
28293
28612
|
forEachLineWithContent(grep, (input) => {
|
|
28294
|
-
const [
|
|
28295
|
-
paths.add(
|
|
28296
|
-
(results[
|
|
28613
|
+
const [path41, line, preview] = input.split(NULL);
|
|
28614
|
+
paths.add(path41);
|
|
28615
|
+
(results[path41] = results[path41] || []).push({
|
|
28297
28616
|
line: asNumber(line),
|
|
28298
|
-
path:
|
|
28617
|
+
path: path41,
|
|
28299
28618
|
preview
|
|
28300
28619
|
});
|
|
28301
28620
|
});
|
|
@@ -29060,14 +29379,14 @@ var init_hash_object = __esm2({
|
|
|
29060
29379
|
init_task();
|
|
29061
29380
|
}
|
|
29062
29381
|
});
|
|
29063
|
-
function parseInit(bare,
|
|
29382
|
+
function parseInit(bare, path41, text) {
|
|
29064
29383
|
const response = String(text).trim();
|
|
29065
29384
|
let result;
|
|
29066
29385
|
if (result = initResponseRegex.exec(response)) {
|
|
29067
|
-
return new InitSummary(bare,
|
|
29386
|
+
return new InitSummary(bare, path41, false, result[1]);
|
|
29068
29387
|
}
|
|
29069
29388
|
if (result = reInitResponseRegex.exec(response)) {
|
|
29070
|
-
return new InitSummary(bare,
|
|
29389
|
+
return new InitSummary(bare, path41, true, result[1]);
|
|
29071
29390
|
}
|
|
29072
29391
|
let gitDir = "";
|
|
29073
29392
|
const tokens = response.split(" ");
|
|
@@ -29078,7 +29397,7 @@ function parseInit(bare, path37, text) {
|
|
|
29078
29397
|
break;
|
|
29079
29398
|
}
|
|
29080
29399
|
}
|
|
29081
|
-
return new InitSummary(bare,
|
|
29400
|
+
return new InitSummary(bare, path41, /^re/i.test(response), gitDir);
|
|
29082
29401
|
}
|
|
29083
29402
|
var InitSummary;
|
|
29084
29403
|
var initResponseRegex;
|
|
@@ -29087,9 +29406,9 @@ var init_InitSummary = __esm2({
|
|
|
29087
29406
|
"src/lib/responses/InitSummary.ts"() {
|
|
29088
29407
|
"use strict";
|
|
29089
29408
|
InitSummary = class {
|
|
29090
|
-
constructor(bare,
|
|
29409
|
+
constructor(bare, path41, existing, gitDir) {
|
|
29091
29410
|
this.bare = bare;
|
|
29092
|
-
this.path =
|
|
29411
|
+
this.path = path41;
|
|
29093
29412
|
this.existing = existing;
|
|
29094
29413
|
this.gitDir = gitDir;
|
|
29095
29414
|
}
|
|
@@ -29101,7 +29420,7 @@ var init_InitSummary = __esm2({
|
|
|
29101
29420
|
function hasBareCommand(command) {
|
|
29102
29421
|
return command.includes(bareCommand);
|
|
29103
29422
|
}
|
|
29104
|
-
function initTask(bare = false,
|
|
29423
|
+
function initTask(bare = false, path41, customArgs) {
|
|
29105
29424
|
const commands = ["init", ...customArgs];
|
|
29106
29425
|
if (bare && !hasBareCommand(commands)) {
|
|
29107
29426
|
commands.splice(1, 0, bareCommand);
|
|
@@ -29110,7 +29429,7 @@ function initTask(bare = false, path37, customArgs) {
|
|
|
29110
29429
|
commands,
|
|
29111
29430
|
format: "utf-8",
|
|
29112
29431
|
parser(text) {
|
|
29113
|
-
return parseInit(commands.includes("--bare"),
|
|
29432
|
+
return parseInit(commands.includes("--bare"), path41, text);
|
|
29114
29433
|
}
|
|
29115
29434
|
};
|
|
29116
29435
|
}
|
|
@@ -29926,12 +30245,12 @@ var init_FileStatusSummary = __esm2({
|
|
|
29926
30245
|
"use strict";
|
|
29927
30246
|
fromPathRegex = /^(.+)\0(.+)$/;
|
|
29928
30247
|
FileStatusSummary = class {
|
|
29929
|
-
constructor(
|
|
29930
|
-
this.path =
|
|
30248
|
+
constructor(path41, index, working_dir) {
|
|
30249
|
+
this.path = path41;
|
|
29931
30250
|
this.index = index;
|
|
29932
30251
|
this.working_dir = working_dir;
|
|
29933
30252
|
if (index === "R" || working_dir === "R") {
|
|
29934
|
-
const detail = fromPathRegex.exec(
|
|
30253
|
+
const detail = fromPathRegex.exec(path41) || [null, path41, path41];
|
|
29935
30254
|
this.from = detail[2] || "";
|
|
29936
30255
|
this.path = detail[1] || "";
|
|
29937
30256
|
}
|
|
@@ -29962,14 +30281,14 @@ function splitLine(result, lineStr) {
|
|
|
29962
30281
|
default:
|
|
29963
30282
|
return;
|
|
29964
30283
|
}
|
|
29965
|
-
function data(index, workingDir,
|
|
30284
|
+
function data(index, workingDir, path41) {
|
|
29966
30285
|
const raw = `${index}${workingDir}`;
|
|
29967
30286
|
const handler = parsers6.get(raw);
|
|
29968
30287
|
if (handler) {
|
|
29969
|
-
handler(result,
|
|
30288
|
+
handler(result, path41);
|
|
29970
30289
|
}
|
|
29971
30290
|
if (raw !== "##" && raw !== "!!") {
|
|
29972
|
-
result.files.push(new FileStatusSummary(
|
|
30291
|
+
result.files.push(new FileStatusSummary(path41, index, workingDir));
|
|
29973
30292
|
}
|
|
29974
30293
|
}
|
|
29975
30294
|
}
|
|
@@ -30242,15 +30561,15 @@ var init_simple_git_api = __esm2({
|
|
|
30242
30561
|
this._executor = _executor;
|
|
30243
30562
|
}
|
|
30244
30563
|
_runTask(task, then) {
|
|
30245
|
-
const
|
|
30246
|
-
const promise2 =
|
|
30564
|
+
const chain2 = this._executor.chain();
|
|
30565
|
+
const promise2 = chain2.push(task);
|
|
30247
30566
|
if (then) {
|
|
30248
30567
|
taskCallback(task, promise2, then);
|
|
30249
30568
|
}
|
|
30250
30569
|
return Object.create(this, {
|
|
30251
30570
|
then: { value: promise2.then.bind(promise2) },
|
|
30252
30571
|
catch: { value: promise2.catch.bind(promise2) },
|
|
30253
|
-
_executor: { value:
|
|
30572
|
+
_executor: { value: chain2 }
|
|
30254
30573
|
});
|
|
30255
30574
|
}
|
|
30256
30575
|
add(files) {
|
|
@@ -30278,9 +30597,9 @@ var init_simple_git_api = __esm2({
|
|
|
30278
30597
|
next
|
|
30279
30598
|
);
|
|
30280
30599
|
}
|
|
30281
|
-
hashObject(
|
|
30600
|
+
hashObject(path41, write) {
|
|
30282
30601
|
return this._runTask(
|
|
30283
|
-
hashObjectTask(
|
|
30602
|
+
hashObjectTask(path41, write === true),
|
|
30284
30603
|
trailingFunctionArgument(arguments)
|
|
30285
30604
|
);
|
|
30286
30605
|
}
|
|
@@ -30633,8 +30952,8 @@ var init_branch = __esm2({
|
|
|
30633
30952
|
}
|
|
30634
30953
|
});
|
|
30635
30954
|
function toPath(input) {
|
|
30636
|
-
const
|
|
30637
|
-
return
|
|
30955
|
+
const path41 = input.trim().replace(/^["']|["']$/g, "");
|
|
30956
|
+
return path41 && normalize(path41);
|
|
30638
30957
|
}
|
|
30639
30958
|
var parseCheckIgnore;
|
|
30640
30959
|
var init_CheckIgnore = __esm2({
|
|
@@ -30948,8 +31267,8 @@ __export2(sub_module_exports, {
|
|
|
30948
31267
|
subModuleTask: () => subModuleTask,
|
|
30949
31268
|
updateSubModuleTask: () => updateSubModuleTask
|
|
30950
31269
|
});
|
|
30951
|
-
function addSubModuleTask(repo,
|
|
30952
|
-
return subModuleTask(["add", repo,
|
|
31270
|
+
function addSubModuleTask(repo, path41) {
|
|
31271
|
+
return subModuleTask(["add", repo, path41]);
|
|
30953
31272
|
}
|
|
30954
31273
|
function initSubModuleTask(customArgs) {
|
|
30955
31274
|
return subModuleTask(["init", ...customArgs]);
|
|
@@ -31282,8 +31601,8 @@ var require_git = __commonJS2({
|
|
|
31282
31601
|
}
|
|
31283
31602
|
return this._runTask(straightThroughStringTask2(command, this._trimmed), next);
|
|
31284
31603
|
};
|
|
31285
|
-
Git2.prototype.submoduleAdd = function(repo,
|
|
31286
|
-
return this._runTask(addSubModuleTask2(repo,
|
|
31604
|
+
Git2.prototype.submoduleAdd = function(repo, path41, then) {
|
|
31605
|
+
return this._runTask(addSubModuleTask2(repo, path41), trailingFunctionArgument2(arguments));
|
|
31287
31606
|
};
|
|
31288
31607
|
Git2.prototype.submoduleUpdate = function(args, then) {
|
|
31289
31608
|
return this._runTask(
|
|
@@ -31927,20 +32246,20 @@ async function isGitRepoDirectory(dirPath) {
|
|
|
31927
32246
|
// src/git/discover-repos.ts
|
|
31928
32247
|
async function discoverGitRepos(cwd = getBridgeRoot()) {
|
|
31929
32248
|
const result = [];
|
|
31930
|
-
const cwdResolved =
|
|
32249
|
+
const cwdResolved = path13.resolve(cwd);
|
|
31931
32250
|
if (await isGitRepoDirectory(cwdResolved)) {
|
|
31932
32251
|
const remoteUrl = await getRemoteOriginUrl(cwdResolved);
|
|
31933
32252
|
result.push({ absolutePath: cwdResolved, remoteUrl });
|
|
31934
32253
|
}
|
|
31935
32254
|
let entries;
|
|
31936
32255
|
try {
|
|
31937
|
-
entries =
|
|
32256
|
+
entries = fs14.readdirSync(cwdResolved, { withFileTypes: true });
|
|
31938
32257
|
} catch {
|
|
31939
32258
|
return result;
|
|
31940
32259
|
}
|
|
31941
32260
|
for (const ent of entries) {
|
|
31942
32261
|
if (!ent.isDirectory()) continue;
|
|
31943
|
-
const childPath =
|
|
32262
|
+
const childPath = path13.join(cwdResolved, ent.name);
|
|
31944
32263
|
if (await isGitRepoDirectory(childPath)) {
|
|
31945
32264
|
const remoteUrl = await getRemoteOriginUrl(childPath);
|
|
31946
32265
|
result.push({ absolutePath: childPath, remoteUrl });
|
|
@@ -31949,22 +32268,22 @@ async function discoverGitRepos(cwd = getBridgeRoot()) {
|
|
|
31949
32268
|
return result;
|
|
31950
32269
|
}
|
|
31951
32270
|
async function discoverGitReposUnderRoot(rootPath) {
|
|
31952
|
-
const root =
|
|
32271
|
+
const root = path13.resolve(rootPath);
|
|
31953
32272
|
const roots = [];
|
|
31954
32273
|
async function walk(dir) {
|
|
31955
32274
|
if (await isGitRepoDirectory(dir)) {
|
|
31956
|
-
roots.push(
|
|
32275
|
+
roots.push(path13.resolve(dir));
|
|
31957
32276
|
return;
|
|
31958
32277
|
}
|
|
31959
32278
|
let entries;
|
|
31960
32279
|
try {
|
|
31961
|
-
entries =
|
|
32280
|
+
entries = fs14.readdirSync(dir, { withFileTypes: true });
|
|
31962
32281
|
} catch {
|
|
31963
32282
|
return;
|
|
31964
32283
|
}
|
|
31965
32284
|
for (const ent of entries) {
|
|
31966
32285
|
if (!ent.isDirectory() || ent.name === ".git") continue;
|
|
31967
|
-
await walk(
|
|
32286
|
+
await walk(path13.join(dir, ent.name));
|
|
31968
32287
|
}
|
|
31969
32288
|
}
|
|
31970
32289
|
await walk(root);
|
|
@@ -31980,7 +32299,7 @@ async function discoverGitReposUnderRoot(rootPath) {
|
|
|
31980
32299
|
// src/git/pre-turn-snapshot.ts
|
|
31981
32300
|
var execFileAsync5 = promisify6(execFile6);
|
|
31982
32301
|
function snapshotsDirForCwd(agentCwd) {
|
|
31983
|
-
return
|
|
32302
|
+
return path14.join(agentCwd, ".buildautomaton", "snapshots");
|
|
31984
32303
|
}
|
|
31985
32304
|
async function gitStashCreate(repoRoot, log2) {
|
|
31986
32305
|
try {
|
|
@@ -32009,7 +32328,7 @@ async function gitRun(repoRoot, args, log2, label) {
|
|
|
32009
32328
|
async function resolveSnapshotRepoRoots(options) {
|
|
32010
32329
|
const { worktreePaths, fallbackCwd, sessionId, log: log2 } = options;
|
|
32011
32330
|
if (worktreePaths?.length) {
|
|
32012
|
-
const uniq = [...new Set(worktreePaths.map((p) =>
|
|
32331
|
+
const uniq = [...new Set(worktreePaths.map((p) => path14.resolve(p)))];
|
|
32013
32332
|
return uniq;
|
|
32014
32333
|
}
|
|
32015
32334
|
try {
|
|
@@ -32017,7 +32336,7 @@ async function resolveSnapshotRepoRoots(options) {
|
|
|
32017
32336
|
const mapped = repos.map((r) => r.absolutePath);
|
|
32018
32337
|
const sid = sessionId?.trim();
|
|
32019
32338
|
if (sid) {
|
|
32020
|
-
const filtered = mapped.filter((root) =>
|
|
32339
|
+
const filtered = mapped.filter((root) => path14.basename(root) === sid);
|
|
32021
32340
|
if (filtered.length > 0) return filtered;
|
|
32022
32341
|
}
|
|
32023
32342
|
return mapped;
|
|
@@ -32038,7 +32357,7 @@ async function capturePreTurnSnapshot(options) {
|
|
|
32038
32357
|
}
|
|
32039
32358
|
const dir = snapshotsDirForCwd(agentCwd);
|
|
32040
32359
|
try {
|
|
32041
|
-
|
|
32360
|
+
fs15.mkdirSync(dir, { recursive: true });
|
|
32042
32361
|
} catch (e) {
|
|
32043
32362
|
return { ok: false, error: e instanceof Error ? e.message : String(e) };
|
|
32044
32363
|
}
|
|
@@ -32047,9 +32366,9 @@ async function capturePreTurnSnapshot(options) {
|
|
|
32047
32366
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
32048
32367
|
repos
|
|
32049
32368
|
};
|
|
32050
|
-
const filePath =
|
|
32369
|
+
const filePath = path14.join(dir, `${runId}.json`);
|
|
32051
32370
|
try {
|
|
32052
|
-
|
|
32371
|
+
fs15.writeFileSync(filePath, JSON.stringify(payload, null, 2), "utf8");
|
|
32053
32372
|
} catch (e) {
|
|
32054
32373
|
return { ok: false, error: e instanceof Error ? e.message : String(e) };
|
|
32055
32374
|
}
|
|
@@ -32062,7 +32381,7 @@ async function capturePreTurnSnapshot(options) {
|
|
|
32062
32381
|
async function applyPreTurnSnapshot(filePath, log2) {
|
|
32063
32382
|
let data;
|
|
32064
32383
|
try {
|
|
32065
|
-
const raw =
|
|
32384
|
+
const raw = fs15.readFileSync(filePath, "utf8");
|
|
32066
32385
|
data = JSON.parse(raw);
|
|
32067
32386
|
} catch (e) {
|
|
32068
32387
|
return { ok: false, error: e instanceof Error ? e.message : String(e) };
|
|
@@ -32085,7 +32404,7 @@ async function applyPreTurnSnapshot(filePath, log2) {
|
|
|
32085
32404
|
return { ok: true };
|
|
32086
32405
|
}
|
|
32087
32406
|
function snapshotFilePath(agentCwd, runId) {
|
|
32088
|
-
return
|
|
32407
|
+
return path14.join(snapshotsDirForCwd(agentCwd), `${runId}.json`);
|
|
32089
32408
|
}
|
|
32090
32409
|
|
|
32091
32410
|
// src/git/session-git-queue.ts
|
|
@@ -32134,7 +32453,7 @@ async function collectTurnGitDiffFromPreTurnSnapshot(options) {
|
|
|
32134
32453
|
continue;
|
|
32135
32454
|
}
|
|
32136
32455
|
const lines = namesRaw.split("\n").map((l) => l.trim()).filter(Boolean);
|
|
32137
|
-
const slug =
|
|
32456
|
+
const slug = path15.basename(repo.path).replace(/[^\w.-]+/g, "_") || "repo";
|
|
32138
32457
|
for (const rel of lines) {
|
|
32139
32458
|
if (rel.includes("..")) continue;
|
|
32140
32459
|
try {
|
|
@@ -32148,7 +32467,7 @@ async function collectTurnGitDiffFromPreTurnSnapshot(options) {
|
|
|
32148
32467
|
);
|
|
32149
32468
|
if (!patchContent.trim()) continue;
|
|
32150
32469
|
const displayPath = multiRepo ? `${slug}/${rel}` : rel;
|
|
32151
|
-
const workspaceFilePath =
|
|
32470
|
+
const workspaceFilePath = path15.join(repo.path, rel);
|
|
32152
32471
|
const newText = await readWorkspaceFileAsUtf8(workspaceFilePath);
|
|
32153
32472
|
sendSessionUpdate({
|
|
32154
32473
|
type: "session_file_change",
|
|
@@ -32170,9 +32489,9 @@ async function collectTurnGitDiffFromPreTurnSnapshot(options) {
|
|
|
32170
32489
|
// src/agents/acp/put-summarize-change-summaries.ts
|
|
32171
32490
|
async function putEncryptedChangeSummaryRows(params) {
|
|
32172
32491
|
const base = params.apiBaseUrl.replace(/\/+$/, "");
|
|
32173
|
-
const entries = params.rows.map(({ path:
|
|
32492
|
+
const entries = params.rows.map(({ path: path41, summary }) => {
|
|
32174
32493
|
const enc = params.e2ee.encryptFields({ summary }, ["summary"]);
|
|
32175
|
-
return { path:
|
|
32494
|
+
return { path: path41, summary: JSON.stringify(enc) };
|
|
32176
32495
|
});
|
|
32177
32496
|
const res = await fetch(
|
|
32178
32497
|
`${base}/api/sessions/${encodeURIComponent(params.sessionId)}/follow-ups/summarize-changes`,
|
|
@@ -32483,8 +32802,8 @@ async function sendPromptToAgent(options) {
|
|
|
32483
32802
|
}
|
|
32484
32803
|
|
|
32485
32804
|
// src/agents/acp/ensure-acp-client.ts
|
|
32486
|
-
import * as
|
|
32487
|
-
import * as
|
|
32805
|
+
import * as fs16 from "node:fs";
|
|
32806
|
+
import * as path19 from "node:path";
|
|
32488
32807
|
|
|
32489
32808
|
// src/error-message.ts
|
|
32490
32809
|
function errorMessage(err) {
|
|
@@ -32648,8 +32967,8 @@ function enrichAcpPermissionRpcResultFromRequestParams(result, params) {
|
|
|
32648
32967
|
}
|
|
32649
32968
|
|
|
32650
32969
|
// src/agents/acp/clients/shared/acp-fs-read-write.ts
|
|
32651
|
-
import { mkdirSync as mkdirSync2, readFileSync as
|
|
32652
|
-
import { dirname as
|
|
32970
|
+
import { mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "node:fs";
|
|
32971
|
+
import { dirname as dirname3 } from "node:path";
|
|
32653
32972
|
|
|
32654
32973
|
// src/files/diff/unified-diff.ts
|
|
32655
32974
|
function computeLineDiff(oldText, newText) {
|
|
@@ -32698,21 +33017,21 @@ function editSnippetToUnifiedDiff(filePath, oldText, newText) {
|
|
|
32698
33017
|
}
|
|
32699
33018
|
|
|
32700
33019
|
// src/agents/acp/safe-fs-path.ts
|
|
32701
|
-
import * as
|
|
33020
|
+
import * as path16 from "node:path";
|
|
32702
33021
|
function resolveSafePathUnderCwd(cwd, filePath) {
|
|
32703
33022
|
const trimmed2 = filePath.trim();
|
|
32704
33023
|
if (!trimmed2) return null;
|
|
32705
|
-
const normalizedCwd =
|
|
32706
|
-
const resolved =
|
|
32707
|
-
const rel =
|
|
32708
|
-
if (rel.startsWith("..") ||
|
|
33024
|
+
const normalizedCwd = path16.resolve(cwd);
|
|
33025
|
+
const resolved = path16.isAbsolute(trimmed2) ? path16.normalize(trimmed2) : path16.resolve(normalizedCwd, trimmed2);
|
|
33026
|
+
const rel = path16.relative(normalizedCwd, resolved);
|
|
33027
|
+
if (rel.startsWith("..") || path16.isAbsolute(rel)) return null;
|
|
32709
33028
|
return resolved;
|
|
32710
33029
|
}
|
|
32711
33030
|
function toDisplayPathRelativeToCwd(cwd, absolutePath) {
|
|
32712
|
-
const normalizedCwd =
|
|
32713
|
-
const rel =
|
|
32714
|
-
if (!rel || rel === "") return
|
|
32715
|
-
return rel.split(
|
|
33031
|
+
const normalizedCwd = path16.resolve(cwd);
|
|
33032
|
+
const rel = path16.relative(normalizedCwd, path16.resolve(absolutePath));
|
|
33033
|
+
if (!rel || rel === "") return path16.basename(absolutePath);
|
|
33034
|
+
return rel.split(path16.sep).join("/");
|
|
32716
33035
|
}
|
|
32717
33036
|
|
|
32718
33037
|
// src/agents/acp/clients/shared/acp-fs-read-write.ts
|
|
@@ -32727,7 +33046,7 @@ function acpReadTextFileInProcess(ctx, filePath, line, limit) {
|
|
|
32727
33046
|
const resolvedPath = resolveSafePathUnderCwd(ctx.cwd, filePath);
|
|
32728
33047
|
if (!resolvedPath) throw new Error("Invalid or disallowed path");
|
|
32729
33048
|
try {
|
|
32730
|
-
let content =
|
|
33049
|
+
let content = readFileSync3(resolvedPath, "utf8");
|
|
32731
33050
|
content = sliceFileContentForAcp(content, line, limit);
|
|
32732
33051
|
return { content };
|
|
32733
33052
|
} catch (e) {
|
|
@@ -32740,11 +33059,11 @@ function acpWriteTextFileInProcess(ctx, filePath, newText) {
|
|
|
32740
33059
|
if (!resolvedPath) throw new Error("Invalid or disallowed path");
|
|
32741
33060
|
let oldText = "";
|
|
32742
33061
|
try {
|
|
32743
|
-
oldText =
|
|
33062
|
+
oldText = readFileSync3(resolvedPath, "utf8");
|
|
32744
33063
|
} catch (e) {
|
|
32745
33064
|
if (e.code !== "ENOENT") throw e;
|
|
32746
33065
|
}
|
|
32747
|
-
mkdirSync2(
|
|
33066
|
+
mkdirSync2(dirname3(resolvedPath), { recursive: true });
|
|
32748
33067
|
writeFileSync2(resolvedPath, newText, "utf8");
|
|
32749
33068
|
const displayPath = toDisplayPathRelativeToCwd(ctx.cwd, resolvedPath);
|
|
32750
33069
|
const patchContent = editSnippetToUnifiedDiff(displayPath, oldText, newText);
|
|
@@ -33681,20 +34000,20 @@ function resolveAgentCommand(preferredAgentType) {
|
|
|
33681
34000
|
|
|
33682
34001
|
// src/agents/acp/session-file-change-path-kind.ts
|
|
33683
34002
|
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
33684
|
-
import { existsSync, statSync } from "node:fs";
|
|
34003
|
+
import { existsSync as existsSync2, statSync } from "node:fs";
|
|
33685
34004
|
|
|
33686
34005
|
// src/git/get-git-repo-root-sync.ts
|
|
33687
34006
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
33688
|
-
import * as
|
|
34007
|
+
import * as path17 from "node:path";
|
|
33689
34008
|
function getGitRepoRootSync(startDir) {
|
|
33690
34009
|
try {
|
|
33691
34010
|
const out = execFileSync2("git", ["rev-parse", "--show-toplevel"], {
|
|
33692
|
-
cwd:
|
|
34011
|
+
cwd: path17.resolve(startDir),
|
|
33693
34012
|
encoding: "utf8",
|
|
33694
34013
|
stdio: ["ignore", "pipe", "ignore"],
|
|
33695
34014
|
maxBuffer: 1024 * 1024
|
|
33696
34015
|
}).trim();
|
|
33697
|
-
return out ?
|
|
34016
|
+
return out ? path17.resolve(out) : null;
|
|
33698
34017
|
} catch {
|
|
33699
34018
|
return null;
|
|
33700
34019
|
}
|
|
@@ -33702,26 +34021,26 @@ function getGitRepoRootSync(startDir) {
|
|
|
33702
34021
|
|
|
33703
34022
|
// src/agents/acp/workspace-files.ts
|
|
33704
34023
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
33705
|
-
import { readFileSync as
|
|
33706
|
-
import * as
|
|
34024
|
+
import { readFileSync as readFileSync4 } from "node:fs";
|
|
34025
|
+
import * as path18 from "node:path";
|
|
33707
34026
|
function resolveWorkspaceFilePath(sessionParentPath, rawPath) {
|
|
33708
34027
|
const trimmed2 = rawPath.trim();
|
|
33709
34028
|
if (!trimmed2) return null;
|
|
33710
|
-
const normalizedSessionParent =
|
|
34029
|
+
const normalizedSessionParent = path18.resolve(sessionParentPath);
|
|
33711
34030
|
let resolvedPath = resolveSafePathUnderCwd(sessionParentPath, trimmed2);
|
|
33712
34031
|
if (!resolvedPath) {
|
|
33713
|
-
const candidate =
|
|
34032
|
+
const candidate = path18.isAbsolute(trimmed2) ? path18.normalize(trimmed2) : path18.normalize(path18.resolve(normalizedSessionParent, trimmed2));
|
|
33714
34033
|
const gitRoot2 = getGitRepoRootSync(sessionParentPath);
|
|
33715
34034
|
if (!gitRoot2) return null;
|
|
33716
|
-
const rel =
|
|
33717
|
-
if (rel.startsWith("..") ||
|
|
34035
|
+
const rel = path18.relative(gitRoot2, candidate);
|
|
34036
|
+
if (rel.startsWith("..") || path18.isAbsolute(rel)) return null;
|
|
33718
34037
|
resolvedPath = candidate;
|
|
33719
34038
|
}
|
|
33720
34039
|
const gitRoot = getGitRepoRootSync(sessionParentPath);
|
|
33721
34040
|
if (gitRoot) {
|
|
33722
|
-
const relFromRoot =
|
|
33723
|
-
if (!relFromRoot.startsWith("..") && !
|
|
33724
|
-
return { resolvedPath, display: relFromRoot.split(
|
|
34041
|
+
const relFromRoot = path18.relative(gitRoot, resolvedPath);
|
|
34042
|
+
if (!relFromRoot.startsWith("..") && !path18.isAbsolute(relFromRoot)) {
|
|
34043
|
+
return { resolvedPath, display: relFromRoot.split(path18.sep).join("/") };
|
|
33725
34044
|
}
|
|
33726
34045
|
}
|
|
33727
34046
|
return { resolvedPath, display: toDisplayPathRelativeToCwd(sessionParentPath, resolvedPath) };
|
|
@@ -33730,11 +34049,11 @@ function readUtf8WorkspaceFile(sessionParentPath, displayPath) {
|
|
|
33730
34049
|
if (!displayPath || displayPath.includes("..")) return "";
|
|
33731
34050
|
const gitRoot = getGitRepoRootSync(sessionParentPath);
|
|
33732
34051
|
if (gitRoot) {
|
|
33733
|
-
const resolvedPath2 =
|
|
33734
|
-
const rel =
|
|
33735
|
-
if (!rel.startsWith("..") && !
|
|
34052
|
+
const resolvedPath2 = path18.resolve(gitRoot, displayPath);
|
|
34053
|
+
const rel = path18.relative(gitRoot, resolvedPath2);
|
|
34054
|
+
if (!rel.startsWith("..") && !path18.isAbsolute(rel)) {
|
|
33736
34055
|
try {
|
|
33737
|
-
return
|
|
34056
|
+
return readFileSync4(resolvedPath2, "utf8");
|
|
33738
34057
|
} catch {
|
|
33739
34058
|
}
|
|
33740
34059
|
}
|
|
@@ -33742,7 +34061,7 @@ function readUtf8WorkspaceFile(sessionParentPath, displayPath) {
|
|
|
33742
34061
|
const resolvedPath = resolveSafePathUnderCwd(sessionParentPath, displayPath);
|
|
33743
34062
|
if (!resolvedPath) return "";
|
|
33744
34063
|
try {
|
|
33745
|
-
return
|
|
34064
|
+
return readFileSync4(resolvedPath, "utf8");
|
|
33746
34065
|
} catch {
|
|
33747
34066
|
return "";
|
|
33748
34067
|
}
|
|
@@ -33751,9 +34070,9 @@ function tryWorkspaceDisplayToPath(sessionParentPath, displayPath) {
|
|
|
33751
34070
|
if (!displayPath || displayPath.includes("..")) return null;
|
|
33752
34071
|
const gitRoot = getGitRepoRootSync(sessionParentPath);
|
|
33753
34072
|
if (gitRoot) {
|
|
33754
|
-
const resolvedPath =
|
|
33755
|
-
const rel =
|
|
33756
|
-
if (!rel.startsWith("..") && !
|
|
34073
|
+
const resolvedPath = path18.resolve(gitRoot, displayPath);
|
|
34074
|
+
const rel = path18.relative(gitRoot, resolvedPath);
|
|
34075
|
+
if (!rel.startsWith("..") && !path18.isAbsolute(rel)) return resolvedPath;
|
|
33757
34076
|
}
|
|
33758
34077
|
return resolveSafePathUnderCwd(sessionParentPath, displayPath);
|
|
33759
34078
|
}
|
|
@@ -33788,7 +34107,7 @@ function gitHeadPathObjectType(sessionParentPath, displayPath) {
|
|
|
33788
34107
|
}
|
|
33789
34108
|
function getSessionFileChangeDirectoryFlags(sessionParentPath, displayPath) {
|
|
33790
34109
|
const resolvedPath = tryWorkspaceDisplayToPath(sessionParentPath, displayPath);
|
|
33791
|
-
if (resolvedPath &&
|
|
34110
|
+
if (resolvedPath && existsSync2(resolvedPath)) {
|
|
33792
34111
|
try {
|
|
33793
34112
|
if (statSync(resolvedPath).isDirectory()) {
|
|
33794
34113
|
return { isDirectory: true, directoryRemoved: false };
|
|
@@ -33888,7 +34207,7 @@ function createBridgeOnRequest(opts) {
|
|
|
33888
34207
|
}
|
|
33889
34208
|
|
|
33890
34209
|
// src/agents/acp/hooks/extract-acp-file-diffs-from-update/paths-and-text.ts
|
|
33891
|
-
import { fileURLToPath as
|
|
34210
|
+
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
33892
34211
|
function readOptionalTextField(v) {
|
|
33893
34212
|
if (v === null || v === void 0) return "";
|
|
33894
34213
|
if (typeof v === "string") return v;
|
|
@@ -33898,7 +34217,7 @@ function normalizePathField(raw) {
|
|
|
33898
34217
|
const t = raw.trim();
|
|
33899
34218
|
if (t.startsWith("file://")) {
|
|
33900
34219
|
try {
|
|
33901
|
-
return
|
|
34220
|
+
return fileURLToPath3(t);
|
|
33902
34221
|
} catch {
|
|
33903
34222
|
return t;
|
|
33904
34223
|
}
|
|
@@ -34356,29 +34675,34 @@ function buildAcpSessionBridgeHooks(opts) {
|
|
|
34356
34675
|
}
|
|
34357
34676
|
|
|
34358
34677
|
// src/agents/acp/local-agent-session-file.ts
|
|
34359
|
-
|
|
34360
|
-
import os3 from "node:os";
|
|
34361
|
-
import path12 from "node:path";
|
|
34362
|
-
var LOCAL_AGENT_SESSION_DIR = path12.join(os3.homedir(), ".buildautomaton", "agent-sessions");
|
|
34363
|
-
function safeFileSlug(cloudSessionId) {
|
|
34678
|
+
function sessionKeyForCloudSessionId(cloudSessionId) {
|
|
34364
34679
|
const t = cloudSessionId.replace(/[^a-zA-Z0-9_-]+/g, "_").slice(0, 220);
|
|
34365
34680
|
return t.length > 0 ? t : "session";
|
|
34366
34681
|
}
|
|
34367
|
-
function localAgentSessionFilePath(cloudSessionId) {
|
|
34368
|
-
return path12.join(LOCAL_AGENT_SESSION_DIR, `${safeFileSlug(cloudSessionId)}.json`);
|
|
34369
|
-
}
|
|
34370
34682
|
function readLocalAgentSessionFile(cloudSessionId) {
|
|
34371
34683
|
try {
|
|
34372
|
-
const
|
|
34373
|
-
const
|
|
34374
|
-
const
|
|
34375
|
-
|
|
34684
|
+
const db = getCliDatabase();
|
|
34685
|
+
const key = sessionKeyForCloudSessionId(cloudSessionId);
|
|
34686
|
+
const row = db.get(
|
|
34687
|
+
"SELECT acp_session_id, backend_agent_type, config_options_json, updated_at FROM agent_session WHERE session_key = ?",
|
|
34688
|
+
[key]
|
|
34689
|
+
);
|
|
34690
|
+
if (!row) return null;
|
|
34691
|
+
let configOptions = null;
|
|
34692
|
+
if (row.config_options_json != null && row.config_options_json !== "") {
|
|
34693
|
+
try {
|
|
34694
|
+
const parsed = JSON.parse(row.config_options_json);
|
|
34695
|
+
configOptions = Array.isArray(parsed) ? parsed : null;
|
|
34696
|
+
} catch {
|
|
34697
|
+
configOptions = null;
|
|
34698
|
+
}
|
|
34699
|
+
}
|
|
34376
34700
|
return {
|
|
34377
34701
|
v: 1,
|
|
34378
|
-
acpSessionId:
|
|
34379
|
-
backendAgentType:
|
|
34380
|
-
configOptions
|
|
34381
|
-
updatedAt:
|
|
34702
|
+
acpSessionId: row.acp_session_id,
|
|
34703
|
+
backendAgentType: row.backend_agent_type,
|
|
34704
|
+
configOptions,
|
|
34705
|
+
updatedAt: row.updated_at
|
|
34382
34706
|
};
|
|
34383
34707
|
} catch {
|
|
34384
34708
|
return null;
|
|
@@ -34386,9 +34710,8 @@ function readLocalAgentSessionFile(cloudSessionId) {
|
|
|
34386
34710
|
}
|
|
34387
34711
|
function writeLocalAgentSessionFile(cloudSessionId, patch) {
|
|
34388
34712
|
try {
|
|
34389
|
-
const
|
|
34390
|
-
|
|
34391
|
-
const p = localAgentSessionFilePath(cloudSessionId);
|
|
34713
|
+
const db = getCliDatabase();
|
|
34714
|
+
const key = sessionKeyForCloudSessionId(cloudSessionId);
|
|
34392
34715
|
const prev = readLocalAgentSessionFile(cloudSessionId);
|
|
34393
34716
|
const next = {
|
|
34394
34717
|
v: 1,
|
|
@@ -34397,7 +34720,17 @@ function writeLocalAgentSessionFile(cloudSessionId, patch) {
|
|
|
34397
34720
|
configOptions: patch.configOptions !== void 0 ? patch.configOptions : prev?.configOptions ?? null,
|
|
34398
34721
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
34399
34722
|
};
|
|
34400
|
-
|
|
34723
|
+
const configJson = next.configOptions != null ? JSON.stringify(next.configOptions) : null;
|
|
34724
|
+
db.run(
|
|
34725
|
+
`INSERT INTO agent_session (session_key, acp_session_id, backend_agent_type, config_options_json, updated_at)
|
|
34726
|
+
VALUES (?, ?, ?, ?, ?)
|
|
34727
|
+
ON CONFLICT(session_key) DO UPDATE SET
|
|
34728
|
+
acp_session_id = excluded.acp_session_id,
|
|
34729
|
+
backend_agent_type = excluded.backend_agent_type,
|
|
34730
|
+
config_options_json = excluded.config_options_json,
|
|
34731
|
+
updated_at = excluded.updated_at`,
|
|
34732
|
+
[key, next.acpSessionId, next.backendAgentType, configJson, next.updatedAt]
|
|
34733
|
+
);
|
|
34401
34734
|
} catch {
|
|
34402
34735
|
}
|
|
34403
34736
|
}
|
|
@@ -34421,7 +34754,7 @@ async function ensureAcpClient(options) {
|
|
|
34421
34754
|
if (state.acpStartPromise && !state.acpHandle) {
|
|
34422
34755
|
await state.acpStartPromise;
|
|
34423
34756
|
}
|
|
34424
|
-
if (state.acpHandle && state.lastAcpCwd != null &&
|
|
34757
|
+
if (state.acpHandle && state.lastAcpCwd != null && path19.resolve(state.lastAcpCwd) !== path19.resolve(targetSessionParentPath)) {
|
|
34425
34758
|
try {
|
|
34426
34759
|
state.acpHandle.disconnect();
|
|
34427
34760
|
} catch {
|
|
@@ -34456,7 +34789,7 @@ async function ensureAcpClient(options) {
|
|
|
34456
34789
|
if (!state.acpStartPromise) {
|
|
34457
34790
|
let statOk = false;
|
|
34458
34791
|
try {
|
|
34459
|
-
const st =
|
|
34792
|
+
const st = fs16.statSync(targetSessionParentPath);
|
|
34460
34793
|
statOk = st.isDirectory();
|
|
34461
34794
|
if (!statOk) {
|
|
34462
34795
|
state.lastAcpStartError = `Agent cwd is not a directory: ${targetSessionParentPath}`;
|
|
@@ -34703,12 +35036,12 @@ async function createAcpManager(options) {
|
|
|
34703
35036
|
}
|
|
34704
35037
|
|
|
34705
35038
|
// src/worktrees/session-worktree-manager.ts
|
|
34706
|
-
import * as
|
|
34707
|
-
import
|
|
35039
|
+
import * as path26 from "node:path";
|
|
35040
|
+
import os8 from "node:os";
|
|
34708
35041
|
|
|
34709
35042
|
// src/worktrees/prepare-new-session-worktrees.ts
|
|
34710
|
-
import * as
|
|
34711
|
-
import * as
|
|
35043
|
+
import * as fs18 from "node:fs";
|
|
35044
|
+
import * as path21 from "node:path";
|
|
34712
35045
|
|
|
34713
35046
|
// src/git/worktree-add.ts
|
|
34714
35047
|
async function gitWorktreeAddBranch(mainRepoPath, worktreePath, branch) {
|
|
@@ -34717,12 +35050,12 @@ async function gitWorktreeAddBranch(mainRepoPath, worktreePath, branch) {
|
|
|
34717
35050
|
}
|
|
34718
35051
|
|
|
34719
35052
|
// src/worktrees/worktree-layout-file.ts
|
|
34720
|
-
import * as
|
|
34721
|
-
import * as
|
|
34722
|
-
import
|
|
35053
|
+
import * as fs17 from "node:fs";
|
|
35054
|
+
import * as path20 from "node:path";
|
|
35055
|
+
import os7 from "node:os";
|
|
34723
35056
|
var LAYOUT_FILENAME = "worktree-launcher-layout.json";
|
|
34724
35057
|
function defaultWorktreeLayoutPath() {
|
|
34725
|
-
return
|
|
35058
|
+
return path20.join(os7.homedir(), ".buildautomaton", LAYOUT_FILENAME);
|
|
34726
35059
|
}
|
|
34727
35060
|
function normalizeLoadedLayout(raw) {
|
|
34728
35061
|
if (raw && typeof raw === "object" && "launcherCwds" in raw) {
|
|
@@ -34734,8 +35067,8 @@ function normalizeLoadedLayout(raw) {
|
|
|
34734
35067
|
function loadWorktreeLayout() {
|
|
34735
35068
|
try {
|
|
34736
35069
|
const p = defaultWorktreeLayoutPath();
|
|
34737
|
-
if (!
|
|
34738
|
-
const raw = JSON.parse(
|
|
35070
|
+
if (!fs17.existsSync(p)) return { launcherCwds: [] };
|
|
35071
|
+
const raw = JSON.parse(fs17.readFileSync(p, "utf8"));
|
|
34739
35072
|
return normalizeLoadedLayout(raw);
|
|
34740
35073
|
} catch {
|
|
34741
35074
|
return { launcherCwds: [] };
|
|
@@ -34743,24 +35076,24 @@ function loadWorktreeLayout() {
|
|
|
34743
35076
|
}
|
|
34744
35077
|
function saveWorktreeLayout(layout) {
|
|
34745
35078
|
try {
|
|
34746
|
-
const dir =
|
|
34747
|
-
|
|
34748
|
-
|
|
35079
|
+
const dir = path20.dirname(defaultWorktreeLayoutPath());
|
|
35080
|
+
fs17.mkdirSync(dir, { recursive: true });
|
|
35081
|
+
fs17.writeFileSync(defaultWorktreeLayoutPath(), JSON.stringify(layout, null, 2), "utf8");
|
|
34749
35082
|
} catch {
|
|
34750
35083
|
}
|
|
34751
35084
|
}
|
|
34752
35085
|
function baseNameSafe(pathString) {
|
|
34753
|
-
return
|
|
35086
|
+
return path20.basename(pathString).replace(/[^a-zA-Z0-9._-]+/g, "-") || "cwd";
|
|
34754
35087
|
}
|
|
34755
35088
|
function getLauncherDirNameIfPresent(layout, bridgeRootPath2) {
|
|
34756
|
-
const norm =
|
|
34757
|
-
const existing = layout.launcherCwds.find((e) =>
|
|
35089
|
+
const norm = path20.resolve(bridgeRootPath2);
|
|
35090
|
+
const existing = layout.launcherCwds.find((e) => path20.resolve(e.absolutePath) === norm);
|
|
34758
35091
|
return existing?.dirName;
|
|
34759
35092
|
}
|
|
34760
35093
|
function allocateDirNameForLauncherCwd(layout, bridgeRootPath2) {
|
|
34761
35094
|
const existing = getLauncherDirNameIfPresent(layout, bridgeRootPath2);
|
|
34762
35095
|
if (existing) return existing;
|
|
34763
|
-
const norm =
|
|
35096
|
+
const norm = path20.resolve(bridgeRootPath2);
|
|
34764
35097
|
const base = baseNameSafe(norm);
|
|
34765
35098
|
const used = new Set(layout.launcherCwds.map((e) => e.dirName));
|
|
34766
35099
|
let name = base;
|
|
@@ -34777,10 +35110,10 @@ function allocateDirNameForLauncherCwd(layout, bridgeRootPath2) {
|
|
|
34777
35110
|
// src/worktrees/prepare-new-session-worktrees.ts
|
|
34778
35111
|
async function prepareNewSessionWorktrees(options) {
|
|
34779
35112
|
const { worktreesRootPath, bridgeRoot, sessionId, layout, log: log2 } = options;
|
|
34780
|
-
const bridgeResolved =
|
|
35113
|
+
const bridgeResolved = path21.resolve(bridgeRoot);
|
|
34781
35114
|
const cwdKey = allocateDirNameForLauncherCwd(layout, bridgeResolved);
|
|
34782
|
-
const bridgeKeyDir =
|
|
34783
|
-
const sessionDir =
|
|
35115
|
+
const bridgeKeyDir = path21.join(worktreesRootPath, cwdKey);
|
|
35116
|
+
const sessionDir = path21.join(bridgeKeyDir, sessionId);
|
|
34784
35117
|
const repos = await discoverGitReposUnderRoot(bridgeResolved);
|
|
34785
35118
|
if (repos.length === 0) {
|
|
34786
35119
|
log2("[worktrees] No Git repositories under bridge root; skipping worktree creation.");
|
|
@@ -34788,14 +35121,14 @@ async function prepareNewSessionWorktrees(options) {
|
|
|
34788
35121
|
}
|
|
34789
35122
|
const branch = `session-${sessionId}`;
|
|
34790
35123
|
const worktreePaths = [];
|
|
34791
|
-
|
|
35124
|
+
fs18.mkdirSync(sessionDir, { recursive: true });
|
|
34792
35125
|
for (const repo of repos) {
|
|
34793
|
-
let rel =
|
|
34794
|
-
if (rel.startsWith("..") ||
|
|
35126
|
+
let rel = path21.relative(bridgeResolved, repo.absolutePath);
|
|
35127
|
+
if (rel.startsWith("..") || path21.isAbsolute(rel)) continue;
|
|
34795
35128
|
const relNorm = rel === "" ? "." : rel;
|
|
34796
|
-
const wtPath = relNorm === "." ? sessionDir :
|
|
35129
|
+
const wtPath = relNorm === "." ? sessionDir : path21.join(sessionDir, relNorm);
|
|
34797
35130
|
if (relNorm !== ".") {
|
|
34798
|
-
|
|
35131
|
+
fs18.mkdirSync(path21.dirname(wtPath), { recursive: true });
|
|
34799
35132
|
}
|
|
34800
35133
|
try {
|
|
34801
35134
|
await gitWorktreeAddBranch(repo.absolutePath, wtPath, branch);
|
|
@@ -34837,23 +35170,23 @@ async function renameSessionWorktreeBranches(paths, newBranch, log2) {
|
|
|
34837
35170
|
}
|
|
34838
35171
|
|
|
34839
35172
|
// src/worktrees/remove-session-worktrees.ts
|
|
34840
|
-
import * as
|
|
35173
|
+
import * as fs21 from "node:fs";
|
|
34841
35174
|
|
|
34842
35175
|
// src/git/worktree-remove.ts
|
|
34843
|
-
import * as
|
|
35176
|
+
import * as fs20 from "node:fs";
|
|
34844
35177
|
|
|
34845
35178
|
// src/git/resolve-main-repo-from-git-file.ts
|
|
34846
|
-
import * as
|
|
34847
|
-
import * as
|
|
35179
|
+
import * as fs19 from "node:fs";
|
|
35180
|
+
import * as path22 from "node:path";
|
|
34848
35181
|
function resolveMainRepoFromWorktreeGitFile(wt) {
|
|
34849
|
-
const gitDirFile =
|
|
34850
|
-
if (!
|
|
34851
|
-
const first2 =
|
|
35182
|
+
const gitDirFile = path22.join(wt, ".git");
|
|
35183
|
+
if (!fs19.existsSync(gitDirFile) || !fs19.statSync(gitDirFile).isFile()) return "";
|
|
35184
|
+
const first2 = fs19.readFileSync(gitDirFile, "utf8").trim();
|
|
34852
35185
|
const m = first2.match(/^gitdir:\s*(.+)$/im);
|
|
34853
35186
|
if (!m) return "";
|
|
34854
|
-
const gitWorktreePath =
|
|
34855
|
-
const gitDir =
|
|
34856
|
-
return
|
|
35187
|
+
const gitWorktreePath = path22.resolve(wt, m[1].trim());
|
|
35188
|
+
const gitDir = path22.dirname(path22.dirname(gitWorktreePath));
|
|
35189
|
+
return path22.dirname(gitDir);
|
|
34857
35190
|
}
|
|
34858
35191
|
|
|
34859
35192
|
// src/git/worktree-remove.ts
|
|
@@ -34862,7 +35195,7 @@ async function gitWorktreeRemoveForce(worktreePath) {
|
|
|
34862
35195
|
if (mainRepo) {
|
|
34863
35196
|
await cliSimpleGit(mainRepo).raw(["worktree", "remove", "--force", worktreePath]);
|
|
34864
35197
|
} else {
|
|
34865
|
-
|
|
35198
|
+
fs20.rmSync(worktreePath, { recursive: true, force: true });
|
|
34866
35199
|
}
|
|
34867
35200
|
}
|
|
34868
35201
|
|
|
@@ -34875,7 +35208,7 @@ async function removeSessionWorktrees(paths, log2) {
|
|
|
34875
35208
|
} catch (e) {
|
|
34876
35209
|
log2(`[worktrees] Remove failed for ${wt}: ${e instanceof Error ? e.message : String(e)}`);
|
|
34877
35210
|
try {
|
|
34878
|
-
|
|
35211
|
+
fs21.rmSync(wt, { recursive: true, force: true });
|
|
34879
35212
|
} catch {
|
|
34880
35213
|
}
|
|
34881
35214
|
}
|
|
@@ -35095,7 +35428,7 @@ function formatRemoteDisplayLabel(remoteUrl) {
|
|
|
35095
35428
|
}
|
|
35096
35429
|
|
|
35097
35430
|
// src/git/working-directory/changes/get-working-tree-change-repo-details.ts
|
|
35098
|
-
import * as
|
|
35431
|
+
import * as path24 from "node:path";
|
|
35099
35432
|
|
|
35100
35433
|
// src/git/working-directory/changes/parse-git-status.ts
|
|
35101
35434
|
function parseNameStatusLines(lines) {
|
|
@@ -35215,8 +35548,8 @@ async function listChangedFilesForCommit(repoGitCwd, repoRelPath, commitSha) {
|
|
|
35215
35548
|
}
|
|
35216
35549
|
|
|
35217
35550
|
// src/git/working-directory/changes/list-changed-files-for-repo.ts
|
|
35218
|
-
import * as
|
|
35219
|
-
import * as
|
|
35551
|
+
import * as fs23 from "node:fs";
|
|
35552
|
+
import * as path23 from "node:path";
|
|
35220
35553
|
|
|
35221
35554
|
// src/git/working-directory/changes/count-lines.ts
|
|
35222
35555
|
import { createReadStream } from "node:fs";
|
|
@@ -35240,7 +35573,7 @@ async function countTextFileLines(filePath) {
|
|
|
35240
35573
|
}
|
|
35241
35574
|
|
|
35242
35575
|
// src/git/working-directory/changes/hydrate-patch.ts
|
|
35243
|
-
import * as
|
|
35576
|
+
import * as fs22 from "node:fs";
|
|
35244
35577
|
var UNIFIED_HUNK_HEADER_RE = /^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/;
|
|
35245
35578
|
var MAX_HYDRATE_LINES_PER_GAP = 8e3;
|
|
35246
35579
|
var MAX_HYDRATE_LINES_PER_FILE = 8e4;
|
|
@@ -35255,7 +35588,7 @@ async function readGitBlobLines(repoCwd, pathInRepo) {
|
|
|
35255
35588
|
}
|
|
35256
35589
|
async function readWorktreeFileLines(filePath) {
|
|
35257
35590
|
try {
|
|
35258
|
-
const raw = await
|
|
35591
|
+
const raw = await fs22.promises.readFile(filePath, "utf8");
|
|
35259
35592
|
return raw.split(/\r?\n/);
|
|
35260
35593
|
} catch {
|
|
35261
35594
|
return null;
|
|
@@ -35390,7 +35723,7 @@ async function listChangedFilesForRepo(repoGitCwd, repoRelPath) {
|
|
|
35390
35723
|
const rows = [];
|
|
35391
35724
|
for (const pathInRepo of paths) {
|
|
35392
35725
|
const relLauncher = posixJoinDirFile(repoRelPath, pathInRepo.replace(/\\/g, "/"));
|
|
35393
|
-
const repoFilePath =
|
|
35726
|
+
const repoFilePath = path23.join(repoGitCwd, pathInRepo);
|
|
35394
35727
|
const nums = numByPath.get(pathInRepo);
|
|
35395
35728
|
let additions = nums?.additions ?? 0;
|
|
35396
35729
|
let deletions = nums?.deletions ?? 0;
|
|
@@ -35403,7 +35736,7 @@ async function listChangedFilesForRepo(repoGitCwd, repoRelPath) {
|
|
|
35403
35736
|
deletions = fromGit.deletions;
|
|
35404
35737
|
} else {
|
|
35405
35738
|
try {
|
|
35406
|
-
const st = await
|
|
35739
|
+
const st = await fs23.promises.stat(repoFilePath);
|
|
35407
35740
|
if (st.isFile()) additions = await countTextFileLines(repoFilePath);
|
|
35408
35741
|
else additions = 0;
|
|
35409
35742
|
} catch {
|
|
@@ -35429,7 +35762,7 @@ async function listChangedFilesForRepo(repoGitCwd, repoRelPath) {
|
|
|
35429
35762
|
} else {
|
|
35430
35763
|
pathInRepo = row.pathRelLauncher;
|
|
35431
35764
|
}
|
|
35432
|
-
const filePath =
|
|
35765
|
+
const filePath = path23.join(repoGitCwd, pathInRepo);
|
|
35433
35766
|
let patch = await unifiedDiffForFile(repoGitCwd, pathInRepo, row.change);
|
|
35434
35767
|
if (patch) {
|
|
35435
35768
|
patch = await hydrateUnifiedPatchWithFileContext(patch, filePath, repoGitCwd, pathInRepo, row.change);
|
|
@@ -35445,8 +35778,8 @@ function normRepoRel(p) {
|
|
|
35445
35778
|
return x === "" ? "." : x;
|
|
35446
35779
|
}
|
|
35447
35780
|
async function getWorkingTreeChangeRepoDetails(options) {
|
|
35448
|
-
const bridgeRoot =
|
|
35449
|
-
const sessionWtRoot = options.sessionWorktreeRootPath ?
|
|
35781
|
+
const bridgeRoot = path24.resolve(getBridgeRoot());
|
|
35782
|
+
const sessionWtRoot = options.sessionWorktreeRootPath ? path24.resolve(options.sessionWorktreeRootPath) : null;
|
|
35450
35783
|
const legacyNested = options.legacyRepoNestedSessionLayout === true;
|
|
35451
35784
|
const out = [];
|
|
35452
35785
|
const filter = options.repoFilterRelPath != null ? normRepoRel(options.repoFilterRelPath) : null;
|
|
@@ -35459,7 +35792,7 @@ async function getWorkingTreeChangeRepoDetails(options) {
|
|
|
35459
35792
|
}
|
|
35460
35793
|
const basis = filter == null && basisInput.kind === "commit" ? { kind: "working" } : basisInput;
|
|
35461
35794
|
for (const target of options.commitTargetPaths) {
|
|
35462
|
-
const t =
|
|
35795
|
+
const t = path24.resolve(target);
|
|
35463
35796
|
if (!await isGitRepoDirectory(t)) continue;
|
|
35464
35797
|
const g = cliSimpleGit(t);
|
|
35465
35798
|
let branch = "HEAD";
|
|
@@ -35472,8 +35805,8 @@ async function getWorkingTreeChangeRepoDetails(options) {
|
|
|
35472
35805
|
const remoteDisplay = formatRemoteDisplayLabel(remoteUrl);
|
|
35473
35806
|
let repoRelPath;
|
|
35474
35807
|
if (sessionWtRoot) {
|
|
35475
|
-
const anchor = legacyNested ?
|
|
35476
|
-
const relNorm =
|
|
35808
|
+
const anchor = legacyNested ? path24.dirname(t) : t;
|
|
35809
|
+
const relNorm = path24.relative(sessionWtRoot, anchor);
|
|
35477
35810
|
repoRelPath = relNorm === "" ? "." : relNorm.replace(/\\/g, "/");
|
|
35478
35811
|
} else {
|
|
35479
35812
|
let top = t;
|
|
@@ -35482,8 +35815,8 @@ async function getWorkingTreeChangeRepoDetails(options) {
|
|
|
35482
35815
|
} catch {
|
|
35483
35816
|
top = t;
|
|
35484
35817
|
}
|
|
35485
|
-
const rel =
|
|
35486
|
-
repoRelPath = rel.startsWith("..") ?
|
|
35818
|
+
const rel = path24.relative(bridgeRoot, path24.resolve(top)).replace(/\\/g, "/") || ".";
|
|
35819
|
+
repoRelPath = rel.startsWith("..") ? path24.basename(path24.resolve(top)) : rel;
|
|
35487
35820
|
}
|
|
35488
35821
|
const norm = normRepoRel(repoRelPath === "" ? "." : repoRelPath);
|
|
35489
35822
|
if (filter && norm !== filter) continue;
|
|
@@ -35548,11 +35881,11 @@ async function commitSessionWorktrees(options) {
|
|
|
35548
35881
|
}
|
|
35549
35882
|
|
|
35550
35883
|
// src/worktrees/discover-session-worktree-on-disk.ts
|
|
35551
|
-
import * as
|
|
35552
|
-
import * as
|
|
35884
|
+
import * as fs24 from "node:fs";
|
|
35885
|
+
import * as path25 from "node:path";
|
|
35553
35886
|
function isGitDir(dirPath) {
|
|
35554
35887
|
try {
|
|
35555
|
-
return
|
|
35888
|
+
return fs24.existsSync(path25.join(dirPath, ".git"));
|
|
35556
35889
|
} catch {
|
|
35557
35890
|
return false;
|
|
35558
35891
|
}
|
|
@@ -35561,23 +35894,23 @@ function collectGitRepoRootsUnderDirectory(rootPath) {
|
|
|
35561
35894
|
const out = [];
|
|
35562
35895
|
const walk = (dir) => {
|
|
35563
35896
|
if (isGitDir(dir)) {
|
|
35564
|
-
out.push(
|
|
35897
|
+
out.push(path25.resolve(dir));
|
|
35565
35898
|
return;
|
|
35566
35899
|
}
|
|
35567
35900
|
let entries;
|
|
35568
35901
|
try {
|
|
35569
|
-
entries =
|
|
35902
|
+
entries = fs24.readdirSync(dir, { withFileTypes: true });
|
|
35570
35903
|
} catch {
|
|
35571
35904
|
return;
|
|
35572
35905
|
}
|
|
35573
35906
|
for (const e of entries) {
|
|
35574
35907
|
if (e.name.startsWith(".")) continue;
|
|
35575
|
-
const full =
|
|
35908
|
+
const full = path25.join(dir, e.name);
|
|
35576
35909
|
if (!e.isDirectory()) continue;
|
|
35577
35910
|
walk(full);
|
|
35578
35911
|
}
|
|
35579
35912
|
};
|
|
35580
|
-
walk(
|
|
35913
|
+
walk(path25.resolve(rootPath));
|
|
35581
35914
|
return [...new Set(out)];
|
|
35582
35915
|
}
|
|
35583
35916
|
function collectWorktreeRootsNamed(root, sessionId, maxDepth) {
|
|
@@ -35586,16 +35919,16 @@ function collectWorktreeRootsNamed(root, sessionId, maxDepth) {
|
|
|
35586
35919
|
if (depth > maxDepth) return;
|
|
35587
35920
|
let entries;
|
|
35588
35921
|
try {
|
|
35589
|
-
entries =
|
|
35922
|
+
entries = fs24.readdirSync(dir, { withFileTypes: true });
|
|
35590
35923
|
} catch {
|
|
35591
35924
|
return;
|
|
35592
35925
|
}
|
|
35593
35926
|
for (const e of entries) {
|
|
35594
35927
|
if (e.name.startsWith(".")) continue;
|
|
35595
|
-
const full =
|
|
35928
|
+
const full = path25.join(dir, e.name);
|
|
35596
35929
|
if (!e.isDirectory()) continue;
|
|
35597
35930
|
if (e.name === sessionId) {
|
|
35598
|
-
if (isGitDir(full)) out.push(
|
|
35931
|
+
if (isGitDir(full)) out.push(path25.resolve(full));
|
|
35599
35932
|
} else {
|
|
35600
35933
|
walk(full, depth + 1);
|
|
35601
35934
|
}
|
|
@@ -35607,14 +35940,14 @@ function collectWorktreeRootsNamed(root, sessionId, maxDepth) {
|
|
|
35607
35940
|
function tryBindingFromSessionDirectory(sessionDir) {
|
|
35608
35941
|
let st;
|
|
35609
35942
|
try {
|
|
35610
|
-
st =
|
|
35943
|
+
st = fs24.statSync(sessionDir);
|
|
35611
35944
|
} catch {
|
|
35612
35945
|
return null;
|
|
35613
35946
|
}
|
|
35614
35947
|
if (!st.isDirectory()) return null;
|
|
35615
35948
|
const worktreePaths = collectGitRepoRootsUnderDirectory(sessionDir);
|
|
35616
35949
|
if (worktreePaths.length === 0) return null;
|
|
35617
|
-
const abs =
|
|
35950
|
+
const abs = path25.resolve(sessionDir);
|
|
35618
35951
|
return {
|
|
35619
35952
|
sessionParentPath: abs,
|
|
35620
35953
|
workingTreeRelRoot: abs,
|
|
@@ -35624,20 +35957,20 @@ function tryBindingFromSessionDirectory(sessionDir) {
|
|
|
35624
35957
|
function discoverLegacyBindingAscendingFromCheckout(sessionId, checkoutPath) {
|
|
35625
35958
|
const sid = sessionId.trim();
|
|
35626
35959
|
if (!sid) return null;
|
|
35627
|
-
const hintR =
|
|
35960
|
+
const hintR = path25.resolve(checkoutPath);
|
|
35628
35961
|
let best = null;
|
|
35629
|
-
let cur =
|
|
35962
|
+
let cur = path25.dirname(hintR);
|
|
35630
35963
|
for (let i = 0; i < 40; i++) {
|
|
35631
35964
|
const paths = collectWorktreeRootsNamed(cur, sid, 24);
|
|
35632
|
-
if (paths.some((p) =>
|
|
35633
|
-
const isolated = resolveIsolatedSessionParentPathFromCheckouts(paths) ??
|
|
35965
|
+
if (paths.some((p) => path25.resolve(p) === hintR)) {
|
|
35966
|
+
const isolated = resolveIsolatedSessionParentPathFromCheckouts(paths) ?? path25.resolve(paths[0]);
|
|
35634
35967
|
best = {
|
|
35635
|
-
sessionParentPath:
|
|
35636
|
-
workingTreeRelRoot:
|
|
35637
|
-
repoCheckoutPaths: paths.map((p) =>
|
|
35968
|
+
sessionParentPath: path25.resolve(isolated),
|
|
35969
|
+
workingTreeRelRoot: path25.resolve(cur),
|
|
35970
|
+
repoCheckoutPaths: paths.map((p) => path25.resolve(p))
|
|
35638
35971
|
};
|
|
35639
35972
|
}
|
|
35640
|
-
const next =
|
|
35973
|
+
const next = path25.dirname(cur);
|
|
35641
35974
|
if (next === cur) break;
|
|
35642
35975
|
cur = next;
|
|
35643
35976
|
}
|
|
@@ -35645,33 +35978,33 @@ function discoverLegacyBindingAscendingFromCheckout(sessionId, checkoutPath) {
|
|
|
35645
35978
|
}
|
|
35646
35979
|
function discoverSessionWorktreeOnDisk(options) {
|
|
35647
35980
|
const { sessionId, worktreesRootPath, layout, bridgeRoot } = options;
|
|
35648
|
-
if (!sessionId.trim() || !
|
|
35981
|
+
if (!sessionId.trim() || !fs24.existsSync(worktreesRootPath)) return null;
|
|
35649
35982
|
const preferredKey = getLauncherDirNameIfPresent(layout, bridgeRoot);
|
|
35650
35983
|
const keys = [];
|
|
35651
35984
|
if (preferredKey) keys.push(preferredKey);
|
|
35652
35985
|
try {
|
|
35653
|
-
for (const name of
|
|
35986
|
+
for (const name of fs24.readdirSync(worktreesRootPath)) {
|
|
35654
35987
|
if (name.startsWith(".")) continue;
|
|
35655
|
-
const p =
|
|
35656
|
-
if (!
|
|
35988
|
+
const p = path25.join(worktreesRootPath, name);
|
|
35989
|
+
if (!fs24.statSync(p).isDirectory()) continue;
|
|
35657
35990
|
if (name !== preferredKey) keys.push(name);
|
|
35658
35991
|
}
|
|
35659
35992
|
} catch {
|
|
35660
35993
|
return null;
|
|
35661
35994
|
}
|
|
35662
35995
|
for (const key of keys) {
|
|
35663
|
-
const layoutRoot =
|
|
35664
|
-
if (!
|
|
35665
|
-
const sessionDir =
|
|
35996
|
+
const layoutRoot = path25.join(worktreesRootPath, key);
|
|
35997
|
+
if (!fs24.existsSync(layoutRoot) || !fs24.statSync(layoutRoot).isDirectory()) continue;
|
|
35998
|
+
const sessionDir = path25.join(layoutRoot, sessionId);
|
|
35666
35999
|
const nested = tryBindingFromSessionDirectory(sessionDir);
|
|
35667
36000
|
if (nested) return nested;
|
|
35668
36001
|
const legacyPaths = collectWorktreeRootsNamed(layoutRoot, sessionId, 24);
|
|
35669
36002
|
if (legacyPaths.length > 0) {
|
|
35670
|
-
const isolated = resolveIsolatedSessionParentPathFromCheckouts(legacyPaths) ??
|
|
36003
|
+
const isolated = resolveIsolatedSessionParentPathFromCheckouts(legacyPaths) ?? path25.resolve(legacyPaths[0]);
|
|
35671
36004
|
return {
|
|
35672
|
-
sessionParentPath:
|
|
35673
|
-
workingTreeRelRoot:
|
|
35674
|
-
repoCheckoutPaths: legacyPaths.map((p) =>
|
|
36005
|
+
sessionParentPath: path25.resolve(isolated),
|
|
36006
|
+
workingTreeRelRoot: path25.resolve(layoutRoot),
|
|
36007
|
+
repoCheckoutPaths: legacyPaths.map((p) => path25.resolve(p))
|
|
35675
36008
|
};
|
|
35676
36009
|
}
|
|
35677
36010
|
}
|
|
@@ -35680,12 +36013,12 @@ function discoverSessionWorktreeOnDisk(options) {
|
|
|
35680
36013
|
function discoverSessionWorktreesUnderSessionWorktreeRoot(sessionWorktreeRootPathOrHint, sessionId) {
|
|
35681
36014
|
const sid = sessionId.trim();
|
|
35682
36015
|
if (!sid) return null;
|
|
35683
|
-
const hint =
|
|
35684
|
-
const underHint = tryBindingFromSessionDirectory(
|
|
36016
|
+
const hint = path25.resolve(sessionWorktreeRootPathOrHint);
|
|
36017
|
+
const underHint = tryBindingFromSessionDirectory(path25.join(hint, sid));
|
|
35685
36018
|
if (underHint) return underHint;
|
|
35686
36019
|
const direct = tryBindingFromSessionDirectory(hint);
|
|
35687
36020
|
if (direct) {
|
|
35688
|
-
if (
|
|
36021
|
+
if (path25.basename(hint) === sid && isGitDir(hint)) {
|
|
35689
36022
|
const legacyFromCheckout = discoverLegacyBindingAscendingFromCheckout(sid, hint);
|
|
35690
36023
|
if (legacyFromCheckout && legacyFromCheckout.repoCheckoutPaths.length > direct.repoCheckoutPaths.length) {
|
|
35691
36024
|
return legacyFromCheckout;
|
|
@@ -35693,24 +36026,24 @@ function discoverSessionWorktreesUnderSessionWorktreeRoot(sessionWorktreeRootPat
|
|
|
35693
36026
|
}
|
|
35694
36027
|
return direct;
|
|
35695
36028
|
}
|
|
35696
|
-
if (
|
|
36029
|
+
if (path25.basename(hint) === sid && isGitDir(hint)) {
|
|
35697
36030
|
const legacyFromCheckout = discoverLegacyBindingAscendingFromCheckout(sid, hint);
|
|
35698
36031
|
if (legacyFromCheckout) return legacyFromCheckout;
|
|
35699
36032
|
}
|
|
35700
36033
|
let st;
|
|
35701
36034
|
try {
|
|
35702
|
-
st =
|
|
36035
|
+
st = fs24.statSync(hint);
|
|
35703
36036
|
} catch {
|
|
35704
36037
|
return null;
|
|
35705
36038
|
}
|
|
35706
36039
|
if (!st.isDirectory()) return null;
|
|
35707
36040
|
const legacyPaths = collectWorktreeRootsNamed(hint, sid, 24);
|
|
35708
36041
|
if (legacyPaths.length === 0) return null;
|
|
35709
|
-
const isolated = resolveIsolatedSessionParentPathFromCheckouts(legacyPaths) ??
|
|
36042
|
+
const isolated = resolveIsolatedSessionParentPathFromCheckouts(legacyPaths) ?? path25.resolve(legacyPaths[0]);
|
|
35710
36043
|
return {
|
|
35711
|
-
sessionParentPath:
|
|
36044
|
+
sessionParentPath: path25.resolve(isolated),
|
|
35712
36045
|
workingTreeRelRoot: hint,
|
|
35713
|
-
repoCheckoutPaths: legacyPaths.map((p) =>
|
|
36046
|
+
repoCheckoutPaths: legacyPaths.map((p) => path25.resolve(p))
|
|
35714
36047
|
};
|
|
35715
36048
|
}
|
|
35716
36049
|
|
|
@@ -35733,10 +36066,10 @@ var SessionWorktreeManager = class {
|
|
|
35733
36066
|
this.layout = loadWorktreeLayout();
|
|
35734
36067
|
}
|
|
35735
36068
|
rememberSessionWorktrees(sessionId, binding) {
|
|
35736
|
-
const paths = binding.repoCheckoutPaths.map((p) =>
|
|
36069
|
+
const paths = binding.repoCheckoutPaths.map((p) => path26.resolve(p));
|
|
35737
36070
|
this.sessionRepoCheckoutPaths.set(sessionId, paths);
|
|
35738
|
-
this.sessionParentPathBySession.set(sessionId,
|
|
35739
|
-
this.sessionWorkingTreeRelRootBySession.set(sessionId,
|
|
36071
|
+
this.sessionParentPathBySession.set(sessionId, path26.resolve(binding.sessionParentPath));
|
|
36072
|
+
this.sessionWorkingTreeRelRootBySession.set(sessionId, path26.resolve(binding.workingTreeRelRoot));
|
|
35740
36073
|
}
|
|
35741
36074
|
sessionParentPathAfterRemember(sessionId) {
|
|
35742
36075
|
return this.sessionParentPathBySession.get(sessionId);
|
|
@@ -35753,7 +36086,7 @@ var SessionWorktreeManager = class {
|
|
|
35753
36086
|
const parent = this.sessionParentPathBySession.get(sessionId);
|
|
35754
36087
|
const relRoot = this.sessionWorkingTreeRelRootBySession.get(sessionId);
|
|
35755
36088
|
if (!parent || !relRoot) return false;
|
|
35756
|
-
return
|
|
36089
|
+
return path26.resolve(parent) !== path26.resolve(relRoot);
|
|
35757
36090
|
}
|
|
35758
36091
|
/**
|
|
35759
36092
|
* Session parent path for `worktrees_root`: the per-session directory (new layout) or primary checkout (legacy).
|
|
@@ -35762,7 +36095,7 @@ var SessionWorktreeManager = class {
|
|
|
35762
36095
|
if (!sessionId) return null;
|
|
35763
36096
|
const sid = sessionId.trim();
|
|
35764
36097
|
const cached2 = this.sessionParentPathBySession.get(sid);
|
|
35765
|
-
if (cached2) return
|
|
36098
|
+
if (cached2) return path26.resolve(cached2);
|
|
35766
36099
|
const paths = this.ensureRepoCheckoutPathsForSession(sid) ?? this.getRepoCheckoutPathsForSession(sid);
|
|
35767
36100
|
if (!paths?.length) return null;
|
|
35768
36101
|
return resolveIsolatedSessionParentPathFromCheckouts(paths);
|
|
@@ -35776,7 +36109,7 @@ var SessionWorktreeManager = class {
|
|
|
35776
36109
|
const sid = sessionId.trim();
|
|
35777
36110
|
const parentPathRaw = opts.sessionParentPath?.trim();
|
|
35778
36111
|
if (parentPathRaw) {
|
|
35779
|
-
const resolved =
|
|
36112
|
+
const resolved = path26.resolve(parentPathRaw);
|
|
35780
36113
|
if (sid && parseSessionParent(opts.sessionParent) === "worktrees_root") {
|
|
35781
36114
|
const diskFirst = this.tryDiscoverFromDisk(sid);
|
|
35782
36115
|
if (diskFirst) {
|
|
@@ -35795,7 +36128,7 @@ var SessionWorktreeManager = class {
|
|
|
35795
36128
|
this.rememberSessionWorktrees(sid, tryRoot);
|
|
35796
36129
|
return this.sessionParentPathAfterRemember(sid);
|
|
35797
36130
|
}
|
|
35798
|
-
const next =
|
|
36131
|
+
const next = path26.dirname(cur);
|
|
35799
36132
|
if (next === cur) break;
|
|
35800
36133
|
cur = next;
|
|
35801
36134
|
}
|
|
@@ -35948,15 +36281,22 @@ var SessionWorktreeManager = class {
|
|
|
35948
36281
|
}
|
|
35949
36282
|
};
|
|
35950
36283
|
function defaultWorktreesRootPath() {
|
|
35951
|
-
return
|
|
36284
|
+
return path26.join(os8.homedir(), ".buildautomaton", "worktrees");
|
|
35952
36285
|
}
|
|
35953
36286
|
|
|
35954
36287
|
// src/files/watch-file-index.ts
|
|
35955
36288
|
import { watch } from "node:fs";
|
|
36289
|
+
import path31 from "node:path";
|
|
36290
|
+
|
|
36291
|
+
// src/files/index/paths.ts
|
|
35956
36292
|
import path27 from "node:path";
|
|
36293
|
+
import crypto2 from "node:crypto";
|
|
36294
|
+
function getCwdHashForFileIndex(resolvedCwd) {
|
|
36295
|
+
return crypto2.createHash("sha256").update(path27.resolve(resolvedCwd)).digest("hex").slice(0, INDEX_HASH_LEN);
|
|
36296
|
+
}
|
|
35957
36297
|
|
|
35958
36298
|
// src/files/index/build-file-index.ts
|
|
35959
|
-
import
|
|
36299
|
+
import path29 from "node:path";
|
|
35960
36300
|
|
|
35961
36301
|
// src/runtime/yield-to-event-loop.ts
|
|
35962
36302
|
function yieldToEventLoop() {
|
|
@@ -35964,47 +36304,12 @@ function yieldToEventLoop() {
|
|
|
35964
36304
|
}
|
|
35965
36305
|
|
|
35966
36306
|
// src/files/index/walk-workspace-tree.ts
|
|
35967
|
-
import
|
|
35968
|
-
import
|
|
35969
|
-
|
|
35970
|
-
// src/files/index/constants.ts
|
|
35971
|
-
import path21 from "node:path";
|
|
35972
|
-
import os6 from "node:os";
|
|
35973
|
-
var INDEX_WORK_YIELD_EVERY = 256;
|
|
35974
|
-
var INDEX_DIR = path21.join(os6.homedir(), ".buildautomaton");
|
|
35975
|
-
var INDEX_HASH_LEN = 16;
|
|
35976
|
-
var INDEX_VERSION = 2;
|
|
35977
|
-
var INDEX_LOG_PREFIX = "[file-index]";
|
|
35978
|
-
|
|
35979
|
-
// src/files/index/walk-workspace-tree.ts
|
|
35980
|
-
function walkWorkspaceTreeSync(dir, baseDir, out) {
|
|
35981
|
-
let names;
|
|
35982
|
-
try {
|
|
35983
|
-
names = fs20.readdirSync(dir);
|
|
35984
|
-
} catch {
|
|
35985
|
-
return;
|
|
35986
|
-
}
|
|
35987
|
-
for (const name of names) {
|
|
35988
|
-
if (name.startsWith(".")) continue;
|
|
35989
|
-
const full = path22.join(dir, name);
|
|
35990
|
-
let stat3;
|
|
35991
|
-
try {
|
|
35992
|
-
stat3 = fs20.statSync(full);
|
|
35993
|
-
} catch {
|
|
35994
|
-
continue;
|
|
35995
|
-
}
|
|
35996
|
-
const relative5 = path22.relative(baseDir, full).replace(/\\/g, "/");
|
|
35997
|
-
if (stat3.isDirectory()) {
|
|
35998
|
-
walkWorkspaceTreeSync(full, baseDir, out);
|
|
35999
|
-
} else if (stat3.isFile()) {
|
|
36000
|
-
out.push(relative5);
|
|
36001
|
-
}
|
|
36002
|
-
}
|
|
36003
|
-
}
|
|
36307
|
+
import fs25 from "node:fs";
|
|
36308
|
+
import path28 from "node:path";
|
|
36004
36309
|
async function walkWorkspaceTreeAsync(dir, baseDir, out, state) {
|
|
36005
36310
|
let names;
|
|
36006
36311
|
try {
|
|
36007
|
-
names = await
|
|
36312
|
+
names = await fs25.promises.readdir(dir);
|
|
36008
36313
|
} catch {
|
|
36009
36314
|
return;
|
|
36010
36315
|
}
|
|
@@ -36014,14 +36319,14 @@ async function walkWorkspaceTreeAsync(dir, baseDir, out, state) {
|
|
|
36014
36319
|
await yieldToEventLoop();
|
|
36015
36320
|
}
|
|
36016
36321
|
state.n++;
|
|
36017
|
-
const full =
|
|
36322
|
+
const full = path28.join(dir, name);
|
|
36018
36323
|
let stat3;
|
|
36019
36324
|
try {
|
|
36020
|
-
stat3 = await
|
|
36325
|
+
stat3 = await fs25.promises.stat(full);
|
|
36021
36326
|
} catch {
|
|
36022
36327
|
continue;
|
|
36023
36328
|
}
|
|
36024
|
-
const relative5 =
|
|
36329
|
+
const relative5 = path28.relative(baseDir, full).replace(/\\/g, "/");
|
|
36025
36330
|
if (stat3.isDirectory()) {
|
|
36026
36331
|
await walkWorkspaceTreeAsync(full, baseDir, out, state);
|
|
36027
36332
|
} else if (stat3.isFile()) {
|
|
@@ -36033,205 +36338,124 @@ function createWalkYieldState() {
|
|
|
36033
36338
|
return { n: 0 };
|
|
36034
36339
|
}
|
|
36035
36340
|
|
|
36036
|
-
// src/files/index/
|
|
36037
|
-
|
|
36038
|
-
|
|
36039
|
-
const
|
|
36040
|
-
|
|
36041
|
-
out.push(lower.slice(i, i + 3));
|
|
36042
|
-
}
|
|
36043
|
-
return out;
|
|
36044
|
-
}
|
|
36045
|
-
function binarySearch(arr, x) {
|
|
36046
|
-
let lo = 0;
|
|
36047
|
-
let hi = arr.length - 1;
|
|
36048
|
-
while (lo <= hi) {
|
|
36049
|
-
const mid = lo + hi >>> 1;
|
|
36050
|
-
if (arr[mid] < x) lo = mid + 1;
|
|
36051
|
-
else if (arr[mid] > x) hi = mid - 1;
|
|
36052
|
-
else return mid;
|
|
36053
|
-
}
|
|
36054
|
-
return -1;
|
|
36055
|
-
}
|
|
36056
|
-
function intersectSortedTrigramSets(arrays) {
|
|
36057
|
-
if (arrays.length === 0) return [];
|
|
36058
|
-
if (arrays.length === 1) return arrays[0];
|
|
36059
|
-
const byLength = arrays.slice().sort((a, b) => a.length - b.length);
|
|
36060
|
-
const smallest = byLength[0];
|
|
36061
|
-
const rest = byLength.slice(1);
|
|
36062
|
-
const result = [];
|
|
36063
|
-
for (const idx of smallest) {
|
|
36064
|
-
if (rest.every((arr) => binarySearch(arr, idx) >= 0)) {
|
|
36065
|
-
result.push(idx);
|
|
36066
|
-
}
|
|
36067
|
-
}
|
|
36068
|
-
return result;
|
|
36069
|
-
}
|
|
36070
|
-
|
|
36071
|
-
// src/files/index/build-trigram-map.ts
|
|
36072
|
-
function buildTrigramMapForPaths(paths) {
|
|
36073
|
-
const trigramIndex = {};
|
|
36074
|
-
for (let i = 0; i < paths.length; i++) {
|
|
36075
|
-
const trigrams = getTrigrams(paths[i]);
|
|
36076
|
-
const seen = /* @__PURE__ */ new Set();
|
|
36077
|
-
for (const tri of trigrams) {
|
|
36078
|
-
if (seen.has(tri)) continue;
|
|
36079
|
-
seen.add(tri);
|
|
36080
|
-
if (!trigramIndex[tri]) trigramIndex[tri] = [];
|
|
36081
|
-
trigramIndex[tri].push(i);
|
|
36082
|
-
}
|
|
36083
|
-
}
|
|
36084
|
-
return trigramIndex;
|
|
36341
|
+
// src/files/index/file-index-sqlite-lock.ts
|
|
36342
|
+
import fs26 from "node:fs";
|
|
36343
|
+
function isSqliteCorruptError(e) {
|
|
36344
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
36345
|
+
return msg.includes("malformed") || msg.includes("database disk image is malformed") || msg.includes("corrupt");
|
|
36085
36346
|
}
|
|
36086
|
-
|
|
36087
|
-
|
|
36088
|
-
|
|
36089
|
-
|
|
36090
|
-
await
|
|
36091
|
-
}
|
|
36092
|
-
|
|
36093
|
-
|
|
36094
|
-
|
|
36095
|
-
|
|
36096
|
-
|
|
36097
|
-
|
|
36098
|
-
|
|
36347
|
+
var chain = Promise.resolve();
|
|
36348
|
+
function withFileIndexSqliteLock(fn) {
|
|
36349
|
+
const run = async () => {
|
|
36350
|
+
try {
|
|
36351
|
+
return await Promise.resolve(fn());
|
|
36352
|
+
} catch (e) {
|
|
36353
|
+
if (!isSqliteCorruptError(e)) throw e;
|
|
36354
|
+
closeAllCliSqliteConnections();
|
|
36355
|
+
try {
|
|
36356
|
+
fs26.unlinkSync(getCliSqlitePath());
|
|
36357
|
+
} catch {
|
|
36358
|
+
}
|
|
36359
|
+
chain = Promise.resolve();
|
|
36360
|
+
return await Promise.resolve(fn());
|
|
36099
36361
|
}
|
|
36100
|
-
}
|
|
36101
|
-
|
|
36102
|
-
|
|
36103
|
-
|
|
36104
|
-
|
|
36105
|
-
|
|
36106
|
-
|
|
36107
|
-
// src/files/index/paths.ts
|
|
36108
|
-
import path23 from "node:path";
|
|
36109
|
-
import crypto2 from "node:crypto";
|
|
36110
|
-
function getIndexPathForCwd(resolvedCwd) {
|
|
36111
|
-
const hash = crypto2.createHash("sha256").update(resolvedCwd).digest("hex").slice(0, INDEX_HASH_LEN);
|
|
36112
|
-
return path23.join(INDEX_DIR, `.file-index-${hash}.json`);
|
|
36113
|
-
}
|
|
36114
|
-
|
|
36115
|
-
// src/files/index/write-index-file.ts
|
|
36116
|
-
function writeIndexFileSync(resolvedCwd, data) {
|
|
36117
|
-
const indexPath = getIndexPathForCwd(resolvedCwd);
|
|
36118
|
-
try {
|
|
36119
|
-
if (!fs21.existsSync(INDEX_DIR)) fs21.mkdirSync(INDEX_DIR, { recursive: true });
|
|
36120
|
-
fs21.writeFileSync(indexPath, JSON.stringify(data), "utf8");
|
|
36121
|
-
} catch (e) {
|
|
36122
|
-
console.error(`${INDEX_LOG_PREFIX} Failed to write index:`, e);
|
|
36123
|
-
}
|
|
36124
|
-
}
|
|
36125
|
-
async function writeIndexFileAsync(resolvedCwd, data) {
|
|
36126
|
-
const indexPath = getIndexPathForCwd(resolvedCwd);
|
|
36127
|
-
try {
|
|
36128
|
-
await fs21.promises.mkdir(INDEX_DIR, { recursive: true });
|
|
36129
|
-
await fs21.promises.writeFile(indexPath, JSON.stringify(data), "utf8");
|
|
36130
|
-
} catch (e) {
|
|
36131
|
-
console.error(`${INDEX_LOG_PREFIX} Failed to write index:`, e);
|
|
36132
|
-
}
|
|
36133
|
-
}
|
|
36134
|
-
function makeTrigramIndexData(paths, trigramIndex) {
|
|
36135
|
-
return { version: INDEX_VERSION, paths, trigramIndex };
|
|
36362
|
+
};
|
|
36363
|
+
const next = chain.then(run);
|
|
36364
|
+
chain = next.then(
|
|
36365
|
+
() => void 0,
|
|
36366
|
+
() => void 0
|
|
36367
|
+
);
|
|
36368
|
+
return next;
|
|
36136
36369
|
}
|
|
36137
36370
|
|
|
36138
36371
|
// src/files/index/build-file-index.ts
|
|
36139
36372
|
function sortPaths(paths) {
|
|
36140
36373
|
paths.sort((a, b) => a.localeCompare(b, void 0, { sensitivity: "base" }));
|
|
36141
36374
|
}
|
|
36142
|
-
function
|
|
36143
|
-
const
|
|
36144
|
-
const
|
|
36145
|
-
|
|
36146
|
-
sortPaths(paths);
|
|
36147
|
-
const trigramIndex = buildTrigramMapForPaths(paths);
|
|
36148
|
-
const data = makeTrigramIndexData(paths, trigramIndex);
|
|
36149
|
-
writeIndexFileSync(resolved, data);
|
|
36150
|
-
return data;
|
|
36151
|
-
}
|
|
36152
|
-
async function buildFileIndexAsync(cwd) {
|
|
36153
|
-
const resolved = path24.resolve(cwd);
|
|
36154
|
-
const paths = [];
|
|
36155
|
-
await walkWorkspaceTreeAsync(resolved, resolved, paths, createWalkYieldState());
|
|
36156
|
-
await yieldToEventLoop();
|
|
36157
|
-
sortPaths(paths);
|
|
36158
|
-
const trigramIndex = await buildTrigramMapForPathsAsync(paths);
|
|
36159
|
-
const data = makeTrigramIndexData(paths, trigramIndex);
|
|
36160
|
-
await writeIndexFileAsync(resolved, data);
|
|
36161
|
-
return data;
|
|
36162
|
-
}
|
|
36163
|
-
|
|
36164
|
-
// src/files/index/load-file-index.ts
|
|
36165
|
-
import fs22 from "node:fs";
|
|
36166
|
-
import path25 from "node:path";
|
|
36167
|
-
function loadFileIndex(cwd) {
|
|
36168
|
-
const resolved = path25.resolve(cwd);
|
|
36169
|
-
const indexPath = getIndexPathForCwd(resolved);
|
|
36375
|
+
function persistPathsToSqlite(resolved, paths) {
|
|
36376
|
+
const db = getCliDatabase();
|
|
36377
|
+
const h = getCwdHashForFileIndex(resolved);
|
|
36378
|
+
db.run("BEGIN IMMEDIATE");
|
|
36170
36379
|
try {
|
|
36171
|
-
|
|
36172
|
-
const
|
|
36173
|
-
|
|
36174
|
-
const
|
|
36175
|
-
|
|
36176
|
-
return obj;
|
|
36380
|
+
db.run("DELETE FROM file_index_path WHERE cwd_hash = ?", [h]);
|
|
36381
|
+
const ins = db.prepare("INSERT INTO file_index_path (cwd_hash, path) VALUES (?, ?)");
|
|
36382
|
+
try {
|
|
36383
|
+
for (const rel of paths) {
|
|
36384
|
+
ins.run([h, rel]);
|
|
36177
36385
|
}
|
|
36178
|
-
|
|
36386
|
+
} finally {
|
|
36387
|
+
ins.finalize();
|
|
36179
36388
|
}
|
|
36180
|
-
|
|
36181
|
-
|
|
36389
|
+
db.run("COMMIT");
|
|
36390
|
+
} catch (e) {
|
|
36391
|
+
try {
|
|
36392
|
+
db.run("ROLLBACK");
|
|
36393
|
+
} catch {
|
|
36182
36394
|
}
|
|
36183
|
-
|
|
36184
|
-
} catch {
|
|
36185
|
-
return null;
|
|
36395
|
+
throw e;
|
|
36186
36396
|
}
|
|
36187
36397
|
}
|
|
36398
|
+
async function buildFileIndexAsync(cwd) {
|
|
36399
|
+
return withFileIndexSqliteLock(async () => {
|
|
36400
|
+
const resolved = path29.resolve(cwd);
|
|
36401
|
+
const paths = [];
|
|
36402
|
+
await walkWorkspaceTreeAsync(resolved, resolved, paths, createWalkYieldState());
|
|
36403
|
+
await yieldToEventLoop();
|
|
36404
|
+
sortPaths(paths);
|
|
36405
|
+
persistPathsToSqlite(resolved, paths);
|
|
36406
|
+
return { pathCount: paths.length };
|
|
36407
|
+
});
|
|
36408
|
+
}
|
|
36188
36409
|
|
|
36189
36410
|
// src/files/index/ensure-file-index.ts
|
|
36190
|
-
import
|
|
36191
|
-
async function ensureFileIndexAsync(cwd) {
|
|
36192
|
-
const resolved = path26.resolve(cwd);
|
|
36193
|
-
const cached2 = loadFileIndex(resolved);
|
|
36194
|
-
if (cached2 !== null) return { data: cached2, fromCache: true };
|
|
36195
|
-
const data = await buildFileIndexAsync(resolved);
|
|
36196
|
-
return { data, fromCache: false };
|
|
36197
|
-
}
|
|
36411
|
+
import path30 from "node:path";
|
|
36198
36412
|
|
|
36199
36413
|
// src/files/index/search-file-index.ts
|
|
36200
|
-
function
|
|
36201
|
-
|
|
36202
|
-
|
|
36203
|
-
|
|
36204
|
-
|
|
36205
|
-
const
|
|
36206
|
-
|
|
36207
|
-
|
|
36208
|
-
|
|
36209
|
-
|
|
36210
|
-
|
|
36211
|
-
|
|
36212
|
-
|
|
36213
|
-
|
|
36214
|
-
|
|
36414
|
+
function escapeLikePattern(fragment) {
|
|
36415
|
+
return fragment.replace(/\\/g, "\\\\").replace(/%/g, "\\%").replace(/_/g, "\\_");
|
|
36416
|
+
}
|
|
36417
|
+
function bridgeFileIndexIsPopulated(resolvedCwd) {
|
|
36418
|
+
const db = getCliDatabase();
|
|
36419
|
+
const h = getCwdHashForFileIndex(resolvedCwd);
|
|
36420
|
+
const row = db.get("SELECT 1 as ok FROM file_index_path WHERE cwd_hash = ? LIMIT 1", [h]);
|
|
36421
|
+
return row != null;
|
|
36422
|
+
}
|
|
36423
|
+
function bridgeFileIndexPathCount(resolvedCwd) {
|
|
36424
|
+
const db = getCliDatabase();
|
|
36425
|
+
const h = getCwdHashForFileIndex(resolvedCwd);
|
|
36426
|
+
const row = db.get("SELECT COUNT(*) as c FROM file_index_path WHERE cwd_hash = ?", [h]);
|
|
36427
|
+
const c = row?.c ?? 0;
|
|
36428
|
+
return Number(c);
|
|
36429
|
+
}
|
|
36430
|
+
function searchBridgeFilePaths(resolvedCwd, query, limit = 100) {
|
|
36215
36431
|
const q = query.trim().toLowerCase();
|
|
36216
36432
|
if (!q) return [];
|
|
36217
|
-
const
|
|
36218
|
-
const
|
|
36219
|
-
const
|
|
36220
|
-
|
|
36221
|
-
|
|
36222
|
-
|
|
36223
|
-
|
|
36224
|
-
|
|
36225
|
-
|
|
36226
|
-
|
|
36227
|
-
|
|
36228
|
-
|
|
36229
|
-
|
|
36230
|
-
|
|
36231
|
-
}
|
|
36433
|
+
const db = getCliDatabase();
|
|
36434
|
+
const h = getCwdHashForFileIndex(resolvedCwd);
|
|
36435
|
+
const pattern = `%${escapeLikePattern(q)}%`;
|
|
36436
|
+
const lim = Math.max(0, Math.min(1e4, Math.floor(limit)));
|
|
36437
|
+
const rows = db.all(
|
|
36438
|
+
`SELECT path FROM file_index_path WHERE cwd_hash = ? AND lower(path) LIKE ? ESCAPE '\\' LIMIT ?`,
|
|
36439
|
+
[h, pattern, lim]
|
|
36440
|
+
);
|
|
36441
|
+
return rows.map((r) => String(r.path));
|
|
36442
|
+
}
|
|
36443
|
+
async function searchBridgeFilePathsAsync(resolvedCwd, query, limit = 100) {
|
|
36444
|
+
await yieldToEventLoop();
|
|
36445
|
+
const out = searchBridgeFilePaths(resolvedCwd, query, limit);
|
|
36446
|
+
if (out.length >= INDEX_WORK_YIELD_EVERY) await yieldToEventLoop();
|
|
36232
36447
|
return out;
|
|
36233
36448
|
}
|
|
36234
36449
|
|
|
36450
|
+
// src/files/index/ensure-file-index.ts
|
|
36451
|
+
async function ensureFileIndexAsync(cwd) {
|
|
36452
|
+
const resolved = path30.resolve(cwd);
|
|
36453
|
+
if (bridgeFileIndexIsPopulated(resolved)) {
|
|
36454
|
+
return { fromCache: true, pathCount: bridgeFileIndexPathCount(resolved) };
|
|
36455
|
+
}
|
|
36456
|
+
return { ...await buildFileIndexAsync(resolved), fromCache: false };
|
|
36457
|
+
}
|
|
36458
|
+
|
|
36235
36459
|
// src/files/watch-file-index.ts
|
|
36236
36460
|
var DEBOUNCE_MS = 900;
|
|
36237
36461
|
function shouldIgnoreRelative(rel) {
|
|
@@ -36272,7 +36496,7 @@ function createFsWatcher(resolved, schedule) {
|
|
|
36272
36496
|
}
|
|
36273
36497
|
}
|
|
36274
36498
|
function startFileIndexWatcher(cwd = getBridgeRoot()) {
|
|
36275
|
-
const resolved =
|
|
36499
|
+
const resolved = path31.resolve(cwd);
|
|
36276
36500
|
void buildFileIndexAsync(resolved).catch((e) => {
|
|
36277
36501
|
console.error("[file-index] Initial index build failed:", e);
|
|
36278
36502
|
});
|
|
@@ -36300,7 +36524,7 @@ function startFileIndexWatcher(cwd = getBridgeRoot()) {
|
|
|
36300
36524
|
}
|
|
36301
36525
|
|
|
36302
36526
|
// src/connection/create-bridge-connection.ts
|
|
36303
|
-
import * as
|
|
36527
|
+
import * as path39 from "node:path";
|
|
36304
36528
|
|
|
36305
36529
|
// src/dev-servers/manager/dev-server-manager.ts
|
|
36306
36530
|
import { rm as rm2 } from "node:fs/promises";
|
|
@@ -36344,7 +36568,7 @@ function forceKillChild(proc, log2, shortId, graceMs) {
|
|
|
36344
36568
|
}
|
|
36345
36569
|
|
|
36346
36570
|
// src/dev-servers/process/wire-dev-server-child-process.ts
|
|
36347
|
-
import
|
|
36571
|
+
import fs27 from "node:fs";
|
|
36348
36572
|
|
|
36349
36573
|
// src/dev-servers/manager/forward-pipe.ts
|
|
36350
36574
|
function forwardChildPipe(childReadable, terminal, onData) {
|
|
@@ -36380,7 +36604,7 @@ function wireDevServerChildProcess(d) {
|
|
|
36380
36604
|
d.setPollInterval(void 0);
|
|
36381
36605
|
return;
|
|
36382
36606
|
}
|
|
36383
|
-
|
|
36607
|
+
fs27.readFile(d.mergedLogPath, (err, buf) => {
|
|
36384
36608
|
if (err || (d.getSpawnGeneration() ?? 0) !== d.scheduledGen) return;
|
|
36385
36609
|
if (buf.length <= d.mergedReadPos.value) return;
|
|
36386
36610
|
const chunk = Buffer.from(buf.subarray(d.mergedReadPos.value));
|
|
@@ -36418,7 +36642,7 @@ ${errTail}` : ""}`);
|
|
|
36418
36642
|
d.sendStatus(code === 0 || code == null ? "stopped" : "error", detail, tails);
|
|
36419
36643
|
};
|
|
36420
36644
|
if (mergedPath) {
|
|
36421
|
-
|
|
36645
|
+
fs27.readFile(mergedPath, (err, buf) => {
|
|
36422
36646
|
if (!err && buf.length > d.mergedReadPos.value) {
|
|
36423
36647
|
const chunk = Buffer.from(buf.subarray(d.mergedReadPos.value));
|
|
36424
36648
|
if (chunk.length > 0) {
|
|
@@ -36520,13 +36744,13 @@ function parseDevServerDefs(servers) {
|
|
|
36520
36744
|
}
|
|
36521
36745
|
|
|
36522
36746
|
// src/dev-servers/manager/shell-spawn/utils.ts
|
|
36523
|
-
import
|
|
36747
|
+
import fs28 from "node:fs";
|
|
36524
36748
|
function isSpawnEbadf(e) {
|
|
36525
36749
|
return typeof e === "object" && e !== null && "code" in e && e.code === "EBADF";
|
|
36526
36750
|
}
|
|
36527
36751
|
function rmDirQuiet(dir) {
|
|
36528
36752
|
try {
|
|
36529
|
-
|
|
36753
|
+
fs28.rmSync(dir, { recursive: true, force: true });
|
|
36530
36754
|
} catch {
|
|
36531
36755
|
}
|
|
36532
36756
|
}
|
|
@@ -36534,7 +36758,7 @@ var cachedDevNullReadFd;
|
|
|
36534
36758
|
function devNullReadFd() {
|
|
36535
36759
|
if (cachedDevNullReadFd === void 0) {
|
|
36536
36760
|
const devPath = process.platform === "win32" ? "nul" : "/dev/null";
|
|
36537
|
-
cachedDevNullReadFd =
|
|
36761
|
+
cachedDevNullReadFd = fs28.openSync(devPath, "r");
|
|
36538
36762
|
}
|
|
36539
36763
|
return cachedDevNullReadFd;
|
|
36540
36764
|
}
|
|
@@ -36608,15 +36832,15 @@ function trySpawnShellTruePiped(command, env, cwd, devNullFd, signal) {
|
|
|
36608
36832
|
|
|
36609
36833
|
// src/dev-servers/manager/shell-spawn/try-spawn-merged-log-file.ts
|
|
36610
36834
|
import { spawn as spawn6 } from "node:child_process";
|
|
36611
|
-
import
|
|
36835
|
+
import fs29 from "node:fs";
|
|
36612
36836
|
import { tmpdir } from "node:os";
|
|
36613
|
-
import
|
|
36837
|
+
import path32 from "node:path";
|
|
36614
36838
|
function trySpawnMergedLogFile(command, env, cwd, signal) {
|
|
36615
|
-
const tmpRoot =
|
|
36616
|
-
const logPath =
|
|
36839
|
+
const tmpRoot = fs29.mkdtempSync(path32.join(tmpdir(), "ba-devsrv-log-"));
|
|
36840
|
+
const logPath = path32.join(tmpRoot, "combined.log");
|
|
36617
36841
|
let logFd;
|
|
36618
36842
|
try {
|
|
36619
|
-
logFd =
|
|
36843
|
+
logFd = fs29.openSync(logPath, "a");
|
|
36620
36844
|
} catch {
|
|
36621
36845
|
rmDirQuiet(tmpRoot);
|
|
36622
36846
|
return null;
|
|
@@ -36635,7 +36859,7 @@ function trySpawnMergedLogFile(command, env, cwd, signal) {
|
|
|
36635
36859
|
} else {
|
|
36636
36860
|
proc = spawn6("/bin/sh", ["-c", command], { env, cwd, stdio, ...signal ? { signal } : {} });
|
|
36637
36861
|
}
|
|
36638
|
-
|
|
36862
|
+
fs29.closeSync(logFd);
|
|
36639
36863
|
return {
|
|
36640
36864
|
proc,
|
|
36641
36865
|
pipedStdoutStderr: true,
|
|
@@ -36644,7 +36868,7 @@ function trySpawnMergedLogFile(command, env, cwd, signal) {
|
|
|
36644
36868
|
};
|
|
36645
36869
|
} catch (e) {
|
|
36646
36870
|
try {
|
|
36647
|
-
|
|
36871
|
+
fs29.closeSync(logFd);
|
|
36648
36872
|
} catch {
|
|
36649
36873
|
}
|
|
36650
36874
|
rmDirQuiet(tmpRoot);
|
|
@@ -36655,22 +36879,22 @@ function trySpawnMergedLogFile(command, env, cwd, signal) {
|
|
|
36655
36879
|
|
|
36656
36880
|
// src/dev-servers/manager/shell-spawn/try-spawn-shell-script-log-redirect.ts
|
|
36657
36881
|
import { spawn as spawn7 } from "node:child_process";
|
|
36658
|
-
import
|
|
36882
|
+
import fs30 from "node:fs";
|
|
36659
36883
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
36660
|
-
import
|
|
36884
|
+
import path33 from "node:path";
|
|
36661
36885
|
function shSingleQuote(s) {
|
|
36662
36886
|
return `'${s.replace(/'/g, `'\\''`)}'`;
|
|
36663
36887
|
}
|
|
36664
36888
|
function trySpawnShellScriptLogRedirectUnix(command, env, cwd, signal) {
|
|
36665
|
-
const tmpRoot =
|
|
36666
|
-
const logPath =
|
|
36667
|
-
const innerPath =
|
|
36668
|
-
const runnerPath =
|
|
36889
|
+
const tmpRoot = fs30.mkdtempSync(path33.join(tmpdir2(), "ba-devsrv-sh-"));
|
|
36890
|
+
const logPath = path33.join(tmpRoot, "combined.log");
|
|
36891
|
+
const innerPath = path33.join(tmpRoot, "_cmd.sh");
|
|
36892
|
+
const runnerPath = path33.join(tmpRoot, "_run.sh");
|
|
36669
36893
|
try {
|
|
36670
|
-
|
|
36894
|
+
fs30.writeFileSync(innerPath, `#!/bin/sh
|
|
36671
36895
|
${command}
|
|
36672
36896
|
`);
|
|
36673
|
-
|
|
36897
|
+
fs30.writeFileSync(
|
|
36674
36898
|
runnerPath,
|
|
36675
36899
|
`#!/bin/sh
|
|
36676
36900
|
cd ${shSingleQuote(cwd)}
|
|
@@ -36696,13 +36920,13 @@ cd ${shSingleQuote(cwd)}
|
|
|
36696
36920
|
}
|
|
36697
36921
|
}
|
|
36698
36922
|
function trySpawnShellScriptLogRedirectWin(command, env, cwd, signal) {
|
|
36699
|
-
const tmpRoot =
|
|
36700
|
-
const logPath =
|
|
36701
|
-
const runnerPath =
|
|
36923
|
+
const tmpRoot = fs30.mkdtempSync(path33.join(tmpdir2(), "ba-devsrv-sh-"));
|
|
36924
|
+
const logPath = path33.join(tmpRoot, "combined.log");
|
|
36925
|
+
const runnerPath = path33.join(tmpRoot, "_run.bat");
|
|
36702
36926
|
const q = (p) => `"${p.replace(/"/g, '""')}"`;
|
|
36703
36927
|
const com = process.env.ComSpec || "cmd.exe";
|
|
36704
36928
|
try {
|
|
36705
|
-
|
|
36929
|
+
fs30.writeFileSync(
|
|
36706
36930
|
runnerPath,
|
|
36707
36931
|
`@ECHO OFF\r
|
|
36708
36932
|
CD /D ${q(cwd)}\r
|
|
@@ -37639,30 +37863,30 @@ function createOnBridgeIdentified(opts) {
|
|
|
37639
37863
|
}
|
|
37640
37864
|
|
|
37641
37865
|
// src/skills/discover-local-agent-skills.ts
|
|
37642
|
-
import
|
|
37643
|
-
import
|
|
37866
|
+
import fs31 from "node:fs";
|
|
37867
|
+
import path34 from "node:path";
|
|
37644
37868
|
var SKILL_DISCOVERY_ROOTS = [".agents/skills", ".claude/skills", ".cursor/skills", "skills"];
|
|
37645
37869
|
function discoverLocalSkills(cwd) {
|
|
37646
37870
|
const out = [];
|
|
37647
37871
|
const seenKeys = /* @__PURE__ */ new Set();
|
|
37648
37872
|
for (const rel of SKILL_DISCOVERY_ROOTS) {
|
|
37649
|
-
const base =
|
|
37650
|
-
if (!
|
|
37873
|
+
const base = path34.join(cwd, rel);
|
|
37874
|
+
if (!fs31.existsSync(base) || !fs31.statSync(base).isDirectory()) continue;
|
|
37651
37875
|
let entries = [];
|
|
37652
37876
|
try {
|
|
37653
|
-
entries =
|
|
37877
|
+
entries = fs31.readdirSync(base);
|
|
37654
37878
|
} catch {
|
|
37655
37879
|
continue;
|
|
37656
37880
|
}
|
|
37657
37881
|
for (const name of entries) {
|
|
37658
|
-
const dir =
|
|
37882
|
+
const dir = path34.join(base, name);
|
|
37659
37883
|
try {
|
|
37660
|
-
if (!
|
|
37884
|
+
if (!fs31.statSync(dir).isDirectory()) continue;
|
|
37661
37885
|
} catch {
|
|
37662
37886
|
continue;
|
|
37663
37887
|
}
|
|
37664
|
-
const skillMd =
|
|
37665
|
-
if (!
|
|
37888
|
+
const skillMd = path34.join(dir, "SKILL.md");
|
|
37889
|
+
if (!fs31.existsSync(skillMd)) continue;
|
|
37666
37890
|
const key = `${rel}/${name}`;
|
|
37667
37891
|
if (seenKeys.has(key)) continue;
|
|
37668
37892
|
seenKeys.add(key);
|
|
@@ -37674,23 +37898,23 @@ function discoverLocalSkills(cwd) {
|
|
|
37674
37898
|
function discoverSkillLayoutRoots(cwd) {
|
|
37675
37899
|
const roots = [];
|
|
37676
37900
|
for (const rel of SKILL_DISCOVERY_ROOTS) {
|
|
37677
|
-
const base =
|
|
37678
|
-
if (!
|
|
37901
|
+
const base = path34.join(cwd, rel);
|
|
37902
|
+
if (!fs31.existsSync(base) || !fs31.statSync(base).isDirectory()) continue;
|
|
37679
37903
|
let entries = [];
|
|
37680
37904
|
try {
|
|
37681
|
-
entries =
|
|
37905
|
+
entries = fs31.readdirSync(base);
|
|
37682
37906
|
} catch {
|
|
37683
37907
|
continue;
|
|
37684
37908
|
}
|
|
37685
37909
|
const skills2 = [];
|
|
37686
37910
|
for (const name of entries) {
|
|
37687
|
-
const dir =
|
|
37911
|
+
const dir = path34.join(base, name);
|
|
37688
37912
|
try {
|
|
37689
|
-
if (!
|
|
37913
|
+
if (!fs31.statSync(dir).isDirectory()) continue;
|
|
37690
37914
|
} catch {
|
|
37691
37915
|
continue;
|
|
37692
37916
|
}
|
|
37693
|
-
if (!
|
|
37917
|
+
if (!fs31.existsSync(path34.join(dir, "SKILL.md"))) continue;
|
|
37694
37918
|
const relPath = `${rel}/${name}`.replace(/\\/g, "/");
|
|
37695
37919
|
skills2.push({ name, relPath });
|
|
37696
37920
|
}
|
|
@@ -37884,7 +38108,7 @@ var handleAgentConfigMessage = (msg, deps) => {
|
|
|
37884
38108
|
};
|
|
37885
38109
|
|
|
37886
38110
|
// src/prompt-turn-queue/runner.ts
|
|
37887
|
-
import
|
|
38111
|
+
import fs32 from "node:fs";
|
|
37888
38112
|
|
|
37889
38113
|
// src/prompt-turn-queue/client-report.ts
|
|
37890
38114
|
function sendPromptQueueClientReport(ws, queues) {
|
|
@@ -37893,32 +38117,6 @@ function sendPromptQueueClientReport(ws, queues) {
|
|
|
37893
38117
|
return true;
|
|
37894
38118
|
}
|
|
37895
38119
|
|
|
37896
|
-
// src/prompt-turn-queue/disk-store.ts
|
|
37897
|
-
import fs29 from "node:fs";
|
|
37898
|
-
|
|
37899
|
-
// src/prompt-turn-queue/paths.ts
|
|
37900
|
-
import crypto3 from "node:crypto";
|
|
37901
|
-
import fs28 from "node:fs";
|
|
37902
|
-
import path31 from "node:path";
|
|
37903
|
-
import os7 from "node:os";
|
|
37904
|
-
var QUEUE_KEY_HEX_64 = /^[a-f0-9]{64}$/i;
|
|
37905
|
-
function queueStateFileSlug(queueKey) {
|
|
37906
|
-
if (QUEUE_KEY_HEX_64.test(queueKey)) return queueKey.toLowerCase();
|
|
37907
|
-
return crypto3.createHash("sha256").update(queueKey, "utf8").digest("hex");
|
|
37908
|
-
}
|
|
37909
|
-
function getPromptQueuesDirectory() {
|
|
37910
|
-
const override = process.env.BUILDAMATON_PROMPT_QUEUES_DIR?.trim();
|
|
37911
|
-
if (override) return path31.resolve(override);
|
|
37912
|
-
return path31.join(os7.homedir(), ".buildautomaton", "queues");
|
|
37913
|
-
}
|
|
37914
|
-
function ensurePromptQueuesDirectory() {
|
|
37915
|
-
const dir = getPromptQueuesDirectory();
|
|
37916
|
-
if (!fs28.existsSync(dir)) fs28.mkdirSync(dir, { recursive: true });
|
|
37917
|
-
}
|
|
37918
|
-
function queueStateFilePath(queueKey) {
|
|
37919
|
-
return path31.join(getPromptQueuesDirectory(), `${queueStateFileSlug(queueKey)}.json`);
|
|
37920
|
-
}
|
|
37921
|
-
|
|
37922
38120
|
// src/prompt-turn-queue/disk-store.ts
|
|
37923
38121
|
var MERGEABLE_SERVER_STATES = /* @__PURE__ */ new Set([
|
|
37924
38122
|
"queued",
|
|
@@ -37928,28 +38126,27 @@ var MERGEABLE_SERVER_STATES = /* @__PURE__ */ new Set([
|
|
|
37928
38126
|
"stopping",
|
|
37929
38127
|
"discarded"
|
|
37930
38128
|
]);
|
|
37931
|
-
function parsePersistedQueueFile(raw) {
|
|
37932
|
-
try {
|
|
37933
|
-
const o = JSON.parse(raw);
|
|
37934
|
-
const queueKey = typeof o.queueKey === "string" ? o.queueKey : typeof o.queueKeyHash === "string" ? o.queueKeyHash : null;
|
|
37935
|
-
if (!queueKey || typeof o.updatedAt !== "string" || !Array.isArray(o.turns)) return null;
|
|
37936
|
-
return { queueKey, updatedAt: o.updatedAt, turns: o.turns };
|
|
37937
|
-
} catch {
|
|
37938
|
-
return null;
|
|
37939
|
-
}
|
|
37940
|
-
}
|
|
37941
38129
|
function readPersistedQueue(queueKey) {
|
|
37942
|
-
const
|
|
38130
|
+
const db = getCliDatabase();
|
|
38131
|
+
const row = db.get("SELECT queue_key, updated_at, turns_json FROM prompt_queue WHERE queue_key = ?", [
|
|
38132
|
+
queueKey
|
|
38133
|
+
]);
|
|
38134
|
+
if (!row) return null;
|
|
37943
38135
|
try {
|
|
37944
|
-
|
|
38136
|
+
const turns = JSON.parse(row.turns_json);
|
|
38137
|
+
if (!Array.isArray(turns)) return null;
|
|
38138
|
+
return { queueKey: row.queue_key, updatedAt: row.updated_at, turns };
|
|
37945
38139
|
} catch {
|
|
37946
38140
|
return null;
|
|
37947
38141
|
}
|
|
37948
38142
|
}
|
|
37949
38143
|
function writePersistedQueue(file2) {
|
|
37950
|
-
|
|
37951
|
-
|
|
37952
|
-
|
|
38144
|
+
const db = getCliDatabase();
|
|
38145
|
+
db.run(
|
|
38146
|
+
`INSERT INTO prompt_queue (queue_key, updated_at, turns_json) VALUES (?, ?, ?)
|
|
38147
|
+
ON CONFLICT(queue_key) DO UPDATE SET updated_at = excluded.updated_at, turns_json = excluded.turns_json`,
|
|
38148
|
+
[file2.queueKey, file2.updatedAt, JSON.stringify(file2.turns)]
|
|
38149
|
+
);
|
|
37953
38150
|
}
|
|
37954
38151
|
function mergeServerQueueSnapshot(queueKey, serverTurns) {
|
|
37955
38152
|
const prev = readPersistedQueue(queueKey);
|
|
@@ -38007,7 +38204,7 @@ async function runLocalRevertBeforeQueuedPrompt(next, deps) {
|
|
|
38007
38204
|
const tid = typeof pl.snapshotRevertTurnId === "string" && pl.snapshotRevertTurnId.trim() !== "" ? pl.snapshotRevertTurnId.trim() : next.turnId;
|
|
38008
38205
|
const agentBase = deps.sessionWorktreeManager.getSessionWorktreeRootForSession(sid) ?? getBridgeRoot();
|
|
38009
38206
|
const file2 = snapshotFilePath(agentBase, tid);
|
|
38010
|
-
if (!
|
|
38207
|
+
if (!fs32.existsSync(file2)) {
|
|
38011
38208
|
deps.log(
|
|
38012
38209
|
`[Queue] requeued_with_revert: no pre-turn snapshot for ${tid.slice(0, 8)}\u2026; continuing without revert.`
|
|
38013
38210
|
);
|
|
@@ -38231,9 +38428,9 @@ function parseChangeSummarySnapshots(raw) {
|
|
|
38231
38428
|
for (const item of raw) {
|
|
38232
38429
|
if (!item || typeof item !== "object") continue;
|
|
38233
38430
|
const o = item;
|
|
38234
|
-
const
|
|
38235
|
-
if (!
|
|
38236
|
-
const row = { path:
|
|
38431
|
+
const path41 = typeof o.path === "string" && o.path.trim() !== "" ? o.path.trim() : "";
|
|
38432
|
+
if (!path41) continue;
|
|
38433
|
+
const row = { path: path41 };
|
|
38237
38434
|
if (typeof o.patchContent === "string") row.patchContent = o.patchContent;
|
|
38238
38435
|
if (typeof o.oldText === "string") row.oldText = o.oldText;
|
|
38239
38436
|
if (typeof o.newText === "string") row.newText = o.newText;
|
|
@@ -38450,8 +38647,8 @@ function randomSecret() {
|
|
|
38450
38647
|
}
|
|
38451
38648
|
return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
38452
38649
|
}
|
|
38453
|
-
async function requestPreviewApi(port, secret, method,
|
|
38454
|
-
const url2 = `http://127.0.0.1:${port}${
|
|
38650
|
+
async function requestPreviewApi(port, secret, method, path41, body) {
|
|
38651
|
+
const url2 = `http://127.0.0.1:${port}${path41}`;
|
|
38455
38652
|
const headers = {
|
|
38456
38653
|
[PREVIEW_SECRET_HEADER]: secret,
|
|
38457
38654
|
"Content-Type": "application/json"
|
|
@@ -38463,7 +38660,7 @@ async function requestPreviewApi(port, secret, method, path37, body) {
|
|
|
38463
38660
|
});
|
|
38464
38661
|
const data = await res.json().catch(() => ({}));
|
|
38465
38662
|
if (!res.ok) {
|
|
38466
|
-
throw new Error(data?.error ?? `Preview API ${method} ${
|
|
38663
|
+
throw new Error(data?.error ?? `Preview API ${method} ${path41}: ${res.status}`);
|
|
38467
38664
|
}
|
|
38468
38665
|
return data;
|
|
38469
38666
|
}
|
|
@@ -38628,15 +38825,15 @@ var handleSkillCallMessage = (msg, { getWs, log: log2 }) => {
|
|
|
38628
38825
|
};
|
|
38629
38826
|
|
|
38630
38827
|
// src/files/list-dir.ts
|
|
38631
|
-
import
|
|
38632
|
-
import
|
|
38828
|
+
import fs33 from "node:fs";
|
|
38829
|
+
import path36 from "node:path";
|
|
38633
38830
|
|
|
38634
38831
|
// src/files/ensure-under-cwd.ts
|
|
38635
|
-
import
|
|
38832
|
+
import path35 from "node:path";
|
|
38636
38833
|
function ensureUnderCwd(relativePath, cwd = getBridgeRoot()) {
|
|
38637
|
-
const normalized =
|
|
38638
|
-
const resolved =
|
|
38639
|
-
if (!resolved.startsWith(cwd +
|
|
38834
|
+
const normalized = path35.normalize(relativePath).replace(/^(\.\/)+/, "");
|
|
38835
|
+
const resolved = path35.resolve(cwd, normalized);
|
|
38836
|
+
if (!resolved.startsWith(cwd + path35.sep) && resolved !== cwd) {
|
|
38640
38837
|
return null;
|
|
38641
38838
|
}
|
|
38642
38839
|
return resolved;
|
|
@@ -38650,7 +38847,7 @@ async function listDirAsync(relativePath) {
|
|
|
38650
38847
|
return { error: "Path is outside working directory" };
|
|
38651
38848
|
}
|
|
38652
38849
|
try {
|
|
38653
|
-
const names = await
|
|
38850
|
+
const names = await fs33.promises.readdir(resolved, { withFileTypes: true });
|
|
38654
38851
|
const visible = names.filter((d) => !d.name.startsWith("."));
|
|
38655
38852
|
const entries = [];
|
|
38656
38853
|
for (let i = 0; i < visible.length; i++) {
|
|
@@ -38658,12 +38855,12 @@ async function listDirAsync(relativePath) {
|
|
|
38658
38855
|
await yieldToEventLoop();
|
|
38659
38856
|
}
|
|
38660
38857
|
const d = visible[i];
|
|
38661
|
-
const entryPath =
|
|
38662
|
-
const fullPath =
|
|
38858
|
+
const entryPath = path36.join(relativePath || ".", d.name).replace(/\\/g, "/");
|
|
38859
|
+
const fullPath = path36.join(resolved, d.name);
|
|
38663
38860
|
let isDir = d.isDirectory();
|
|
38664
38861
|
if (d.isSymbolicLink()) {
|
|
38665
38862
|
try {
|
|
38666
|
-
const targetStat = await
|
|
38863
|
+
const targetStat = await fs33.promises.stat(fullPath);
|
|
38667
38864
|
isDir = targetStat.isDirectory();
|
|
38668
38865
|
} catch {
|
|
38669
38866
|
isDir = false;
|
|
@@ -38688,25 +38885,25 @@ async function listDirAsync(relativePath) {
|
|
|
38688
38885
|
}
|
|
38689
38886
|
|
|
38690
38887
|
// src/files/read-file.ts
|
|
38691
|
-
import
|
|
38888
|
+
import fs34 from "node:fs";
|
|
38692
38889
|
import { StringDecoder } from "node:string_decoder";
|
|
38693
38890
|
function resolveFilePath(relativePath) {
|
|
38694
38891
|
const resolved = ensureUnderCwd(relativePath, getBridgeRoot());
|
|
38695
38892
|
if (!resolved) return { error: "Path is outside working directory" };
|
|
38696
38893
|
let real;
|
|
38697
38894
|
try {
|
|
38698
|
-
real =
|
|
38895
|
+
real = fs34.realpathSync(resolved);
|
|
38699
38896
|
} catch {
|
|
38700
38897
|
real = resolved;
|
|
38701
38898
|
}
|
|
38702
|
-
const stat3 =
|
|
38899
|
+
const stat3 = fs34.statSync(real);
|
|
38703
38900
|
if (!stat3.isFile()) return { error: "Not a file" };
|
|
38704
38901
|
return real;
|
|
38705
38902
|
}
|
|
38706
38903
|
var LINE_CHUNK_SIZE = 64 * 1024;
|
|
38707
38904
|
function readFileRange(filePath, startLine, endLine, lineOffsetIn, lineChunkSize = LINE_CHUNK_SIZE) {
|
|
38708
|
-
const fileSize =
|
|
38709
|
-
const fd =
|
|
38905
|
+
const fileSize = fs34.statSync(filePath).size;
|
|
38906
|
+
const fd = fs34.openSync(filePath, "r");
|
|
38710
38907
|
const bufSize = 64 * 1024;
|
|
38711
38908
|
const buf = Buffer.alloc(bufSize);
|
|
38712
38909
|
const decoder = new StringDecoder("utf8");
|
|
@@ -38719,7 +38916,7 @@ function readFileRange(filePath, startLine, endLine, lineOffsetIn, lineChunkSize
|
|
|
38719
38916
|
let line0Accum = "";
|
|
38720
38917
|
try {
|
|
38721
38918
|
let bytesRead;
|
|
38722
|
-
while (!done && (bytesRead =
|
|
38919
|
+
while (!done && (bytesRead = fs34.readSync(fd, buf, 0, bufSize, null)) > 0) {
|
|
38723
38920
|
const text = partial2 + decoder.write(buf.subarray(0, bytesRead));
|
|
38724
38921
|
partial2 = "";
|
|
38725
38922
|
let lineStart = 0;
|
|
@@ -38854,7 +39051,7 @@ function readFileRange(filePath, startLine, endLine, lineOffsetIn, lineChunkSize
|
|
|
38854
39051
|
}
|
|
38855
39052
|
return { content: resultLines.join("\n"), size: fileSize };
|
|
38856
39053
|
} finally {
|
|
38857
|
-
|
|
39054
|
+
fs34.closeSync(fd);
|
|
38858
39055
|
}
|
|
38859
39056
|
}
|
|
38860
39057
|
function readFile3(relativePath, startLine, endLine, lineOffset, lineChunkSize = LINE_CHUNK_SIZE) {
|
|
@@ -38865,8 +39062,8 @@ function readFile3(relativePath, startLine, endLine, lineOffset, lineChunkSize =
|
|
|
38865
39062
|
if (hasRange) {
|
|
38866
39063
|
return readFileRange(result, startLine, endLine, lineOffset, lineChunkSize);
|
|
38867
39064
|
}
|
|
38868
|
-
const stat3 =
|
|
38869
|
-
const raw =
|
|
39065
|
+
const stat3 = fs34.statSync(result);
|
|
39066
|
+
const raw = fs34.readFileSync(result, "utf8");
|
|
38870
39067
|
const lines = raw.split(/\r?\n/);
|
|
38871
39068
|
return { content: raw, totalLines: lines.length, size: stat3.size };
|
|
38872
39069
|
} catch (err) {
|
|
@@ -38879,14 +39076,14 @@ async function readFileAsync(relativePath, startLine, endLine, lineOffset, lineC
|
|
|
38879
39076
|
}
|
|
38880
39077
|
|
|
38881
39078
|
// src/files/handle-file-browser-search.ts
|
|
39079
|
+
import path37 from "node:path";
|
|
38882
39080
|
var SEARCH_LIMIT = 100;
|
|
38883
39081
|
function handleFileBrowserSearch(msg, socket, e2ee) {
|
|
38884
39082
|
void (async () => {
|
|
38885
39083
|
await yieldToEventLoop();
|
|
38886
39084
|
const q = typeof msg.q === "string" ? msg.q : "";
|
|
38887
|
-
const cwd = getBridgeRoot();
|
|
38888
|
-
|
|
38889
|
-
if (index === null) {
|
|
39085
|
+
const cwd = path37.resolve(getBridgeRoot());
|
|
39086
|
+
if (!bridgeFileIndexIsPopulated(cwd)) {
|
|
38890
39087
|
const payload2 = {
|
|
38891
39088
|
type: "file_browser_search_response",
|
|
38892
39089
|
id: msg.id,
|
|
@@ -38896,7 +39093,7 @@ function handleFileBrowserSearch(msg, socket, e2ee) {
|
|
|
38896
39093
|
sendWsMessage(socket, e2ee ? e2ee.encryptFields(payload2, ["paths"]) : payload2);
|
|
38897
39094
|
return;
|
|
38898
39095
|
}
|
|
38899
|
-
const results = await
|
|
39096
|
+
const results = await searchBridgeFilePathsAsync(cwd, q, SEARCH_LIMIT);
|
|
38900
39097
|
const payload = {
|
|
38901
39098
|
type: "file_browser_search_response",
|
|
38902
39099
|
id: msg.id,
|
|
@@ -38984,8 +39181,8 @@ function handleSkillLayoutRequest(msg, deps) {
|
|
|
38984
39181
|
}
|
|
38985
39182
|
|
|
38986
39183
|
// src/skills/install-remote-skills.ts
|
|
38987
|
-
import
|
|
38988
|
-
import
|
|
39184
|
+
import fs35 from "node:fs";
|
|
39185
|
+
import path38 from "node:path";
|
|
38989
39186
|
function installRemoteSkills(cwd, targetDir, items) {
|
|
38990
39187
|
const installed2 = [];
|
|
38991
39188
|
if (!Array.isArray(items)) {
|
|
@@ -38996,15 +39193,15 @@ function installRemoteSkills(cwd, targetDir, items) {
|
|
|
38996
39193
|
if (typeof item.sourceId !== "string" || typeof item.skillName !== "string" || typeof item.versionHash !== "string" || !Array.isArray(item.files)) {
|
|
38997
39194
|
continue;
|
|
38998
39195
|
}
|
|
38999
|
-
const skillDir =
|
|
39196
|
+
const skillDir = path38.join(cwd, targetDir, item.skillName);
|
|
39000
39197
|
for (const f of item.files) {
|
|
39001
39198
|
if (typeof f.path !== "string" || !f.text && !f.base64) continue;
|
|
39002
|
-
const dest =
|
|
39003
|
-
|
|
39199
|
+
const dest = path38.join(skillDir, f.path);
|
|
39200
|
+
fs35.mkdirSync(path38.dirname(dest), { recursive: true });
|
|
39004
39201
|
if (f.text !== void 0) {
|
|
39005
|
-
|
|
39202
|
+
fs35.writeFileSync(dest, f.text, "utf8");
|
|
39006
39203
|
} else if (f.base64) {
|
|
39007
|
-
|
|
39204
|
+
fs35.writeFileSync(dest, Buffer.from(f.base64, "base64"));
|
|
39008
39205
|
}
|
|
39009
39206
|
}
|
|
39010
39207
|
installed2.push({
|
|
@@ -39154,7 +39351,7 @@ var handleSessionDiscardedMessage = (msg, deps) => {
|
|
|
39154
39351
|
};
|
|
39155
39352
|
|
|
39156
39353
|
// src/routing/handlers/revert-turn-snapshot.ts
|
|
39157
|
-
import * as
|
|
39354
|
+
import * as fs36 from "node:fs";
|
|
39158
39355
|
var handleRevertTurnSnapshotMessage = (msg, deps) => {
|
|
39159
39356
|
const id = typeof msg.id === "string" ? msg.id : "";
|
|
39160
39357
|
const sessionId = typeof msg.sessionId === "string" ? msg.sessionId : "";
|
|
@@ -39166,7 +39363,7 @@ var handleRevertTurnSnapshotMessage = (msg, deps) => {
|
|
|
39166
39363
|
if (!s) return;
|
|
39167
39364
|
const agentBase = sessionWorktreeManager.getSessionWorktreeRootForSession(sessionId) ?? getBridgeRoot();
|
|
39168
39365
|
const file2 = snapshotFilePath(agentBase, turnId);
|
|
39169
|
-
if (!
|
|
39366
|
+
if (!fs36.existsSync(file2)) {
|
|
39170
39367
|
sendWsMessage(s, {
|
|
39171
39368
|
type: "revert_turn_snapshot_result",
|
|
39172
39369
|
id,
|
|
@@ -39582,6 +39779,7 @@ async function createBridgeConnection(options) {
|
|
|
39582
39779
|
const { apiUrl, workspaceId, justAuthenticated, onAuthInvalid, persistTokens } = options;
|
|
39583
39780
|
const firehoseServerUrl = options.firehoseServerUrl ?? options.proxyServerUrl;
|
|
39584
39781
|
const logFn = options.log ?? log;
|
|
39782
|
+
getCliDatabase({ logLegacyMigration: logFn });
|
|
39585
39783
|
const tokens = {
|
|
39586
39784
|
accessToken: options.authToken,
|
|
39587
39785
|
refreshToken: options.refreshToken
|
|
@@ -39647,8 +39845,8 @@ async function createBridgeConnection(options) {
|
|
|
39647
39845
|
getCloudAccessToken: () => tokens.accessToken
|
|
39648
39846
|
};
|
|
39649
39847
|
const identifyReportedPaths = {
|
|
39650
|
-
bridgeRootPath:
|
|
39651
|
-
worktreesRootPath:
|
|
39848
|
+
bridgeRootPath: path39.resolve(getBridgeRoot()),
|
|
39849
|
+
worktreesRootPath: path39.resolve(worktreesRootPath)
|
|
39652
39850
|
};
|
|
39653
39851
|
const { connect } = createMainBridgeWebSocketLifecycle({
|
|
39654
39852
|
state,
|
|
@@ -39886,9 +40084,9 @@ async function runCliAction(program2, opts) {
|
|
|
39886
40084
|
const firehoseServerUrl = opts.firehoseUrl ?? opts.proxyUrl ?? process.env.BUILDAUTOMATON_FIREHOSE_URL ?? process.env.BUILDAUTOMATON_PROXY_URL ?? DEFAULT_FIREHOSE_URL;
|
|
39887
40085
|
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);
|
|
39888
40086
|
if (bridgeRootOpt) {
|
|
39889
|
-
const resolvedBridgeRoot =
|
|
40087
|
+
const resolvedBridgeRoot = path40.resolve(process.cwd(), bridgeRootOpt);
|
|
39890
40088
|
try {
|
|
39891
|
-
const st =
|
|
40089
|
+
const st = fs37.statSync(resolvedBridgeRoot);
|
|
39892
40090
|
if (!st.isDirectory()) {
|
|
39893
40091
|
console.error(`Bridge root is not a directory: ${resolvedBridgeRoot}`);
|
|
39894
40092
|
process.exit(1);
|
|
@@ -39908,7 +40106,7 @@ async function runCliAction(program2, opts) {
|
|
|
39908
40106
|
);
|
|
39909
40107
|
let worktreesRootPath;
|
|
39910
40108
|
if (opts.worktreesRoot && opts.worktreesRoot.trim()) {
|
|
39911
|
-
worktreesRootPath =
|
|
40109
|
+
worktreesRootPath = path40.resolve(opts.worktreesRoot.trim());
|
|
39912
40110
|
}
|
|
39913
40111
|
const e2eCertificates = opts.e2eeCertificatesDir?.trim() ? await loadOrCreateE2eCertificates(opts.e2eeCertificatesDir.trim()) : void 0;
|
|
39914
40112
|
if (e2eCertificates) {
|