@buildautomaton/cli 0.1.56 → 0.1.57
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 +1467 -1156
- package/dist/cli.js.map +4 -4
- package/dist/index.js +1437 -1126
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -973,8 +973,8 @@ var require_command = __commonJS({
|
|
|
973
973
|
"../../node_modules/.pnpm/commander@12.1.0/node_modules/commander/lib/command.js"(exports) {
|
|
974
974
|
var EventEmitter2 = __require("node:events").EventEmitter;
|
|
975
975
|
var childProcess2 = __require("node:child_process");
|
|
976
|
-
var
|
|
977
|
-
var
|
|
976
|
+
var path75 = __require("node:path");
|
|
977
|
+
var fs53 = __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 = path75.resolve(baseDir, baseName);
|
|
1910
|
+
if (fs53.existsSync(localBin)) return localBin;
|
|
1911
|
+
if (sourceExt.includes(path75.extname(baseName))) return void 0;
|
|
1912
1912
|
const foundExt = sourceExt.find(
|
|
1913
|
-
(ext) =>
|
|
1913
|
+
(ext) => fs53.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 = fs53.realpathSync(this._scriptPath);
|
|
1926
1926
|
} catch (err) {
|
|
1927
1927
|
resolvedScriptPath = this._scriptPath;
|
|
1928
1928
|
}
|
|
1929
|
-
executableDir =
|
|
1930
|
-
|
|
1929
|
+
executableDir = path75.resolve(
|
|
1930
|
+
path75.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 = path75.basename(
|
|
1938
1938
|
this._scriptPath,
|
|
1939
|
-
|
|
1939
|
+
path75.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(path75.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 = path75.basename(filename, path75.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(path76) {
|
|
2805
|
+
if (path76 === void 0) return this._executableDir;
|
|
2806
|
+
this._executableDir = path76;
|
|
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: path75, errorMaps, issueData } = params;
|
|
7065
|
+
const fullPath = [...path75, ...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, path75, key) {
|
|
7374
7374
|
this._cachedPath = [];
|
|
7375
7375
|
this.parent = parent;
|
|
7376
7376
|
this.data = value;
|
|
7377
|
-
this._path =
|
|
7377
|
+
this._path = path75;
|
|
7378
7378
|
this._key = key;
|
|
7379
7379
|
}
|
|
7380
7380
|
get path() {
|
|
@@ -11099,10 +11099,10 @@ function assignProp(target, prop, value) {
|
|
|
11099
11099
|
configurable: true
|
|
11100
11100
|
});
|
|
11101
11101
|
}
|
|
11102
|
-
function getElementAtPath(obj,
|
|
11103
|
-
if (!
|
|
11102
|
+
function getElementAtPath(obj, path75) {
|
|
11103
|
+
if (!path75)
|
|
11104
11104
|
return obj;
|
|
11105
|
-
return
|
|
11105
|
+
return path75.reduce((acc, key) => acc?.[key], obj);
|
|
11106
11106
|
}
|
|
11107
11107
|
function promiseAllObject(promisesObj) {
|
|
11108
11108
|
const keys = Object.keys(promisesObj);
|
|
@@ -11351,11 +11351,11 @@ function aborted(x, startIndex = 0) {
|
|
|
11351
11351
|
}
|
|
11352
11352
|
return false;
|
|
11353
11353
|
}
|
|
11354
|
-
function prefixIssues(
|
|
11354
|
+
function prefixIssues(path75, issues) {
|
|
11355
11355
|
return issues.map((iss) => {
|
|
11356
11356
|
var _a2;
|
|
11357
11357
|
(_a2 = iss).path ?? (_a2.path = []);
|
|
11358
|
-
iss.path.unshift(
|
|
11358
|
+
iss.path.unshift(path75);
|
|
11359
11359
|
return iss;
|
|
11360
11360
|
});
|
|
11361
11361
|
}
|
|
@@ -11544,7 +11544,7 @@ function treeifyError(error40, _mapper) {
|
|
|
11544
11544
|
return issue2.message;
|
|
11545
11545
|
};
|
|
11546
11546
|
const result = { errors: [] };
|
|
11547
|
-
const processError = (error41,
|
|
11547
|
+
const processError = (error41, path75 = []) => {
|
|
11548
11548
|
var _a2, _b;
|
|
11549
11549
|
for (const issue2 of error41.issues) {
|
|
11550
11550
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
@@ -11554,7 +11554,7 @@ function treeifyError(error40, _mapper) {
|
|
|
11554
11554
|
} else if (issue2.code === "invalid_element") {
|
|
11555
11555
|
processError({ issues: issue2.issues }, issue2.path);
|
|
11556
11556
|
} else {
|
|
11557
|
-
const fullpath = [...
|
|
11557
|
+
const fullpath = [...path75, ...issue2.path];
|
|
11558
11558
|
if (fullpath.length === 0) {
|
|
11559
11559
|
result.errors.push(mapper(issue2));
|
|
11560
11560
|
continue;
|
|
@@ -11584,9 +11584,9 @@ function treeifyError(error40, _mapper) {
|
|
|
11584
11584
|
processError(error40);
|
|
11585
11585
|
return result;
|
|
11586
11586
|
}
|
|
11587
|
-
function toDotPath(
|
|
11587
|
+
function toDotPath(path75) {
|
|
11588
11588
|
const segs = [];
|
|
11589
|
-
for (const seg of
|
|
11589
|
+
for (const seg of path75) {
|
|
11590
11590
|
if (typeof seg === "number")
|
|
11591
11591
|
segs.push(`[${seg}]`);
|
|
11592
11592
|
else if (typeof seg === "symbol")
|
|
@@ -24592,7 +24592,7 @@ var require_ignore = __commonJS({
|
|
|
24592
24592
|
// path matching.
|
|
24593
24593
|
// - check `string` either `MODE_IGNORE` or `MODE_CHECK_IGNORE`
|
|
24594
24594
|
// @returns {TestResult} true if a file is ignored
|
|
24595
|
-
test(
|
|
24595
|
+
test(path75, checkUnignored, mode) {
|
|
24596
24596
|
let ignored = false;
|
|
24597
24597
|
let unignored = false;
|
|
24598
24598
|
let matchedRule;
|
|
@@ -24601,7 +24601,7 @@ var require_ignore = __commonJS({
|
|
|
24601
24601
|
if (unignored === negative && ignored !== unignored || negative && !ignored && !unignored && !checkUnignored) {
|
|
24602
24602
|
return;
|
|
24603
24603
|
}
|
|
24604
|
-
const matched = rule[mode].test(
|
|
24604
|
+
const matched = rule[mode].test(path75);
|
|
24605
24605
|
if (!matched) {
|
|
24606
24606
|
return;
|
|
24607
24607
|
}
|
|
@@ -24622,17 +24622,17 @@ var require_ignore = __commonJS({
|
|
|
24622
24622
|
var throwError = (message, Ctor) => {
|
|
24623
24623
|
throw new Ctor(message);
|
|
24624
24624
|
};
|
|
24625
|
-
var checkPath = (
|
|
24626
|
-
if (!isString(
|
|
24625
|
+
var checkPath = (path75, originalPath, doThrow) => {
|
|
24626
|
+
if (!isString(path75)) {
|
|
24627
24627
|
return doThrow(
|
|
24628
24628
|
`path must be a string, but got \`${originalPath}\``,
|
|
24629
24629
|
TypeError
|
|
24630
24630
|
);
|
|
24631
24631
|
}
|
|
24632
|
-
if (!
|
|
24632
|
+
if (!path75) {
|
|
24633
24633
|
return doThrow(`path must not be empty`, TypeError);
|
|
24634
24634
|
}
|
|
24635
|
-
if (checkPath.isNotRelative(
|
|
24635
|
+
if (checkPath.isNotRelative(path75)) {
|
|
24636
24636
|
const r = "`path.relative()`d";
|
|
24637
24637
|
return doThrow(
|
|
24638
24638
|
`path should be a ${r} string, but got "${originalPath}"`,
|
|
@@ -24641,7 +24641,7 @@ var require_ignore = __commonJS({
|
|
|
24641
24641
|
}
|
|
24642
24642
|
return true;
|
|
24643
24643
|
};
|
|
24644
|
-
var isNotRelative = (
|
|
24644
|
+
var isNotRelative = (path75) => REGEX_TEST_INVALID_PATH.test(path75);
|
|
24645
24645
|
checkPath.isNotRelative = isNotRelative;
|
|
24646
24646
|
checkPath.convert = (p) => p;
|
|
24647
24647
|
var Ignore = class {
|
|
@@ -24671,19 +24671,19 @@ var require_ignore = __commonJS({
|
|
|
24671
24671
|
}
|
|
24672
24672
|
// @returns {TestResult}
|
|
24673
24673
|
_test(originalPath, cache2, checkUnignored, slices) {
|
|
24674
|
-
const
|
|
24674
|
+
const path75 = originalPath && checkPath.convert(originalPath);
|
|
24675
24675
|
checkPath(
|
|
24676
|
-
|
|
24676
|
+
path75,
|
|
24677
24677
|
originalPath,
|
|
24678
24678
|
this._strictPathCheck ? throwError : RETURN_FALSE
|
|
24679
24679
|
);
|
|
24680
|
-
return this._t(
|
|
24680
|
+
return this._t(path75, cache2, checkUnignored, slices);
|
|
24681
24681
|
}
|
|
24682
|
-
checkIgnore(
|
|
24683
|
-
if (!REGEX_TEST_TRAILING_SLASH.test(
|
|
24684
|
-
return this.test(
|
|
24682
|
+
checkIgnore(path75) {
|
|
24683
|
+
if (!REGEX_TEST_TRAILING_SLASH.test(path75)) {
|
|
24684
|
+
return this.test(path75);
|
|
24685
24685
|
}
|
|
24686
|
-
const slices =
|
|
24686
|
+
const slices = path75.split(SLASH).filter(Boolean);
|
|
24687
24687
|
slices.pop();
|
|
24688
24688
|
if (slices.length) {
|
|
24689
24689
|
const parent = this._t(
|
|
@@ -24696,18 +24696,18 @@ var require_ignore = __commonJS({
|
|
|
24696
24696
|
return parent;
|
|
24697
24697
|
}
|
|
24698
24698
|
}
|
|
24699
|
-
return this._rules.test(
|
|
24699
|
+
return this._rules.test(path75, false, MODE_CHECK_IGNORE);
|
|
24700
24700
|
}
|
|
24701
|
-
_t(
|
|
24702
|
-
if (
|
|
24703
|
-
return cache2[
|
|
24701
|
+
_t(path75, cache2, checkUnignored, slices) {
|
|
24702
|
+
if (path75 in cache2) {
|
|
24703
|
+
return cache2[path75];
|
|
24704
24704
|
}
|
|
24705
24705
|
if (!slices) {
|
|
24706
|
-
slices =
|
|
24706
|
+
slices = path75.split(SLASH).filter(Boolean);
|
|
24707
24707
|
}
|
|
24708
24708
|
slices.pop();
|
|
24709
24709
|
if (!slices.length) {
|
|
24710
|
-
return cache2[
|
|
24710
|
+
return cache2[path75] = this._rules.test(path75, checkUnignored, MODE_IGNORE);
|
|
24711
24711
|
}
|
|
24712
24712
|
const parent = this._t(
|
|
24713
24713
|
slices.join(SLASH) + SLASH,
|
|
@@ -24715,29 +24715,29 @@ var require_ignore = __commonJS({
|
|
|
24715
24715
|
checkUnignored,
|
|
24716
24716
|
slices
|
|
24717
24717
|
);
|
|
24718
|
-
return cache2[
|
|
24718
|
+
return cache2[path75] = parent.ignored ? parent : this._rules.test(path75, checkUnignored, MODE_IGNORE);
|
|
24719
24719
|
}
|
|
24720
|
-
ignores(
|
|
24721
|
-
return this._test(
|
|
24720
|
+
ignores(path75) {
|
|
24721
|
+
return this._test(path75, this._ignoreCache, false).ignored;
|
|
24722
24722
|
}
|
|
24723
24723
|
createFilter() {
|
|
24724
|
-
return (
|
|
24724
|
+
return (path75) => !this.ignores(path75);
|
|
24725
24725
|
}
|
|
24726
24726
|
filter(paths) {
|
|
24727
24727
|
return makeArray(paths).filter(this.createFilter());
|
|
24728
24728
|
}
|
|
24729
24729
|
// @returns {TestResult}
|
|
24730
|
-
test(
|
|
24731
|
-
return this._test(
|
|
24730
|
+
test(path75) {
|
|
24731
|
+
return this._test(path75, this._testCache, true);
|
|
24732
24732
|
}
|
|
24733
24733
|
};
|
|
24734
24734
|
var factory = (options) => new Ignore(options);
|
|
24735
|
-
var isPathValid = (
|
|
24735
|
+
var isPathValid = (path75) => checkPath(path75 && checkPath.convert(path75), path75, RETURN_FALSE);
|
|
24736
24736
|
var setupWindows = () => {
|
|
24737
24737
|
const makePosix = (str) => /^\\\\\?\\/.test(str) || /["<>|\u0000-\u001F]+/u.test(str) ? str : str.replace(/\\/g, "/");
|
|
24738
24738
|
checkPath.convert = makePosix;
|
|
24739
24739
|
const REGEX_TEST_WINDOWS_PATH_ABSOLUTE = /^[a-z]:\//i;
|
|
24740
|
-
checkPath.isNotRelative = (
|
|
24740
|
+
checkPath.isNotRelative = (path75) => REGEX_TEST_WINDOWS_PATH_ABSOLUTE.test(path75) || isNotRelative(path75);
|
|
24741
24741
|
};
|
|
24742
24742
|
if (
|
|
24743
24743
|
// Detect `process` so that it can run in browsers.
|
|
@@ -25526,10 +25526,10 @@ var require_src2 = __commonJS({
|
|
|
25526
25526
|
var fs_1 = __require("fs");
|
|
25527
25527
|
var debug_1 = __importDefault(require_src());
|
|
25528
25528
|
var log2 = debug_1.default("@kwsites/file-exists");
|
|
25529
|
-
function check2(
|
|
25530
|
-
log2(`checking %s`,
|
|
25529
|
+
function check2(path75, isFile, isDirectory) {
|
|
25530
|
+
log2(`checking %s`, path75);
|
|
25531
25531
|
try {
|
|
25532
|
-
const stat3 = fs_1.statSync(
|
|
25532
|
+
const stat3 = fs_1.statSync(path75);
|
|
25533
25533
|
if (stat3.isFile() && isFile) {
|
|
25534
25534
|
log2(`[OK] path represents a file`);
|
|
25535
25535
|
return true;
|
|
@@ -25549,8 +25549,8 @@ var require_src2 = __commonJS({
|
|
|
25549
25549
|
throw e;
|
|
25550
25550
|
}
|
|
25551
25551
|
}
|
|
25552
|
-
function exists2(
|
|
25553
|
-
return check2(
|
|
25552
|
+
function exists2(path75, type = exports.READABLE) {
|
|
25553
|
+
return check2(path75, (type & exports.FILE) > 0, (type & exports.FOLDER) > 0);
|
|
25554
25554
|
}
|
|
25555
25555
|
exports.exists = exists2;
|
|
25556
25556
|
exports.FILE = 1;
|
|
@@ -25631,15 +25631,15 @@ var {
|
|
|
25631
25631
|
} = import_index.default;
|
|
25632
25632
|
|
|
25633
25633
|
// src/cli-version.ts
|
|
25634
|
-
var CLI_VERSION = "0.1.
|
|
25634
|
+
var CLI_VERSION = "0.1.57".length > 0 ? "0.1.57" : "0.0.0-dev";
|
|
25635
25635
|
|
|
25636
25636
|
// src/cli/defaults.ts
|
|
25637
25637
|
var DEFAULT_API_URL = process.env.BUILDAUTOMATON_API_URL ?? "https://api.buildautomaton.com";
|
|
25638
25638
|
var DEFAULT_FIREHOSE_URL = "https://buildautomaton-firehose.fly.dev";
|
|
25639
25639
|
|
|
25640
25640
|
// src/cli/run-cli-action.ts
|
|
25641
|
-
import * as
|
|
25642
|
-
import * as
|
|
25641
|
+
import * as fs52 from "node:fs";
|
|
25642
|
+
import * as path74 from "node:path";
|
|
25643
25643
|
|
|
25644
25644
|
// src/cli-log-level.ts
|
|
25645
25645
|
var verbosity = "info";
|
|
@@ -27183,7 +27183,7 @@ function clearMainBridgeReconnectQuietOnOpen(state, log2) {
|
|
|
27183
27183
|
function scheduleMainBridgeReconnect(state, connect, log2, closeMeta) {
|
|
27184
27184
|
if (state.closedByUser || state.currentWs != null) return;
|
|
27185
27185
|
const meta = closeMeta ?? state.lastReconnectCloseMeta ?? void 0;
|
|
27186
|
-
const
|
|
27186
|
+
const delay3 = applyTieredReconnectPlanAndLog(
|
|
27187
27187
|
state.mainOutage,
|
|
27188
27188
|
log2,
|
|
27189
27189
|
BRIDGE_SERVICE_LABEL,
|
|
@@ -27192,7 +27192,7 @@ function scheduleMainBridgeReconnect(state, connect, log2, closeMeta) {
|
|
|
27192
27192
|
meta?.reason
|
|
27193
27193
|
);
|
|
27194
27194
|
armReconnectDelayTimer({
|
|
27195
|
-
delayMs:
|
|
27195
|
+
delayMs: delay3,
|
|
27196
27196
|
bumpAttempt: () => {
|
|
27197
27197
|
state.reconnectAttempt += 1;
|
|
27198
27198
|
},
|
|
@@ -27394,10 +27394,10 @@ function runPendingAuth(options) {
|
|
|
27394
27394
|
}
|
|
27395
27395
|
if (resolved) return;
|
|
27396
27396
|
beginDeferredPendingCloseLog(code, reason);
|
|
27397
|
-
const
|
|
27397
|
+
const delay3 = pendingAuthReconnectDelayMs(reconnectAttempt);
|
|
27398
27398
|
reconnectAttempt += 1;
|
|
27399
27399
|
if (signInQuiet.verboseLogs) {
|
|
27400
|
-
const delayLabel = formatReconnectDelayForLog(
|
|
27400
|
+
const delayLabel = formatReconnectDelayForLog(delay3);
|
|
27401
27401
|
logFn(
|
|
27402
27402
|
`[Bridge service] Next sign-in connection attempt in ${delayLabel} (attempt ${reconnectAttempt}).`
|
|
27403
27403
|
);
|
|
@@ -27405,7 +27405,7 @@ function runPendingAuth(options) {
|
|
|
27405
27405
|
reconnectTimeout = setTimeout(() => {
|
|
27406
27406
|
reconnectTimeout = null;
|
|
27407
27407
|
connect();
|
|
27408
|
-
},
|
|
27408
|
+
}, delay3);
|
|
27409
27409
|
},
|
|
27410
27410
|
onError: (err) => logCliWebSocketError(logFn, "[Bridge service]", err, "while waiting for sign-in"),
|
|
27411
27411
|
onMessage: (data) => {
|
|
@@ -27499,11 +27499,7 @@ function isCliSqliteLockError(e) {
|
|
|
27499
27499
|
return lower.includes("database is locked") || lower.includes("sqlite_busy") || lower.includes("sqlite3_busy") || lower.includes("database") && lower.includes("locked");
|
|
27500
27500
|
}
|
|
27501
27501
|
|
|
27502
|
-
// src/sqlite/
|
|
27503
|
-
var { Database: SqliteDatabase } = sqliteWasm;
|
|
27504
|
-
var SYNC_RETRY_MAX = 40;
|
|
27505
|
-
var ASYNC_RETRY_MAX = 60;
|
|
27506
|
-
var ASYNC_BASE_DELAY_MS = 20;
|
|
27502
|
+
// src/sqlite/sqlite-pragmas.ts
|
|
27507
27503
|
function applySqliteConcurrencyPragmas(db) {
|
|
27508
27504
|
try {
|
|
27509
27505
|
db.run("PRAGMA foreign_keys = ON");
|
|
@@ -27529,12 +27525,17 @@ function applySqliteMemoryPragmas(db) {
|
|
|
27529
27525
|
} catch {
|
|
27530
27526
|
}
|
|
27531
27527
|
}
|
|
27528
|
+
|
|
27529
|
+
// src/sqlite/sqlite-lock-retry.ts
|
|
27530
|
+
var SYNC_RETRY_MAX = 40;
|
|
27531
|
+
var ASYNC_RETRY_MAX = 60;
|
|
27532
|
+
var ASYNC_BASE_DELAY_MS = 20;
|
|
27532
27533
|
function syncSleepMs(ms) {
|
|
27533
27534
|
if (ms <= 0) return;
|
|
27534
27535
|
const deadline = Date.now() + ms;
|
|
27535
27536
|
while (Date.now() < deadline) {
|
|
27536
27537
|
if (isCliImmediateShutdownRequested()) throw new CliSqliteInterrupted();
|
|
27537
|
-
const chunk = Math.min(
|
|
27538
|
+
const chunk = Math.min(10, deadline - Date.now());
|
|
27538
27539
|
if (chunk <= 0) break;
|
|
27539
27540
|
try {
|
|
27540
27541
|
const sab = new SharedArrayBuffer(4);
|
|
@@ -27558,7 +27559,22 @@ async function asyncDelayMsInterruptible(ms) {
|
|
|
27558
27559
|
await yieldToEventLoop();
|
|
27559
27560
|
}
|
|
27560
27561
|
}
|
|
27562
|
+
|
|
27563
|
+
// src/sqlite/create-sqlite-database-access.ts
|
|
27564
|
+
var { Database: SqliteDatabase } = sqliteWasm;
|
|
27561
27565
|
function createSqliteDatabaseAccess(config2) {
|
|
27566
|
+
let migrateDoneForPath = null;
|
|
27567
|
+
function shouldSkipMigrate(sqlitePath, db) {
|
|
27568
|
+
if (migrateDoneForPath !== sqlitePath) return false;
|
|
27569
|
+
try {
|
|
27570
|
+
const row = db.get(
|
|
27571
|
+
"SELECT 1 as ok FROM sqlite_master WHERE type='table' AND name='__migrations' LIMIT 1"
|
|
27572
|
+
);
|
|
27573
|
+
return row != null;
|
|
27574
|
+
} catch {
|
|
27575
|
+
return false;
|
|
27576
|
+
}
|
|
27577
|
+
}
|
|
27562
27578
|
function safeClose(db) {
|
|
27563
27579
|
if (db == null) return;
|
|
27564
27580
|
try {
|
|
@@ -27574,7 +27590,11 @@ function createSqliteDatabaseAccess(config2) {
|
|
|
27574
27590
|
try {
|
|
27575
27591
|
applySqliteConcurrencyPragmas(db);
|
|
27576
27592
|
applySqliteMemoryPragmas(db);
|
|
27577
|
-
config2.
|
|
27593
|
+
const sqlitePath2 = config2.getPath();
|
|
27594
|
+
if (!shouldSkipMigrate(sqlitePath2, db)) {
|
|
27595
|
+
config2.migrate(db);
|
|
27596
|
+
migrateDoneForPath = sqlitePath2;
|
|
27597
|
+
}
|
|
27578
27598
|
config2.afterOpen?.(db, options);
|
|
27579
27599
|
} catch (e) {
|
|
27580
27600
|
safeClose(db);
|
|
@@ -27630,14 +27650,16 @@ function createSqliteDatabaseAccess(config2) {
|
|
|
27630
27650
|
async function ensureInitialized(options) {
|
|
27631
27651
|
await withAsync(() => void 0, options);
|
|
27632
27652
|
}
|
|
27653
|
+
function closeAllConnections() {
|
|
27654
|
+
migrateDoneForPath = null;
|
|
27655
|
+
}
|
|
27633
27656
|
return {
|
|
27634
27657
|
safeClose,
|
|
27635
27658
|
openConnection,
|
|
27636
27659
|
withSync,
|
|
27637
27660
|
withAsync,
|
|
27638
27661
|
ensureInitialized,
|
|
27639
|
-
closeAllConnections
|
|
27640
|
-
}
|
|
27662
|
+
closeAllConnections
|
|
27641
27663
|
};
|
|
27642
27664
|
}
|
|
27643
27665
|
|
|
@@ -27837,7 +27859,7 @@ function readMigrationSql(filename, ...searchSubdirs) {
|
|
|
27837
27859
|
join2(moduleDir, "..", sub, filename),
|
|
27838
27860
|
join2(moduleDir, "..", "..", "dist", sub, filename)
|
|
27839
27861
|
]);
|
|
27840
|
-
const resolved = candidates.find((
|
|
27862
|
+
const resolved = candidates.find((path75) => existsSync(path75));
|
|
27841
27863
|
if (!resolved) {
|
|
27842
27864
|
throw new Error(`Missing SQLite migration SQL: ${filename} (searched ${searchSubdirs.join(", ")})`);
|
|
27843
27865
|
}
|
|
@@ -27969,6 +27991,161 @@ var withCliSqliteSync = cliSqlite.withSync;
|
|
|
27969
27991
|
var withCliSqlite = cliSqlite.withAsync;
|
|
27970
27992
|
var ensureCliSqliteInitialized = cliSqlite.ensureInitialized;
|
|
27971
27993
|
|
|
27994
|
+
// src/sqlite/code-nav-cache/code-nav-cache-paths.ts
|
|
27995
|
+
import fs15 from "node:fs";
|
|
27996
|
+
import path12 from "node:path";
|
|
27997
|
+
import os7 from "node:os";
|
|
27998
|
+
function getCodeNavCacheSqlitePath() {
|
|
27999
|
+
const override = process.env.BUILDAMATON_CODE_NAV_CACHE_SQLITE_PATH?.trim();
|
|
28000
|
+
if (override) return path12.resolve(override);
|
|
28001
|
+
return path12.join(os7.homedir(), ".buildautomaton", "code-nav-cache.sqlite");
|
|
28002
|
+
}
|
|
28003
|
+
function ensureCodeNavCacheSqliteParentDir(sqlitePath) {
|
|
28004
|
+
const dir = path12.dirname(sqlitePath);
|
|
28005
|
+
if (!fs15.existsSync(dir)) fs15.mkdirSync(dir, { recursive: true });
|
|
28006
|
+
}
|
|
28007
|
+
|
|
28008
|
+
// src/sqlite/code-nav-cache/migrate-code-nav-cache-sqlite.ts
|
|
28009
|
+
var CHECKPOINT_V12 = "001_code_nav_cache_checkpoint_v1";
|
|
28010
|
+
var CHECKPOINT_V1_SQL2 = readCodeNavCacheMigrationSql("001_code_nav_cache_checkpoint_v1.sql");
|
|
28011
|
+
var MIGRATION_002 = "002_content_hash_symbol_index";
|
|
28012
|
+
var MIGRATION_002_SQL = readCodeNavCacheMigrationSql("002_content_hash_symbol_index.sql");
|
|
28013
|
+
var MIGRATION_003 = "003_content_hash_tag_rows";
|
|
28014
|
+
var MIGRATION_003_SQL = readCodeNavCacheMigrationSql("003_content_hash_tag_rows.sql");
|
|
28015
|
+
var CODE_NAV_CACHE_SQLITE_MIGRATIONS = [
|
|
28016
|
+
{
|
|
28017
|
+
name: CHECKPOINT_V12,
|
|
28018
|
+
checkpoint: true,
|
|
28019
|
+
migrate: (db) => {
|
|
28020
|
+
db.exec(CHECKPOINT_V1_SQL2);
|
|
28021
|
+
},
|
|
28022
|
+
alreadyApplied: (db) => {
|
|
28023
|
+
const row = db.get(
|
|
28024
|
+
`SELECT 1 as ok FROM sqlite_master WHERE type='table' AND name='file_index_parent_path' LIMIT 1`
|
|
28025
|
+
);
|
|
28026
|
+
return row != null;
|
|
28027
|
+
}
|
|
28028
|
+
},
|
|
28029
|
+
{
|
|
28030
|
+
name: MIGRATION_002,
|
|
28031
|
+
migrate: (db) => {
|
|
28032
|
+
db.exec(MIGRATION_002_SQL);
|
|
28033
|
+
},
|
|
28034
|
+
alreadyApplied: (db) => {
|
|
28035
|
+
const row = db.get(
|
|
28036
|
+
`SELECT 1 as ok FROM sqlite_master WHERE type='table' AND name='symbol_file_blob' LIMIT 1`
|
|
28037
|
+
);
|
|
28038
|
+
return row != null;
|
|
28039
|
+
}
|
|
28040
|
+
},
|
|
28041
|
+
{
|
|
28042
|
+
name: MIGRATION_003,
|
|
28043
|
+
migrate: (db) => {
|
|
28044
|
+
db.exec(MIGRATION_003_SQL);
|
|
28045
|
+
},
|
|
28046
|
+
alreadyApplied: (db) => {
|
|
28047
|
+
const row = db.get(
|
|
28048
|
+
`SELECT 1 as ok FROM sqlite_master WHERE type='table' AND name='symbol_index_tag' LIMIT 1`
|
|
28049
|
+
);
|
|
28050
|
+
if (row == null) return false;
|
|
28051
|
+
const blob = db.get(
|
|
28052
|
+
`SELECT 1 as ok FROM sqlite_master WHERE type='table' AND name='symbol_file_blob' LIMIT 1`
|
|
28053
|
+
);
|
|
28054
|
+
return blob == null;
|
|
28055
|
+
}
|
|
28056
|
+
}
|
|
28057
|
+
];
|
|
28058
|
+
function migrateCodeNavCacheSqlite(db) {
|
|
28059
|
+
runSqliteMigrations(
|
|
28060
|
+
db,
|
|
28061
|
+
CODE_NAV_CACHE_SQLITE_MIGRATIONS,
|
|
28062
|
+
readCodeNavCacheMigrationSql("000_bootstrap_migrations_table.sql"),
|
|
28063
|
+
"code-nav-cache"
|
|
28064
|
+
);
|
|
28065
|
+
}
|
|
28066
|
+
|
|
28067
|
+
// src/sqlite/code-nav-cache/code-nav-cache-sqlite-work-lock.ts
|
|
28068
|
+
import fs16 from "node:fs";
|
|
28069
|
+
function isSqliteCorruptError(e) {
|
|
28070
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
28071
|
+
return msg.includes("malformed") || msg.includes("database disk image is malformed") || msg.includes("corrupt");
|
|
28072
|
+
}
|
|
28073
|
+
var chain = Promise.resolve();
|
|
28074
|
+
var workLockDepth = 0;
|
|
28075
|
+
function resetCodeNavCacheSqliteWorkLock() {
|
|
28076
|
+
chain = Promise.resolve();
|
|
28077
|
+
workLockDepth = 0;
|
|
28078
|
+
}
|
|
28079
|
+
function withCodeNavCacheSqliteWorkLock(fn) {
|
|
28080
|
+
if (workLockDepth > 0) {
|
|
28081
|
+
return Promise.resolve(fn());
|
|
28082
|
+
}
|
|
28083
|
+
const run = async () => {
|
|
28084
|
+
workLockDepth += 1;
|
|
28085
|
+
try {
|
|
28086
|
+
return await Promise.resolve(fn());
|
|
28087
|
+
} finally {
|
|
28088
|
+
workLockDepth = Math.max(0, workLockDepth - 1);
|
|
28089
|
+
}
|
|
28090
|
+
};
|
|
28091
|
+
const runWithCorruptRecovery = async () => {
|
|
28092
|
+
try {
|
|
28093
|
+
return await run();
|
|
28094
|
+
} catch (e) {
|
|
28095
|
+
if (!isSqliteCorruptError(e)) throw e;
|
|
28096
|
+
try {
|
|
28097
|
+
fs16.unlinkSync(getCodeNavCacheSqlitePath());
|
|
28098
|
+
} catch {
|
|
28099
|
+
}
|
|
28100
|
+
chain = Promise.resolve();
|
|
28101
|
+
return await run();
|
|
28102
|
+
}
|
|
28103
|
+
};
|
|
28104
|
+
const next = chain.then(runWithCorruptRecovery);
|
|
28105
|
+
chain = next.then(
|
|
28106
|
+
() => void 0,
|
|
28107
|
+
() => void 0
|
|
28108
|
+
);
|
|
28109
|
+
return next;
|
|
28110
|
+
}
|
|
28111
|
+
|
|
28112
|
+
// src/sqlite/code-nav-cache/code-nav-cache-database.ts
|
|
28113
|
+
var codeNavCacheSqlite = createSqliteDatabaseAccess({
|
|
28114
|
+
getPath: getCodeNavCacheSqlitePath,
|
|
28115
|
+
ensureParentDir: ensureCodeNavCacheSqliteParentDir,
|
|
28116
|
+
migrate: migrateCodeNavCacheSqlite
|
|
28117
|
+
});
|
|
28118
|
+
var codeNavCacheAccessDepth = 0;
|
|
28119
|
+
async function waitForOuterCodeNavCacheAccessAsync() {
|
|
28120
|
+
while (codeNavCacheAccessDepth > 0) {
|
|
28121
|
+
if (isCliImmediateShutdownRequested()) throw new CliSqliteInterrupted();
|
|
28122
|
+
await new Promise((resolve34) => setTimeout(resolve34, 5));
|
|
28123
|
+
await yieldToEventLoop();
|
|
28124
|
+
}
|
|
28125
|
+
}
|
|
28126
|
+
var safeCloseCodeNavCacheSqliteDatabase = codeNavCacheSqlite.safeClose;
|
|
28127
|
+
function closeAllCodeNavCacheSqliteConnections() {
|
|
28128
|
+
codeNavCacheSqlite.closeAllConnections();
|
|
28129
|
+
resetCodeNavCacheSqliteWorkLock();
|
|
28130
|
+
codeNavCacheAccessDepth = 0;
|
|
28131
|
+
}
|
|
28132
|
+
var openCodeNavCacheSqliteConnection = codeNavCacheSqlite.openConnection;
|
|
28133
|
+
async function withCodeNavCacheSqlite(fn) {
|
|
28134
|
+
return withCodeNavCacheSqliteWorkLock(async () => {
|
|
28135
|
+
const nested = codeNavCacheAccessDepth > 0;
|
|
28136
|
+
if (!nested) await waitForOuterCodeNavCacheAccessAsync();
|
|
28137
|
+
codeNavCacheAccessDepth += 1;
|
|
28138
|
+
try {
|
|
28139
|
+
return await codeNavCacheSqlite.withAsync(fn);
|
|
28140
|
+
} finally {
|
|
28141
|
+
codeNavCacheAccessDepth = Math.max(0, codeNavCacheAccessDepth - 1);
|
|
28142
|
+
}
|
|
28143
|
+
});
|
|
28144
|
+
}
|
|
28145
|
+
async function ensureCodeNavCacheSqliteInitialized() {
|
|
28146
|
+
await withCodeNavCacheSqlite(() => void 0);
|
|
28147
|
+
}
|
|
28148
|
+
|
|
27972
28149
|
// src/connection/close-bridge-connection.ts
|
|
27973
28150
|
async function closeBridgeConnection(state, acpManager, devServerManager, log2) {
|
|
27974
28151
|
requestCliImmediateShutdown();
|
|
@@ -28014,6 +28191,7 @@ async function closeBridgeConnection(state, acpManager, devServerManager, log2)
|
|
|
28014
28191
|
}
|
|
28015
28192
|
try {
|
|
28016
28193
|
closeAllCliSqliteConnections();
|
|
28194
|
+
closeAllCodeNavCacheSqliteConnections();
|
|
28017
28195
|
} catch {
|
|
28018
28196
|
}
|
|
28019
28197
|
say("Shutdown complete.");
|
|
@@ -28635,9 +28813,9 @@ function parseChangeSummaryJson(raw, allowedPaths, options) {
|
|
|
28635
28813
|
const rawPath = typeof o.path === "string" ? o.path.trim() : "";
|
|
28636
28814
|
const summary = typeof o.summary === "string" ? o.summary.trim() : "";
|
|
28637
28815
|
if (!rawPath || !summary) continue;
|
|
28638
|
-
const
|
|
28639
|
-
if (!
|
|
28640
|
-
rows.push({ path:
|
|
28816
|
+
const path75 = skip ? normalizeRepoRelativePath(rawPath) || rawPath : resolveChangeSummaryPathAgainstAllowed(rawPath, allowedPaths);
|
|
28817
|
+
if (!path75) continue;
|
|
28818
|
+
rows.push({ path: path75, summary: clampSummaryToAtMostTwoLines(summary) });
|
|
28641
28819
|
}
|
|
28642
28820
|
return rows;
|
|
28643
28821
|
}
|
|
@@ -28991,16 +29169,16 @@ function getAgentModelFromAgentConfig(config2) {
|
|
|
28991
29169
|
}
|
|
28992
29170
|
|
|
28993
29171
|
// src/paths/session-layout-paths.ts
|
|
28994
|
-
import * as
|
|
29172
|
+
import * as path13 from "node:path";
|
|
28995
29173
|
function resolveIsolatedSessionParentPathFromCheckouts(worktreePaths) {
|
|
28996
|
-
const resolved = worktreePaths.map((p) =>
|
|
29174
|
+
const resolved = worktreePaths.map((p) => path13.resolve(p)).filter(Boolean);
|
|
28997
29175
|
if (resolved.length === 0) return null;
|
|
28998
29176
|
resolved.sort();
|
|
28999
29177
|
return resolved[0];
|
|
29000
29178
|
}
|
|
29001
29179
|
function resolveSessionParentPathForAgentProcess(resolvedSessionParentPath) {
|
|
29002
29180
|
if (resolvedSessionParentPath != null && String(resolvedSessionParentPath).trim() !== "") {
|
|
29003
|
-
return
|
|
29181
|
+
return path13.resolve(String(resolvedSessionParentPath).trim());
|
|
29004
29182
|
}
|
|
29005
29183
|
return getBridgeRoot();
|
|
29006
29184
|
}
|
|
@@ -29345,21 +29523,21 @@ import { mkdirSync, readFileSync as readFileSync2, writeFileSync } from "node:fs
|
|
|
29345
29523
|
import { dirname as dirname3 } from "node:path";
|
|
29346
29524
|
|
|
29347
29525
|
// src/agents/acp/safe-fs-path.ts
|
|
29348
|
-
import * as
|
|
29526
|
+
import * as path14 from "node:path";
|
|
29349
29527
|
function resolveSafePathUnderCwd(cwd, filePath) {
|
|
29350
29528
|
const trimmed2 = filePath.trim();
|
|
29351
29529
|
if (!trimmed2) return null;
|
|
29352
|
-
const normalizedCwd =
|
|
29353
|
-
const resolved =
|
|
29354
|
-
const rel =
|
|
29355
|
-
if (rel.startsWith("..") ||
|
|
29530
|
+
const normalizedCwd = path14.resolve(cwd);
|
|
29531
|
+
const resolved = path14.isAbsolute(trimmed2) ? path14.normalize(trimmed2) : path14.resolve(normalizedCwd, trimmed2);
|
|
29532
|
+
const rel = path14.relative(normalizedCwd, resolved);
|
|
29533
|
+
if (rel.startsWith("..") || path14.isAbsolute(rel)) return null;
|
|
29356
29534
|
return resolved;
|
|
29357
29535
|
}
|
|
29358
29536
|
function toDisplayPathRelativeToCwd(cwd, absolutePath) {
|
|
29359
|
-
const normalizedCwd =
|
|
29360
|
-
const rel =
|
|
29361
|
-
if (!rel || rel === "") return
|
|
29362
|
-
return rel.split(
|
|
29537
|
+
const normalizedCwd = path14.resolve(cwd);
|
|
29538
|
+
const rel = path14.relative(normalizedCwd, path14.resolve(absolutePath));
|
|
29539
|
+
if (!rel || rel === "") return path14.basename(absolutePath);
|
|
29540
|
+
return rel.split(path14.sep).join("/");
|
|
29363
29541
|
}
|
|
29364
29542
|
|
|
29365
29543
|
// src/agents/acp/clients/shared/acp-fs-read-write.ts
|
|
@@ -30762,16 +30940,16 @@ import { existsSync as existsSync2, statSync } from "node:fs";
|
|
|
30762
30940
|
|
|
30763
30941
|
// src/git/get-git-repo-root-sync.ts
|
|
30764
30942
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
30765
|
-
import * as
|
|
30943
|
+
import * as path15 from "node:path";
|
|
30766
30944
|
function getGitRepoRootSync(startDir) {
|
|
30767
30945
|
try {
|
|
30768
30946
|
const out = execFileSync2("git", ["rev-parse", "--show-toplevel"], {
|
|
30769
|
-
cwd:
|
|
30947
|
+
cwd: path15.resolve(startDir),
|
|
30770
30948
|
encoding: "utf8",
|
|
30771
30949
|
stdio: ["ignore", "pipe", "ignore"],
|
|
30772
30950
|
maxBuffer: 1024 * 1024
|
|
30773
30951
|
}).trim();
|
|
30774
|
-
return out ?
|
|
30952
|
+
return out ? path15.resolve(out) : null;
|
|
30775
30953
|
} catch {
|
|
30776
30954
|
return null;
|
|
30777
30955
|
}
|
|
@@ -30780,25 +30958,25 @@ function getGitRepoRootSync(startDir) {
|
|
|
30780
30958
|
// src/agents/acp/workspace-files.ts
|
|
30781
30959
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
30782
30960
|
import { readFileSync as readFileSync3 } from "node:fs";
|
|
30783
|
-
import * as
|
|
30961
|
+
import * as path16 from "node:path";
|
|
30784
30962
|
function resolveWorkspaceFilePath(sessionParentPath, rawPath) {
|
|
30785
30963
|
const trimmed2 = rawPath.trim();
|
|
30786
30964
|
if (!trimmed2) return null;
|
|
30787
|
-
const normalizedSessionParent =
|
|
30965
|
+
const normalizedSessionParent = path16.resolve(sessionParentPath);
|
|
30788
30966
|
let resolvedPath = resolveSafePathUnderCwd(sessionParentPath, trimmed2);
|
|
30789
30967
|
if (!resolvedPath) {
|
|
30790
|
-
const candidate =
|
|
30968
|
+
const candidate = path16.isAbsolute(trimmed2) ? path16.normalize(trimmed2) : path16.normalize(path16.resolve(normalizedSessionParent, trimmed2));
|
|
30791
30969
|
const gitRoot2 = getGitRepoRootSync(sessionParentPath);
|
|
30792
30970
|
if (!gitRoot2) return null;
|
|
30793
|
-
const rel =
|
|
30794
|
-
if (rel.startsWith("..") ||
|
|
30971
|
+
const rel = path16.relative(gitRoot2, candidate);
|
|
30972
|
+
if (rel.startsWith("..") || path16.isAbsolute(rel)) return null;
|
|
30795
30973
|
resolvedPath = candidate;
|
|
30796
30974
|
}
|
|
30797
30975
|
const gitRoot = getGitRepoRootSync(sessionParentPath);
|
|
30798
30976
|
if (gitRoot) {
|
|
30799
|
-
const relFromRoot =
|
|
30800
|
-
if (!relFromRoot.startsWith("..") && !
|
|
30801
|
-
return { resolvedPath, display: relFromRoot.split(
|
|
30977
|
+
const relFromRoot = path16.relative(gitRoot, resolvedPath);
|
|
30978
|
+
if (!relFromRoot.startsWith("..") && !path16.isAbsolute(relFromRoot)) {
|
|
30979
|
+
return { resolvedPath, display: relFromRoot.split(path16.sep).join("/") };
|
|
30802
30980
|
}
|
|
30803
30981
|
}
|
|
30804
30982
|
return { resolvedPath, display: toDisplayPathRelativeToCwd(sessionParentPath, resolvedPath) };
|
|
@@ -30807,9 +30985,9 @@ function readUtf8WorkspaceFile(sessionParentPath, displayPath) {
|
|
|
30807
30985
|
if (!displayPath || displayPath.includes("..")) return "";
|
|
30808
30986
|
const gitRoot = getGitRepoRootSync(sessionParentPath);
|
|
30809
30987
|
if (gitRoot) {
|
|
30810
|
-
const resolvedPath2 =
|
|
30811
|
-
const rel =
|
|
30812
|
-
if (!rel.startsWith("..") && !
|
|
30988
|
+
const resolvedPath2 = path16.resolve(gitRoot, displayPath);
|
|
30989
|
+
const rel = path16.relative(gitRoot, resolvedPath2);
|
|
30990
|
+
if (!rel.startsWith("..") && !path16.isAbsolute(rel)) {
|
|
30813
30991
|
try {
|
|
30814
30992
|
return readFileSync3(resolvedPath2, "utf8");
|
|
30815
30993
|
} catch {
|
|
@@ -30828,9 +31006,9 @@ function tryWorkspaceDisplayToPath(sessionParentPath, displayPath) {
|
|
|
30828
31006
|
if (!displayPath || displayPath.includes("..")) return null;
|
|
30829
31007
|
const gitRoot = getGitRepoRootSync(sessionParentPath);
|
|
30830
31008
|
if (gitRoot) {
|
|
30831
|
-
const resolvedPath =
|
|
30832
|
-
const rel =
|
|
30833
|
-
if (!rel.startsWith("..") && !
|
|
31009
|
+
const resolvedPath = path16.resolve(gitRoot, displayPath);
|
|
31010
|
+
const rel = path16.relative(gitRoot, resolvedPath);
|
|
31011
|
+
if (!rel.startsWith("..") && !path16.isAbsolute(rel)) return resolvedPath;
|
|
30834
31012
|
}
|
|
30835
31013
|
return resolveSafePathUnderCwd(sessionParentPath, displayPath);
|
|
30836
31014
|
}
|
|
@@ -30881,92 +31059,22 @@ function getSessionFileChangeDirectoryFlags(sessionParentPath, displayPath) {
|
|
|
30881
31059
|
return { isDirectory: false, directoryRemoved: false };
|
|
30882
31060
|
}
|
|
30883
31061
|
|
|
30884
|
-
// src/sqlite/code-nav-cache/code-nav-cache-
|
|
30885
|
-
|
|
30886
|
-
|
|
30887
|
-
|
|
30888
|
-
|
|
30889
|
-
|
|
30890
|
-
|
|
30891
|
-
|
|
30892
|
-
|
|
30893
|
-
|
|
30894
|
-
|
|
30895
|
-
if (!fs15.existsSync(dir)) fs15.mkdirSync(dir, { recursive: true });
|
|
30896
|
-
}
|
|
30897
|
-
|
|
30898
|
-
// src/sqlite/code-nav-cache/migrate-code-nav-cache-sqlite.ts
|
|
30899
|
-
var CHECKPOINT_V12 = "001_code_nav_cache_checkpoint_v1";
|
|
30900
|
-
var CHECKPOINT_V1_SQL2 = readCodeNavCacheMigrationSql("001_code_nav_cache_checkpoint_v1.sql");
|
|
30901
|
-
var MIGRATION_002 = "002_content_hash_symbol_index";
|
|
30902
|
-
var MIGRATION_002_SQL = readCodeNavCacheMigrationSql("002_content_hash_symbol_index.sql");
|
|
30903
|
-
var MIGRATION_003 = "003_content_hash_tag_rows";
|
|
30904
|
-
var MIGRATION_003_SQL = readCodeNavCacheMigrationSql("003_content_hash_tag_rows.sql");
|
|
30905
|
-
var CODE_NAV_CACHE_SQLITE_MIGRATIONS = [
|
|
30906
|
-
{
|
|
30907
|
-
name: CHECKPOINT_V12,
|
|
30908
|
-
checkpoint: true,
|
|
30909
|
-
migrate: (db) => {
|
|
30910
|
-
db.exec(CHECKPOINT_V1_SQL2);
|
|
30911
|
-
},
|
|
30912
|
-
alreadyApplied: (db) => {
|
|
30913
|
-
const row = db.get(
|
|
30914
|
-
`SELECT 1 as ok FROM sqlite_master WHERE type='table' AND name='file_index_parent_path' LIMIT 1`
|
|
30915
|
-
);
|
|
30916
|
-
return row != null;
|
|
30917
|
-
}
|
|
30918
|
-
},
|
|
30919
|
-
{
|
|
30920
|
-
name: MIGRATION_002,
|
|
30921
|
-
migrate: (db) => {
|
|
30922
|
-
db.exec(MIGRATION_002_SQL);
|
|
30923
|
-
},
|
|
30924
|
-
alreadyApplied: (db) => {
|
|
30925
|
-
const row = db.get(
|
|
30926
|
-
`SELECT 1 as ok FROM sqlite_master WHERE type='table' AND name='symbol_file_blob' LIMIT 1`
|
|
30927
|
-
);
|
|
30928
|
-
return row != null;
|
|
30929
|
-
}
|
|
30930
|
-
},
|
|
30931
|
-
{
|
|
30932
|
-
name: MIGRATION_003,
|
|
30933
|
-
migrate: (db) => {
|
|
30934
|
-
db.exec(MIGRATION_003_SQL);
|
|
30935
|
-
},
|
|
30936
|
-
alreadyApplied: (db) => {
|
|
30937
|
-
const row = db.get(
|
|
30938
|
-
`SELECT 1 as ok FROM sqlite_master WHERE type='table' AND name='symbol_index_tag' LIMIT 1`
|
|
30939
|
-
);
|
|
30940
|
-
if (row == null) return false;
|
|
30941
|
-
const blob = db.get(
|
|
30942
|
-
`SELECT 1 as ok FROM sqlite_master WHERE type='table' AND name='symbol_file_blob' LIMIT 1`
|
|
30943
|
-
);
|
|
30944
|
-
return blob == null;
|
|
31062
|
+
// src/sqlite/code-nav-cache/code-nav-cache-sqlite-transaction.ts
|
|
31063
|
+
function runCodeNavCacheWriteTransaction(db, fn) {
|
|
31064
|
+
db.run("BEGIN IMMEDIATE");
|
|
31065
|
+
try {
|
|
31066
|
+
const result = fn();
|
|
31067
|
+
db.run("COMMIT");
|
|
31068
|
+
return result;
|
|
31069
|
+
} catch (e) {
|
|
31070
|
+
try {
|
|
31071
|
+
db.run("ROLLBACK");
|
|
31072
|
+
} catch {
|
|
30945
31073
|
}
|
|
31074
|
+
throw e;
|
|
30946
31075
|
}
|
|
30947
|
-
];
|
|
30948
|
-
function migrateCodeNavCacheSqlite(db) {
|
|
30949
|
-
runSqliteMigrations(
|
|
30950
|
-
db,
|
|
30951
|
-
CODE_NAV_CACHE_SQLITE_MIGRATIONS,
|
|
30952
|
-
readCodeNavCacheMigrationSql("000_bootstrap_migrations_table.sql"),
|
|
30953
|
-
"code-nav-cache"
|
|
30954
|
-
);
|
|
30955
31076
|
}
|
|
30956
31077
|
|
|
30957
|
-
// src/sqlite/code-nav-cache/code-nav-cache-database.ts
|
|
30958
|
-
var codeNavCacheSqlite = createSqliteDatabaseAccess({
|
|
30959
|
-
getPath: getCodeNavCacheSqlitePath,
|
|
30960
|
-
ensureParentDir: ensureCodeNavCacheSqliteParentDir,
|
|
30961
|
-
migrate: migrateCodeNavCacheSqlite
|
|
30962
|
-
});
|
|
30963
|
-
var safeCloseCodeNavCacheSqliteDatabase = codeNavCacheSqlite.safeClose;
|
|
30964
|
-
var closeAllCodeNavCacheSqliteConnections = codeNavCacheSqlite.closeAllConnections;
|
|
30965
|
-
var openCodeNavCacheSqliteConnection = codeNavCacheSqlite.openConnection;
|
|
30966
|
-
var withCodeNavCacheSqliteSync = codeNavCacheSqlite.withSync;
|
|
30967
|
-
var withCodeNavCacheSqlite = codeNavCacheSqlite.withAsync;
|
|
30968
|
-
var ensureCodeNavCacheSqliteInitialized = codeNavCacheSqlite.ensureInitialized;
|
|
30969
|
-
|
|
30970
31078
|
// src/code-nav/yield-during-work.ts
|
|
30971
31079
|
var CODE_NAV_YIELD_EVERY = INDEX_WORK_YIELD_EVERY;
|
|
30972
31080
|
function createCodeNavYieldState() {
|
|
@@ -30981,11 +31089,11 @@ async function yieldDuringCodeNavWork(state) {
|
|
|
30981
31089
|
}
|
|
30982
31090
|
|
|
30983
31091
|
// src/code-nav/walk-code-nav-files.ts
|
|
30984
|
-
import
|
|
31092
|
+
import fs19 from "node:fs";
|
|
30985
31093
|
import path20 from "node:path";
|
|
30986
31094
|
|
|
30987
31095
|
// src/files/index/walk-workspace-tree.ts
|
|
30988
|
-
import
|
|
31096
|
+
import fs17 from "node:fs";
|
|
30989
31097
|
import path17 from "node:path";
|
|
30990
31098
|
var DEPENDENCY_INSTALL_DIR_NAMES = /* @__PURE__ */ new Set([
|
|
30991
31099
|
"node_modules",
|
|
@@ -31003,7 +31111,7 @@ function shouldSkipWorkspaceWalkEntry(name) {
|
|
|
31003
31111
|
async function walkWorkspaceTreeAsync(dir, baseDir, onFile, state) {
|
|
31004
31112
|
let names;
|
|
31005
31113
|
try {
|
|
31006
|
-
names = await
|
|
31114
|
+
names = await fs17.promises.readdir(dir);
|
|
31007
31115
|
} catch {
|
|
31008
31116
|
return;
|
|
31009
31117
|
}
|
|
@@ -31018,7 +31126,7 @@ async function walkWorkspaceTreeAsync(dir, baseDir, onFile, state) {
|
|
|
31018
31126
|
const full = path17.join(dir, name);
|
|
31019
31127
|
let stat3;
|
|
31020
31128
|
try {
|
|
31021
|
-
stat3 = await
|
|
31129
|
+
stat3 = await fs17.promises.stat(full);
|
|
31022
31130
|
} catch {
|
|
31023
31131
|
continue;
|
|
31024
31132
|
}
|
|
@@ -31036,7 +31144,7 @@ function createWalkYieldState() {
|
|
|
31036
31144
|
|
|
31037
31145
|
// src/code-nav/gitignore-filter.ts
|
|
31038
31146
|
var import_ignore = __toESM(require_ignore(), 1);
|
|
31039
|
-
import
|
|
31147
|
+
import fs18 from "node:fs";
|
|
31040
31148
|
import path18 from "node:path";
|
|
31041
31149
|
var DEFAULT_IGNORED = [".git", ".git/**"];
|
|
31042
31150
|
function normalizeRelPath(relPath) {
|
|
@@ -31047,7 +31155,7 @@ var GitignoreFilter = class {
|
|
|
31047
31155
|
/** Load `.gitignore` in `absDir` and push a layer when the file exists. */
|
|
31048
31156
|
async enterDirectory(absDir, dirRel) {
|
|
31049
31157
|
try {
|
|
31050
|
-
const content = await
|
|
31158
|
+
const content = await fs18.promises.readFile(path18.join(absDir, ".gitignore"), "utf8");
|
|
31051
31159
|
this.layers.push({ dirRel, ig: (0, import_ignore.default)().add(content) });
|
|
31052
31160
|
} catch {
|
|
31053
31161
|
}
|
|
@@ -31150,7 +31258,7 @@ async function walkCodeNavFilesInDirectory(dir, baseDir, relDir, filter, onFile,
|
|
|
31150
31258
|
await filter.enterDirectory(dir, relDir);
|
|
31151
31259
|
let names;
|
|
31152
31260
|
try {
|
|
31153
|
-
names = await
|
|
31261
|
+
names = await fs19.promises.readdir(dir);
|
|
31154
31262
|
} catch {
|
|
31155
31263
|
filter.leaveDirectory(relDir);
|
|
31156
31264
|
return;
|
|
@@ -31167,7 +31275,7 @@ async function walkCodeNavFilesInDirectory(dir, baseDir, relDir, filter, onFile,
|
|
|
31167
31275
|
const full = path20.join(dir, name);
|
|
31168
31276
|
let stat3;
|
|
31169
31277
|
try {
|
|
31170
|
-
stat3 = await
|
|
31278
|
+
stat3 = await fs19.promises.stat(full);
|
|
31171
31279
|
} catch {
|
|
31172
31280
|
continue;
|
|
31173
31281
|
}
|
|
@@ -31374,12 +31482,27 @@ function removeParentFileMapEntry(db, parentId, filePath) {
|
|
|
31374
31482
|
db.run("DELETE FROM symbol_parent_file_map WHERE parent_id = ? AND file_path = ?", [parentId, filePath]);
|
|
31375
31483
|
return previous === void 0 ? null : previous;
|
|
31376
31484
|
}
|
|
31377
|
-
function
|
|
31378
|
-
const rows = db.all(
|
|
31379
|
-
|
|
31380
|
-
|
|
31381
|
-
|
|
31382
|
-
|
|
31485
|
+
function clearParentFileMapBatch(db, parentId, limit) {
|
|
31486
|
+
const rows = db.all(
|
|
31487
|
+
`SELECT file_path, content_hash
|
|
31488
|
+
FROM symbol_parent_file_map
|
|
31489
|
+
WHERE parent_id = ?
|
|
31490
|
+
LIMIT ?`,
|
|
31491
|
+
[parentId, limit]
|
|
31492
|
+
);
|
|
31493
|
+
if (rows.length === 0) return { released: [], remaining: false };
|
|
31494
|
+
const del = db.prepare("DELETE FROM symbol_parent_file_map WHERE parent_id = ? AND file_path = ?");
|
|
31495
|
+
try {
|
|
31496
|
+
for (const row of rows) {
|
|
31497
|
+
del.run([parentId, row.file_path]);
|
|
31498
|
+
}
|
|
31499
|
+
} finally {
|
|
31500
|
+
del.finalize();
|
|
31501
|
+
}
|
|
31502
|
+
return {
|
|
31503
|
+
released: rows.flatMap((row) => row.content_hash == null ? [] : [row.content_hash]),
|
|
31504
|
+
remaining: rows.length >= limit
|
|
31505
|
+
};
|
|
31383
31506
|
}
|
|
31384
31507
|
|
|
31385
31508
|
// src/code-nav/symbol-index/storage/symbol-content-index.ts
|
|
@@ -31468,139 +31591,15 @@ function removeSymbolIndexFileData(db, ctx, filePath) {
|
|
|
31468
31591
|
const released = removeParentFileMapEntry(db, ctx.parentId, filePath);
|
|
31469
31592
|
gcReleasedHashes(db, [released]);
|
|
31470
31593
|
}
|
|
31471
|
-
function
|
|
31472
|
-
const released =
|
|
31594
|
+
function clearSymbolIndexParentDataBatch(db, ctx, limit) {
|
|
31595
|
+
const { released, remaining } = clearParentFileMapBatch(db, ctx.parentId, limit);
|
|
31473
31596
|
gcReleasedHashes(db, released);
|
|
31474
|
-
|
|
31475
|
-
|
|
31476
|
-
// src/code-nav/symbol-index/query/tag-query-shared.ts
|
|
31477
|
-
var TAG_SELECT = `file_path, name, role, kind, start_line, start_column, end_line, end_column,
|
|
31478
|
-
scope_start_line, scope_start_column, parent_scope_start_line, parent_scope_start_column, nav_target_path, scope_chain`;
|
|
31479
|
-
function rowToLocation(row) {
|
|
31480
|
-
return {
|
|
31481
|
-
path: row.file_path,
|
|
31482
|
-
line: row.start_line + 1,
|
|
31483
|
-
column: row.start_column,
|
|
31484
|
-
kind: row.kind,
|
|
31485
|
-
role: row.role === "def" ? "definition" : "reference"
|
|
31486
|
-
};
|
|
31487
|
-
}
|
|
31488
|
-
function modulePathLocation(row) {
|
|
31489
|
-
return {
|
|
31490
|
-
path: row.nav_target_path,
|
|
31491
|
-
line: 1,
|
|
31492
|
-
column: 0,
|
|
31493
|
-
kind: "module",
|
|
31494
|
-
role: "reference"
|
|
31495
|
-
};
|
|
31496
|
-
}
|
|
31497
|
-
function emptyRefRow(filePath) {
|
|
31498
|
-
return {
|
|
31499
|
-
file_path: filePath,
|
|
31500
|
-
name: "",
|
|
31501
|
-
role: "ref",
|
|
31502
|
-
kind: "",
|
|
31503
|
-
start_line: 0,
|
|
31504
|
-
start_column: 0,
|
|
31505
|
-
end_line: 0,
|
|
31506
|
-
end_column: 0,
|
|
31507
|
-
scope_start_line: null,
|
|
31508
|
-
scope_start_column: null,
|
|
31509
|
-
parent_scope_start_line: null,
|
|
31510
|
-
parent_scope_start_column: null,
|
|
31511
|
-
nav_target_path: null,
|
|
31512
|
-
scope_chain: null
|
|
31513
|
-
};
|
|
31514
|
-
}
|
|
31515
|
-
|
|
31516
|
-
// src/code-nav/symbol-index/storage/file-content-load.ts
|
|
31517
|
-
function loadFileTags(db, ctx, filePath) {
|
|
31518
|
-
const contentHash = getEffectiveContentHash(db, ctx, filePath);
|
|
31519
|
-
if (contentHash == null) return [];
|
|
31520
|
-
return db.all(
|
|
31521
|
-
`SELECT ${TAG_SELECT}
|
|
31522
|
-
FROM symbol_index_tag
|
|
31523
|
-
WHERE content_hash = ? AND file_path = ?
|
|
31524
|
-
ORDER BY start_line, start_column`,
|
|
31525
|
-
[contentHash, filePath]
|
|
31526
|
-
);
|
|
31527
|
-
}
|
|
31528
|
-
function loadFileImports(db, ctx, filePath) {
|
|
31529
|
-
const contentHash = getEffectiveContentHash(db, ctx, filePath);
|
|
31530
|
-
if (contentHash == null) return [];
|
|
31531
|
-
return db.all(
|
|
31532
|
-
`SELECT file_path, local_name, source_name, module_specifier, source_file_path, import_kind, start_line, start_column
|
|
31533
|
-
FROM symbol_index_import
|
|
31534
|
-
WHERE content_hash = ? AND file_path = ?
|
|
31535
|
-
ORDER BY start_line, start_column`,
|
|
31536
|
-
[contentHash, filePath]
|
|
31537
|
-
);
|
|
31538
|
-
}
|
|
31539
|
-
function findTagsByName(db, ctx, name) {
|
|
31540
|
-
const filePaths = listEffectiveIndexedFilePaths(db, ctx);
|
|
31541
|
-
const rows = [];
|
|
31542
|
-
for (const filePath of filePaths) {
|
|
31543
|
-
const contentHash = getEffectiveContentHash(db, ctx, filePath);
|
|
31544
|
-
if (contentHash == null) continue;
|
|
31545
|
-
const matches = db.all(
|
|
31546
|
-
`SELECT ${TAG_SELECT}
|
|
31547
|
-
FROM symbol_index_tag
|
|
31548
|
-
WHERE content_hash = ? AND file_path = ? AND name = ?
|
|
31549
|
-
ORDER BY start_line, start_column`,
|
|
31550
|
-
[contentHash, filePath, name]
|
|
31551
|
-
);
|
|
31552
|
-
rows.push(...matches);
|
|
31553
|
-
}
|
|
31554
|
-
rows.sort(
|
|
31555
|
-
(a, b) => a.file_path.localeCompare(b.file_path) || a.start_line - b.start_line || a.start_column - b.start_column
|
|
31556
|
-
);
|
|
31557
|
-
return rows;
|
|
31558
|
-
}
|
|
31559
|
-
|
|
31560
|
-
// src/code-nav/symbol-index/lifecycle/symbol-index-file-ready.ts
|
|
31561
|
-
function symbolIndexFileIsReady(parentPath, filePath) {
|
|
31562
|
-
const normalizedParent = normalizeResolvedPath(parentPath);
|
|
31563
|
-
const normalizedFile = filePath.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
31564
|
-
if (!normalizedFile) return false;
|
|
31565
|
-
return withCodeNavCacheSqliteSync((db) => {
|
|
31566
|
-
const ctx = getSymbolIndexParentContext(db, normalizedParent);
|
|
31567
|
-
if (ctx == null) return false;
|
|
31568
|
-
const versionRow = db.get("SELECT index_version FROM symbol_index_parent_path WHERE id = ?", [
|
|
31569
|
-
ctx.parentId
|
|
31570
|
-
]);
|
|
31571
|
-
if (versionRow == null || versionRow.index_version < SYMBOL_INDEX_VERSION) return false;
|
|
31572
|
-
return getEffectiveContentHash(db, ctx, normalizedFile) != null;
|
|
31573
|
-
});
|
|
31597
|
+
return remaining;
|
|
31574
31598
|
}
|
|
31575
31599
|
|
|
31576
31600
|
// src/code-nav/symbol-index/sqlite/symbol-index-sqlite-lock.ts
|
|
31577
|
-
import fs19 from "node:fs";
|
|
31578
|
-
function isSqliteCorruptError(e) {
|
|
31579
|
-
const msg = e instanceof Error ? e.message : String(e);
|
|
31580
|
-
return msg.includes("malformed") || msg.includes("database disk image is malformed") || msg.includes("corrupt");
|
|
31581
|
-
}
|
|
31582
|
-
var chain = Promise.resolve();
|
|
31583
31601
|
function withSymbolIndexSqliteLock(fn) {
|
|
31584
|
-
|
|
31585
|
-
try {
|
|
31586
|
-
return await Promise.resolve(fn());
|
|
31587
|
-
} catch (e) {
|
|
31588
|
-
if (!isSqliteCorruptError(e)) throw e;
|
|
31589
|
-
closeAllCodeNavCacheSqliteConnections();
|
|
31590
|
-
try {
|
|
31591
|
-
fs19.unlinkSync(getCodeNavCacheSqlitePath());
|
|
31592
|
-
} catch {
|
|
31593
|
-
}
|
|
31594
|
-
chain = Promise.resolve();
|
|
31595
|
-
return await Promise.resolve(fn());
|
|
31596
|
-
}
|
|
31597
|
-
};
|
|
31598
|
-
const next = chain.then(run);
|
|
31599
|
-
chain = next.then(
|
|
31600
|
-
() => void 0,
|
|
31601
|
-
() => void 0
|
|
31602
|
-
);
|
|
31603
|
-
return next;
|
|
31602
|
+
return withCodeNavCacheSqliteWorkLock(fn);
|
|
31604
31603
|
}
|
|
31605
31604
|
|
|
31606
31605
|
// src/code-nav/symbol-index/imports/star-reexport-names.ts
|
|
@@ -31705,43 +31704,111 @@ function expandStarReexportBindings(collected) {
|
|
|
31705
31704
|
}
|
|
31706
31705
|
|
|
31707
31706
|
// src/code-nav/symbol-index/persistence/persist-single-file.ts
|
|
31708
|
-
function
|
|
31709
|
-
|
|
31710
|
-
db
|
|
31711
|
-
try {
|
|
31707
|
+
async function persistSymbolIndexFileAsync(resolved, relPath, source, tags, imports) {
|
|
31708
|
+
await withCodeNavCacheSqlite(async (db) => {
|
|
31709
|
+
runCodeNavCacheWriteTransaction(db, () => {
|
|
31712
31710
|
upsertSymbolIndexParentPath(db, resolved);
|
|
31713
31711
|
const ctx = getSymbolIndexParentContext(db, resolved);
|
|
31714
31712
|
if (ctx == null) throw new Error(`Failed to resolve symbol index parent: ${resolved}`);
|
|
31715
31713
|
persistSymbolIndexFileData(db, ctx, relPath, source, tags, imports);
|
|
31716
|
-
|
|
31717
|
-
} catch (e) {
|
|
31718
|
-
try {
|
|
31719
|
-
db.run("ROLLBACK");
|
|
31720
|
-
} catch {
|
|
31721
|
-
}
|
|
31722
|
-
throw e;
|
|
31723
|
-
}
|
|
31714
|
+
});
|
|
31724
31715
|
});
|
|
31725
31716
|
}
|
|
31726
|
-
function
|
|
31727
|
-
|
|
31728
|
-
db
|
|
31729
|
-
try {
|
|
31717
|
+
async function removeSymbolIndexFileAsync(resolved, relPath) {
|
|
31718
|
+
await withCodeNavCacheSqlite(async (db) => {
|
|
31719
|
+
runCodeNavCacheWriteTransaction(db, () => {
|
|
31730
31720
|
upsertSymbolIndexParentPath(db, resolved);
|
|
31731
31721
|
const ctx = getSymbolIndexParentContext(db, resolved);
|
|
31732
31722
|
if (ctx == null) throw new Error(`Failed to resolve symbol index parent: ${resolved}`);
|
|
31733
31723
|
removeSymbolIndexFileData(db, ctx, relPath);
|
|
31734
|
-
|
|
31735
|
-
} catch (e) {
|
|
31736
|
-
try {
|
|
31737
|
-
db.run("ROLLBACK");
|
|
31738
|
-
} catch {
|
|
31739
|
-
}
|
|
31740
|
-
throw e;
|
|
31741
|
-
}
|
|
31724
|
+
});
|
|
31742
31725
|
});
|
|
31743
31726
|
}
|
|
31744
31727
|
|
|
31728
|
+
// src/code-nav/symbol-index/query/tag-query-shared.ts
|
|
31729
|
+
var TAG_SELECT = `file_path, name, role, kind, start_line, start_column, end_line, end_column,
|
|
31730
|
+
scope_start_line, scope_start_column, parent_scope_start_line, parent_scope_start_column, nav_target_path, scope_chain`;
|
|
31731
|
+
function rowToLocation(row) {
|
|
31732
|
+
return {
|
|
31733
|
+
path: row.file_path,
|
|
31734
|
+
line: row.start_line + 1,
|
|
31735
|
+
column: row.start_column,
|
|
31736
|
+
kind: row.kind,
|
|
31737
|
+
role: row.role === "def" ? "definition" : "reference"
|
|
31738
|
+
};
|
|
31739
|
+
}
|
|
31740
|
+
function modulePathLocation(row) {
|
|
31741
|
+
return {
|
|
31742
|
+
path: row.nav_target_path,
|
|
31743
|
+
line: 1,
|
|
31744
|
+
column: 0,
|
|
31745
|
+
kind: "module",
|
|
31746
|
+
role: "reference"
|
|
31747
|
+
};
|
|
31748
|
+
}
|
|
31749
|
+
function emptyRefRow(filePath) {
|
|
31750
|
+
return {
|
|
31751
|
+
file_path: filePath,
|
|
31752
|
+
name: "",
|
|
31753
|
+
role: "ref",
|
|
31754
|
+
kind: "",
|
|
31755
|
+
start_line: 0,
|
|
31756
|
+
start_column: 0,
|
|
31757
|
+
end_line: 0,
|
|
31758
|
+
end_column: 0,
|
|
31759
|
+
scope_start_line: null,
|
|
31760
|
+
scope_start_column: null,
|
|
31761
|
+
parent_scope_start_line: null,
|
|
31762
|
+
parent_scope_start_column: null,
|
|
31763
|
+
nav_target_path: null,
|
|
31764
|
+
scope_chain: null
|
|
31765
|
+
};
|
|
31766
|
+
}
|
|
31767
|
+
|
|
31768
|
+
// src/code-nav/symbol-index/storage/file-content-load.ts
|
|
31769
|
+
function loadFileTags(db, ctx, filePath) {
|
|
31770
|
+
const contentHash = getEffectiveContentHash(db, ctx, filePath);
|
|
31771
|
+
if (contentHash == null) return [];
|
|
31772
|
+
return db.all(
|
|
31773
|
+
`SELECT ${TAG_SELECT}
|
|
31774
|
+
FROM symbol_index_tag
|
|
31775
|
+
WHERE content_hash = ? AND file_path = ?
|
|
31776
|
+
ORDER BY start_line, start_column`,
|
|
31777
|
+
[contentHash, filePath]
|
|
31778
|
+
);
|
|
31779
|
+
}
|
|
31780
|
+
function loadFileImports(db, ctx, filePath) {
|
|
31781
|
+
const contentHash = getEffectiveContentHash(db, ctx, filePath);
|
|
31782
|
+
if (contentHash == null) return [];
|
|
31783
|
+
return db.all(
|
|
31784
|
+
`SELECT file_path, local_name, source_name, module_specifier, source_file_path, import_kind, start_line, start_column
|
|
31785
|
+
FROM symbol_index_import
|
|
31786
|
+
WHERE content_hash = ? AND file_path = ?
|
|
31787
|
+
ORDER BY start_line, start_column`,
|
|
31788
|
+
[contentHash, filePath]
|
|
31789
|
+
);
|
|
31790
|
+
}
|
|
31791
|
+
function findTagsByName(db, ctx, name) {
|
|
31792
|
+
const filePaths = listEffectiveIndexedFilePaths(db, ctx);
|
|
31793
|
+
const rows = [];
|
|
31794
|
+
for (const filePath of filePaths) {
|
|
31795
|
+
const contentHash = getEffectiveContentHash(db, ctx, filePath);
|
|
31796
|
+
if (contentHash == null) continue;
|
|
31797
|
+
const matches = db.all(
|
|
31798
|
+
`SELECT ${TAG_SELECT}
|
|
31799
|
+
FROM symbol_index_tag
|
|
31800
|
+
WHERE content_hash = ? AND file_path = ? AND name = ?
|
|
31801
|
+
ORDER BY start_line, start_column`,
|
|
31802
|
+
[contentHash, filePath, name]
|
|
31803
|
+
);
|
|
31804
|
+
rows.push(...matches);
|
|
31805
|
+
}
|
|
31806
|
+
rows.sort(
|
|
31807
|
+
(a, b) => a.file_path.localeCompare(b.file_path) || a.start_line - b.start_line || a.start_column - b.start_column
|
|
31808
|
+
);
|
|
31809
|
+
return rows;
|
|
31810
|
+
}
|
|
31811
|
+
|
|
31745
31812
|
// src/code-nav/symbol-index/build/load-indexed-file-entry.ts
|
|
31746
31813
|
function dbTagToSymbolTag(row) {
|
|
31747
31814
|
return {
|
|
@@ -31787,21 +31854,52 @@ function loadIndexedFileEntry(db, ctx, relPath) {
|
|
|
31787
31854
|
function normalizeRelPath2(filePath) {
|
|
31788
31855
|
return filePath.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
31789
31856
|
}
|
|
31790
|
-
function
|
|
31857
|
+
function listDirectImportTargetsWithDb(db, resolved, relPath) {
|
|
31858
|
+
const ctx = getSymbolIndexParentContext(db, resolved);
|
|
31859
|
+
if (ctx == null) return [];
|
|
31860
|
+
const entry = loadIndexedFileEntry(db, ctx, relPath);
|
|
31861
|
+
if (entry == null) return [];
|
|
31862
|
+
const paths = /* @__PURE__ */ new Set();
|
|
31863
|
+
for (const binding of entry.imports) {
|
|
31864
|
+
if (binding.sourceFilePath) paths.add(binding.sourceFilePath);
|
|
31865
|
+
}
|
|
31866
|
+
return Array.from(paths);
|
|
31867
|
+
}
|
|
31868
|
+
async function listDirectImportTargetsForFileAsync(parentPath, filePath) {
|
|
31791
31869
|
const resolved = normalizeResolvedPath(parentPath);
|
|
31792
31870
|
const relPath = normalizeRelPath2(filePath);
|
|
31793
31871
|
if (!relPath) return [];
|
|
31794
|
-
return
|
|
31795
|
-
|
|
31872
|
+
return withCodeNavCacheSqlite((db) => listDirectImportTargetsWithDb(db, resolved, relPath));
|
|
31873
|
+
}
|
|
31874
|
+
|
|
31875
|
+
// src/code-nav/symbol-index/lifecycle/symbol-index-file-ready.ts
|
|
31876
|
+
function symbolIndexFileIsReadyWithDb(db, parentPath, filePath) {
|
|
31877
|
+
const normalizedParent = normalizeResolvedPath(parentPath);
|
|
31878
|
+
const normalizedFile = filePath.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
31879
|
+
if (!normalizedFile) return false;
|
|
31880
|
+
const ctx = getSymbolIndexParentContext(db, normalizedParent);
|
|
31881
|
+
if (ctx == null) return false;
|
|
31882
|
+
const versionRow = db.get("SELECT index_version FROM symbol_index_parent_path WHERE id = ?", [
|
|
31883
|
+
ctx.parentId
|
|
31884
|
+
]);
|
|
31885
|
+
if (versionRow == null || versionRow.index_version < SYMBOL_INDEX_VERSION) return false;
|
|
31886
|
+
return getEffectiveContentHash(db, ctx, normalizedFile) != null;
|
|
31887
|
+
}
|
|
31888
|
+
async function symbolIndexFileIsReadyAsync(parentPath, filePath) {
|
|
31889
|
+
return withCodeNavCacheSqlite((db) => symbolIndexFileIsReadyWithDb(db, parentPath, filePath));
|
|
31890
|
+
}
|
|
31891
|
+
async function loadSymbolIndexReadyFileSet(parentPath) {
|
|
31892
|
+
const normalizedParent = normalizeResolvedPath(parentPath);
|
|
31893
|
+
const paths = await withCodeNavCacheSqlite((db) => {
|
|
31894
|
+
const ctx = getSymbolIndexParentContext(db, normalizedParent);
|
|
31796
31895
|
if (ctx == null) return [];
|
|
31797
|
-
const
|
|
31798
|
-
|
|
31799
|
-
|
|
31800
|
-
|
|
31801
|
-
|
|
31802
|
-
}
|
|
31803
|
-
return [...paths];
|
|
31896
|
+
const versionRow = db.get("SELECT index_version FROM symbol_index_parent_path WHERE id = ?", [
|
|
31897
|
+
ctx.parentId
|
|
31898
|
+
]);
|
|
31899
|
+
if (versionRow == null || versionRow.index_version < SYMBOL_INDEX_VERSION) return [];
|
|
31900
|
+
return listEffectiveIndexedFilePaths(db, ctx);
|
|
31804
31901
|
});
|
|
31902
|
+
return new Set(paths);
|
|
31805
31903
|
}
|
|
31806
31904
|
|
|
31807
31905
|
// src/code-nav/symbol-index/build/extract-file-symbol-data.ts
|
|
@@ -32111,9 +32209,9 @@ async function augmentTypeReferenceTags(tags, nameNodes, root) {
|
|
|
32111
32209
|
}
|
|
32112
32210
|
|
|
32113
32211
|
// src/code-nav/scope-chain.ts
|
|
32114
|
-
function serializeScopeChain(
|
|
32115
|
-
if (
|
|
32116
|
-
return
|
|
32212
|
+
function serializeScopeChain(chain2) {
|
|
32213
|
+
if (chain2.length === 0) return null;
|
|
32214
|
+
return chain2.map((anchor) => `${anchor.startLine}:${anchor.startColumn}`).join(",");
|
|
32117
32215
|
}
|
|
32118
32216
|
function parseScopeChain(raw) {
|
|
32119
32217
|
if (!raw) return [];
|
|
@@ -32129,9 +32227,9 @@ function parseScopeChain(raw) {
|
|
|
32129
32227
|
}
|
|
32130
32228
|
return out;
|
|
32131
32229
|
}
|
|
32132
|
-
function anchorInScopeChain(line, column,
|
|
32133
|
-
if (line == null || column == null) return
|
|
32134
|
-
return
|
|
32230
|
+
function anchorInScopeChain(line, column, chain2) {
|
|
32231
|
+
if (line == null || column == null) return chain2.length === 0;
|
|
32232
|
+
return chain2.some((anchor) => anchor.startLine === line && anchor.startColumn === column);
|
|
32135
32233
|
}
|
|
32136
32234
|
|
|
32137
32235
|
// src/code-nav/enrich-tag-scope.ts
|
|
@@ -32168,15 +32266,15 @@ function scopeAnchorFromNode(node) {
|
|
|
32168
32266
|
};
|
|
32169
32267
|
}
|
|
32170
32268
|
function findEnclosingScopeChain(nameNode) {
|
|
32171
|
-
const
|
|
32269
|
+
const chain2 = [];
|
|
32172
32270
|
let current = nameNode.parent;
|
|
32173
32271
|
while (current) {
|
|
32174
32272
|
if (SCOPE_CONTAINER_TYPES.has(current.type)) {
|
|
32175
|
-
|
|
32273
|
+
chain2.push(scopeAnchorFromNode(current));
|
|
32176
32274
|
}
|
|
32177
32275
|
current = current.parent;
|
|
32178
32276
|
}
|
|
32179
|
-
return
|
|
32277
|
+
return chain2;
|
|
32180
32278
|
}
|
|
32181
32279
|
function findEnclosingScopes(nameNode) {
|
|
32182
32280
|
const scopeChain = findEnclosingScopeChain(nameNode);
|
|
@@ -33033,7 +33131,7 @@ async function extractFileSymbolData(resolved, relPath, workspaceFilesOverride)
|
|
|
33033
33131
|
}
|
|
33034
33132
|
}
|
|
33035
33133
|
await yieldToEventLoop();
|
|
33036
|
-
const workspaceFiles = workspaceFilesOverride ??
|
|
33134
|
+
const workspaceFiles = workspaceFilesOverride ?? await withCodeNavCacheSqlite((db) => listWorkspaceFiles(db, resolved, relPath));
|
|
33037
33135
|
const imports = source != null ? await extractImportBindingsFromSource(relPath, source, workspaceFiles) : [];
|
|
33038
33136
|
const yieldState = createCodeNavYieldState();
|
|
33039
33137
|
return {
|
|
@@ -33058,7 +33156,7 @@ async function indexOneSymbolFileForBuild(resolved, relPath, workspaceFiles) {
|
|
|
33058
33156
|
};
|
|
33059
33157
|
if (data.imports.some((binding) => binding.importKind === "star")) {
|
|
33060
33158
|
await yieldToEventLoop();
|
|
33061
|
-
entry =
|
|
33159
|
+
entry = await withCodeNavCacheSqlite((db) => {
|
|
33062
33160
|
const ctx = getSymbolIndexParentContext(db, resolved);
|
|
33063
33161
|
if (ctx == null) return entry;
|
|
33064
33162
|
const resolveEntry = (filePath) => loadIndexedFileEntry(db, ctx, filePath);
|
|
@@ -33068,7 +33166,7 @@ async function indexOneSymbolFileForBuild(resolved, relPath, workspaceFiles) {
|
|
|
33068
33166
|
}
|
|
33069
33167
|
await withSymbolIndexSqliteLock(async () => {
|
|
33070
33168
|
await yieldToEventLoop();
|
|
33071
|
-
|
|
33169
|
+
await persistSymbolIndexFileAsync(resolved, relPath, entry.source, entry.tags, entry.imports);
|
|
33072
33170
|
});
|
|
33073
33171
|
}
|
|
33074
33172
|
async function ensureSymbolIndexFileAsync(parentPath, filePath, opts) {
|
|
@@ -33076,41 +33174,51 @@ async function ensureSymbolIndexFileAsync(parentPath, filePath, opts) {
|
|
|
33076
33174
|
const relPath = normalizeRelPath3(filePath);
|
|
33077
33175
|
if (!relPath) return false;
|
|
33078
33176
|
const importDepth = opts?.importDepth ?? 0;
|
|
33079
|
-
|
|
33177
|
+
await withCodeNavCacheSqlite((db) => {
|
|
33080
33178
|
upsertSymbolIndexParentPath(db, resolved);
|
|
33081
33179
|
});
|
|
33082
|
-
if (!
|
|
33180
|
+
if (!await symbolIndexFileIsReadyAsync(resolved, relPath)) {
|
|
33083
33181
|
await indexOneSymbolFileForBuild(resolved, relPath, void 0);
|
|
33084
33182
|
}
|
|
33085
|
-
if (importDepth > 0 &&
|
|
33086
|
-
const targets =
|
|
33183
|
+
if (importDepth > 0 && await symbolIndexFileIsReadyAsync(resolved, relPath)) {
|
|
33184
|
+
const targets = (await listDirectImportTargetsForFileAsync(resolved, relPath)).slice(
|
|
33185
|
+
0,
|
|
33186
|
+
MAX_IMPORT_PREFETCH_COUNT
|
|
33187
|
+
);
|
|
33087
33188
|
for (const target of targets) {
|
|
33088
33189
|
await yieldToEventLoop();
|
|
33089
|
-
if (!
|
|
33190
|
+
if (!await symbolIndexFileIsReadyAsync(resolved, target)) {
|
|
33090
33191
|
await ensureSymbolIndexFileAsync(resolved, target, { importDepth: importDepth - 1 });
|
|
33091
33192
|
}
|
|
33092
33193
|
}
|
|
33093
33194
|
}
|
|
33094
|
-
return
|
|
33195
|
+
return await symbolIndexFileIsReadyAsync(resolved, relPath);
|
|
33095
33196
|
}
|
|
33096
|
-
function
|
|
33197
|
+
async function registerSymbolIndexParentAsync(parentPath) {
|
|
33097
33198
|
const resolved = normalizeResolvedPath(parentPath);
|
|
33098
|
-
|
|
33199
|
+
await withCodeNavCacheSqlite((db) => {
|
|
33099
33200
|
upsertSymbolIndexParentPath(db, resolved);
|
|
33100
33201
|
});
|
|
33101
33202
|
}
|
|
33102
33203
|
|
|
33103
33204
|
// src/code-nav/symbol-index/build/build-symbol-index.ts
|
|
33205
|
+
var SYMBOL_PARENT_CLEAR_BATCH_SIZE = 256;
|
|
33104
33206
|
async function buildSymbolIndexAsync(parentPath) {
|
|
33105
33207
|
const resolved = normalizeResolvedPath(parentPath);
|
|
33106
33208
|
await yieldToEventLoop();
|
|
33107
|
-
|
|
33108
|
-
|
|
33109
|
-
|
|
33110
|
-
|
|
33111
|
-
|
|
33209
|
+
let clearRemaining = true;
|
|
33210
|
+
while (clearRemaining) {
|
|
33211
|
+
await withSymbolIndexSqliteLock(async () => {
|
|
33212
|
+
clearRemaining = await withCodeNavCacheSqlite(
|
|
33213
|
+
(db) => runCodeNavCacheWriteTransaction(db, () => {
|
|
33214
|
+
upsertSymbolIndexParentPath(db, resolved);
|
|
33215
|
+
const ctx = getSymbolIndexParentContext(db, resolved);
|
|
33216
|
+
return ctx == null ? false : clearSymbolIndexParentDataBatch(db, ctx, SYMBOL_PARENT_CLEAR_BATCH_SIZE);
|
|
33217
|
+
})
|
|
33218
|
+
);
|
|
33112
33219
|
});
|
|
33113
|
-
|
|
33220
|
+
if (clearRemaining) await yieldToEventLoop();
|
|
33221
|
+
}
|
|
33114
33222
|
const workspaceFiles = /* @__PURE__ */ new Set();
|
|
33115
33223
|
const walkState = createWalkYieldState();
|
|
33116
33224
|
const yieldState = createCodeNavYieldState();
|
|
@@ -33127,9 +33235,7 @@ async function buildSymbolIndexAsync(parentPath) {
|
|
|
33127
33235
|
resolved,
|
|
33128
33236
|
async (relPath) => {
|
|
33129
33237
|
await yieldDuringCodeNavWork(yieldState);
|
|
33130
|
-
|
|
33131
|
-
await indexOneSymbolFileForBuild(resolved, relPath, workspaceFiles);
|
|
33132
|
-
}
|
|
33238
|
+
await indexOneSymbolFileForBuild(resolved, relPath, workspaceFiles);
|
|
33133
33239
|
fileCount += 1;
|
|
33134
33240
|
},
|
|
33135
33241
|
walkState
|
|
@@ -33138,18 +33244,79 @@ async function buildSymbolIndexAsync(parentPath) {
|
|
|
33138
33244
|
return { fileCount, tagCount: 0 };
|
|
33139
33245
|
}
|
|
33140
33246
|
|
|
33247
|
+
// src/code-nav/symbol-index/scheduler/task-priority-heap.ts
|
|
33248
|
+
function higherPriority(a, b) {
|
|
33249
|
+
return a.priority > b.priority;
|
|
33250
|
+
}
|
|
33251
|
+
var SymbolIndexTaskPriorityHeap = class {
|
|
33252
|
+
heap = [];
|
|
33253
|
+
clear() {
|
|
33254
|
+
this.heap.length = 0;
|
|
33255
|
+
}
|
|
33256
|
+
push(task) {
|
|
33257
|
+
this.heap.push(task);
|
|
33258
|
+
let i = this.heap.length - 1;
|
|
33259
|
+
while (i > 0) {
|
|
33260
|
+
const parent = Math.floor((i - 1) / 2);
|
|
33261
|
+
if (!higherPriority(this.heap[i], this.heap[parent])) break;
|
|
33262
|
+
this.swap(i, parent);
|
|
33263
|
+
i = parent;
|
|
33264
|
+
}
|
|
33265
|
+
}
|
|
33266
|
+
pop() {
|
|
33267
|
+
if (this.heap.length === 0) return void 0;
|
|
33268
|
+
const top = this.heap[0];
|
|
33269
|
+
const last2 = this.heap.pop();
|
|
33270
|
+
if (this.heap.length > 0) {
|
|
33271
|
+
this.heap[0] = last2;
|
|
33272
|
+
this.sink(0);
|
|
33273
|
+
}
|
|
33274
|
+
return top;
|
|
33275
|
+
}
|
|
33276
|
+
get size() {
|
|
33277
|
+
return this.heap.length;
|
|
33278
|
+
}
|
|
33279
|
+
sink(start) {
|
|
33280
|
+
let i = start;
|
|
33281
|
+
while (true) {
|
|
33282
|
+
const left = i * 2 + 1;
|
|
33283
|
+
const right = left + 1;
|
|
33284
|
+
let best = i;
|
|
33285
|
+
if (left < this.heap.length && higherPriority(this.heap[left], this.heap[best])) best = left;
|
|
33286
|
+
if (right < this.heap.length && higherPriority(this.heap[right], this.heap[best])) best = right;
|
|
33287
|
+
if (best === i) break;
|
|
33288
|
+
this.swap(i, best);
|
|
33289
|
+
i = best;
|
|
33290
|
+
}
|
|
33291
|
+
}
|
|
33292
|
+
swap(i, j) {
|
|
33293
|
+
const tmp = this.heap[i];
|
|
33294
|
+
this.heap[i] = this.heap[j];
|
|
33295
|
+
this.heap[j] = tmp;
|
|
33296
|
+
}
|
|
33297
|
+
};
|
|
33298
|
+
|
|
33299
|
+
// src/code-nav/symbol-index/scheduler/task-queue-types.ts
|
|
33300
|
+
function symbolIndexTaskKey(parentPath, filePath) {
|
|
33301
|
+
return `${parentPath}\0${filePath}`;
|
|
33302
|
+
}
|
|
33303
|
+
|
|
33141
33304
|
// src/code-nav/symbol-index/scheduler/task-queue.ts
|
|
33142
33305
|
var pending = /* @__PURE__ */ new Map();
|
|
33306
|
+
var heap = new SymbolIndexTaskPriorityHeap();
|
|
33307
|
+
var latestActiveSequenceByParent = /* @__PURE__ */ new Map();
|
|
33143
33308
|
var workerRunning = false;
|
|
33144
|
-
function
|
|
33145
|
-
|
|
33309
|
+
function taskMatchesCurrentPending(task) {
|
|
33310
|
+
const current = pending.get(symbolIndexTaskKey(task.parentPath, task.filePath));
|
|
33311
|
+
return current === task;
|
|
33146
33312
|
}
|
|
33147
33313
|
function pickNextTask() {
|
|
33148
|
-
|
|
33149
|
-
|
|
33150
|
-
if (
|
|
33314
|
+
while (heap.size > 0) {
|
|
33315
|
+
const task = heap.pop();
|
|
33316
|
+
if (task == null || !taskMatchesCurrentPending(task)) continue;
|
|
33317
|
+
return task;
|
|
33151
33318
|
}
|
|
33152
|
-
return
|
|
33319
|
+
return void 0;
|
|
33153
33320
|
}
|
|
33154
33321
|
async function runWorker() {
|
|
33155
33322
|
if (workerRunning) return;
|
|
@@ -33159,74 +33326,93 @@ async function runWorker() {
|
|
|
33159
33326
|
while (pending.size > 0) {
|
|
33160
33327
|
const task = pickNextTask();
|
|
33161
33328
|
if (task == null) break;
|
|
33162
|
-
pending.delete(
|
|
33329
|
+
pending.delete(symbolIndexTaskKey(task.parentPath, task.filePath));
|
|
33163
33330
|
await yieldDuringCodeNavWork(yieldState);
|
|
33164
|
-
|
|
33331
|
+
const latestActiveSequence = latestActiveSequenceByParent.get(task.parentPath);
|
|
33332
|
+
if (latestActiveSequence != null && task.sequence != null && task.sequence < latestActiveSequence) {
|
|
33333
|
+
continue;
|
|
33334
|
+
}
|
|
33335
|
+
if (!await symbolIndexFileIsReadyAsync(task.parentPath, task.filePath)) {
|
|
33165
33336
|
await ensureSymbolIndexFileAsync(task.parentPath, task.filePath);
|
|
33166
33337
|
}
|
|
33167
33338
|
await yieldToEventLoop();
|
|
33168
33339
|
}
|
|
33169
33340
|
} finally {
|
|
33341
|
+
if (pending.size === 0) heap.clear();
|
|
33170
33342
|
workerRunning = false;
|
|
33171
33343
|
if (pending.size > 0) void runWorker();
|
|
33172
33344
|
}
|
|
33173
33345
|
}
|
|
33174
|
-
function enqueueSymbolIndexTask(parentPath, filePath, priority) {
|
|
33346
|
+
function enqueueSymbolIndexTask(parentPath, filePath, priority, sequence) {
|
|
33175
33347
|
const normalizedParent = normalizeResolvedPath(parentPath);
|
|
33176
33348
|
const normalizedFile = filePath.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
33177
33349
|
if (!normalizedFile) return;
|
|
33178
|
-
|
|
33179
|
-
const key = taskKey(normalizedParent, normalizedFile);
|
|
33350
|
+
const key = symbolIndexTaskKey(normalizedParent, normalizedFile);
|
|
33180
33351
|
const existing = pending.get(key);
|
|
33181
33352
|
if (existing != null && existing.priority >= priority) return;
|
|
33182
|
-
|
|
33353
|
+
const task = { parentPath: normalizedParent, filePath: normalizedFile, priority, sequence };
|
|
33354
|
+
pending.set(key, task);
|
|
33355
|
+
heap.push(task);
|
|
33183
33356
|
void runWorker();
|
|
33184
33357
|
}
|
|
33358
|
+
function markLatestActiveSymbolIndexTask(parentPath, sequence) {
|
|
33359
|
+
const normalizedParent = normalizeResolvedPath(parentPath);
|
|
33360
|
+
const existing = latestActiveSequenceByParent.get(normalizedParent);
|
|
33361
|
+
if (existing != null && existing >= sequence) return;
|
|
33362
|
+
latestActiveSequenceByParent.set(normalizedParent, sequence);
|
|
33363
|
+
for (const [key, task] of pending) {
|
|
33364
|
+
if (task.parentPath === normalizedParent && task.sequence != null && task.sequence < sequence) {
|
|
33365
|
+
pending.delete(key);
|
|
33366
|
+
}
|
|
33367
|
+
}
|
|
33368
|
+
if (pending.size === 0) heap.clear();
|
|
33369
|
+
}
|
|
33185
33370
|
|
|
33186
33371
|
// src/code-nav/symbol-index/scheduler/symbol-index-scheduler.ts
|
|
33187
33372
|
var requestSeq = 0;
|
|
33188
33373
|
var warmupSeq = 0;
|
|
33189
33374
|
var warmupScheduled = /* @__PURE__ */ new Set();
|
|
33375
|
+
var warmupCompleted = /* @__PURE__ */ new Set();
|
|
33190
33376
|
function scheduleSymbolIndexFile(parentPath, filePath) {
|
|
33191
|
-
|
|
33377
|
+
const sequence = ++requestSeq;
|
|
33378
|
+
markLatestActiveSymbolIndexTask(parentPath, sequence);
|
|
33379
|
+
enqueueSymbolIndexTask(parentPath, filePath, 1e6 + sequence, sequence);
|
|
33192
33380
|
}
|
|
33193
33381
|
function scheduleSymbolIndexImportNeighbors(parentPath, filePaths) {
|
|
33194
33382
|
let priority = 5e5 + requestSeq;
|
|
33195
33383
|
for (const filePath of filePaths) {
|
|
33196
|
-
enqueueSymbolIndexTask(parentPath, filePath, priority);
|
|
33384
|
+
enqueueSymbolIndexTask(parentPath, filePath, priority, requestSeq);
|
|
33197
33385
|
priority -= 1;
|
|
33198
33386
|
}
|
|
33199
33387
|
}
|
|
33200
33388
|
function scheduleSymbolIndexWarmup(parentPath) {
|
|
33201
33389
|
const resolved = normalizeResolvedPath(parentPath);
|
|
33390
|
+
if (warmupCompleted.has(resolved)) return;
|
|
33202
33391
|
if (warmupScheduled.has(resolved)) return;
|
|
33203
33392
|
warmupScheduled.add(resolved);
|
|
33204
33393
|
setImmediate(() => {
|
|
33205
33394
|
void (async () => {
|
|
33206
33395
|
try {
|
|
33396
|
+
const readyFiles = await loadSymbolIndexReadyFileSet(resolved);
|
|
33207
33397
|
const walkState = createWalkYieldState();
|
|
33208
33398
|
const yieldState = createCodeNavYieldState();
|
|
33209
33399
|
await walkCodeNavFilesAsync(
|
|
33210
33400
|
resolved,
|
|
33211
33401
|
async (relPath) => {
|
|
33212
33402
|
await yieldDuringCodeNavWork(yieldState);
|
|
33213
|
-
if (!
|
|
33214
|
-
enqueueSymbolIndexTask(resolved, relPath, ++warmupSeq);
|
|
33403
|
+
if (!readyFiles.has(relPath)) {
|
|
33404
|
+
enqueueSymbolIndexTask(resolved, relPath, ++warmupSeq, requestSeq);
|
|
33215
33405
|
}
|
|
33216
33406
|
},
|
|
33217
33407
|
walkState
|
|
33218
33408
|
);
|
|
33409
|
+
warmupCompleted.add(resolved);
|
|
33219
33410
|
} finally {
|
|
33220
33411
|
warmupScheduled.delete(resolved);
|
|
33221
33412
|
}
|
|
33222
33413
|
})();
|
|
33223
33414
|
});
|
|
33224
33415
|
}
|
|
33225
|
-
function scheduleSymbolIndexForRequest(parentPath, reqPath, importTargets) {
|
|
33226
|
-
scheduleSymbolIndexFile(parentPath, reqPath);
|
|
33227
|
-
scheduleSymbolIndexImportNeighbors(parentPath, importTargets);
|
|
33228
|
-
scheduleSymbolIndexWarmup(parentPath);
|
|
33229
|
-
}
|
|
33230
33416
|
|
|
33231
33417
|
// src/code-nav/symbol-index/lifecycle/normalize-symbol-index-path.ts
|
|
33232
33418
|
import path24 from "node:path";
|
|
@@ -33242,27 +33428,23 @@ function normalizeSymbolIndexRelPath(parentPath, changedPath) {
|
|
|
33242
33428
|
async function updateSymbolIndexForFile(parentPath, changedPath) {
|
|
33243
33429
|
const relPath = normalizeSymbolIndexRelPath(parentPath, changedPath);
|
|
33244
33430
|
if (relPath == null) return;
|
|
33431
|
+
const resolved = normalizeResolvedPath(parentPath);
|
|
33432
|
+
const { source, tags, imports } = await extractFileSymbolData(resolved, relPath);
|
|
33433
|
+
await yieldToEventLoop();
|
|
33245
33434
|
await withSymbolIndexSqliteLock(async () => {
|
|
33246
|
-
|
|
33247
|
-
const { source, tags, imports } = await extractFileSymbolData(resolved, relPath);
|
|
33248
|
-
await yieldToEventLoop();
|
|
33249
|
-
persistSymbolIndexFile(resolved, relPath, source, tags, imports);
|
|
33435
|
+
await persistSymbolIndexFileAsync(resolved, relPath, source, tags, imports);
|
|
33250
33436
|
});
|
|
33251
33437
|
}
|
|
33252
33438
|
async function removeSymbolIndexForFile(parentPath, changedPath) {
|
|
33253
33439
|
const relPath = normalizeSymbolIndexRelPath(parentPath, changedPath);
|
|
33254
33440
|
if (relPath == null) return;
|
|
33441
|
+
const resolved = normalizeResolvedPath(parentPath);
|
|
33255
33442
|
await withSymbolIndexSqliteLock(async () => {
|
|
33256
|
-
|
|
33443
|
+
await removeSymbolIndexFileAsync(resolved, relPath);
|
|
33257
33444
|
});
|
|
33258
33445
|
}
|
|
33259
33446
|
|
|
33260
33447
|
// src/code-nav/symbol-index/sqlite/symbol-index-import-sqlite.ts
|
|
33261
|
-
function listImportsForFile(db, parentId, filePath) {
|
|
33262
|
-
const ctx = getSymbolIndexParentContextById(db, parentId);
|
|
33263
|
-
if (ctx == null) return [];
|
|
33264
|
-
return loadFileImports(db, ctx, filePath);
|
|
33265
|
-
}
|
|
33266
33448
|
function prefersTypeImport(refKind) {
|
|
33267
33449
|
return refKind === "type";
|
|
33268
33450
|
}
|
|
@@ -33288,7 +33470,7 @@ function findImportBindingForLocalName(imports, localName, ref) {
|
|
|
33288
33470
|
function defsByFileNameKey(filePath, name) {
|
|
33289
33471
|
return `${filePath}\0${name}`;
|
|
33290
33472
|
}
|
|
33291
|
-
function
|
|
33473
|
+
function createSnapshotNavigationLookups(db, parentId) {
|
|
33292
33474
|
const ctx = getSymbolIndexParentContextById(db, parentId);
|
|
33293
33475
|
if (ctx == null) {
|
|
33294
33476
|
return {
|
|
@@ -33300,29 +33482,24 @@ function createNavigationLookups(db, parentId) {
|
|
|
33300
33482
|
const fileDefsCache = /* @__PURE__ */ new Map();
|
|
33301
33483
|
const defsByFileNameCache = /* @__PURE__ */ new Map();
|
|
33302
33484
|
const importsCache = /* @__PURE__ */ new Map();
|
|
33303
|
-
|
|
33304
|
-
|
|
33305
|
-
|
|
33306
|
-
|
|
33307
|
-
|
|
33308
|
-
|
|
33309
|
-
|
|
33310
|
-
|
|
33311
|
-
|
|
33312
|
-
|
|
33313
|
-
|
|
33314
|
-
if (cached2) return cached2;
|
|
33315
|
-
cached2 = loadFileTags(db, ctx, filePath).filter((row) => row.role === "def" && row.name === name);
|
|
33316
|
-
defsByFileNameCache.set(key, cached2);
|
|
33317
|
-
return cached2;
|
|
33318
|
-
},
|
|
33319
|
-
lookupImportsForFile(filePath) {
|
|
33320
|
-
let cached2 = importsCache.get(filePath);
|
|
33321
|
-
if (cached2) return cached2;
|
|
33322
|
-
cached2 = listImportsForFile(db, parentId, filePath);
|
|
33323
|
-
importsCache.set(filePath, cached2);
|
|
33324
|
-
return cached2;
|
|
33485
|
+
for (const filePath of listEffectiveIndexedFilePaths(db, ctx)) {
|
|
33486
|
+
const defs = loadFileTags(db, ctx, filePath).filter((row) => row.role === "def");
|
|
33487
|
+
fileDefsCache.set(filePath, defs);
|
|
33488
|
+
for (const def of defs) {
|
|
33489
|
+
const key = defsByFileNameKey(filePath, def.name);
|
|
33490
|
+
const existing = defsByFileNameCache.get(key);
|
|
33491
|
+
if (existing) {
|
|
33492
|
+
existing.push(def);
|
|
33493
|
+
} else {
|
|
33494
|
+
defsByFileNameCache.set(key, [def]);
|
|
33495
|
+
}
|
|
33325
33496
|
}
|
|
33497
|
+
importsCache.set(filePath, loadFileImports(db, ctx, filePath));
|
|
33498
|
+
}
|
|
33499
|
+
return {
|
|
33500
|
+
loadFileDefs: (filePath) => fileDefsCache.get(filePath) ?? [],
|
|
33501
|
+
lookupDefsInFileNamed: (filePath, name) => defsByFileNameCache.get(defsByFileNameKey(filePath, name)) ?? [],
|
|
33502
|
+
lookupImportsForFile: (filePath) => importsCache.get(filePath) ?? []
|
|
33326
33503
|
};
|
|
33327
33504
|
}
|
|
33328
33505
|
|
|
@@ -33331,11 +33508,11 @@ function refScopeChain(ref) {
|
|
|
33331
33508
|
const parsed = parseScopeChain(ref.scope_chain);
|
|
33332
33509
|
if (parsed.length > 0) return parsed;
|
|
33333
33510
|
if (ref.scope_start_line != null && ref.scope_start_column != null) {
|
|
33334
|
-
const
|
|
33511
|
+
const chain2 = [{ startLine: ref.scope_start_line, startColumn: ref.scope_start_column }];
|
|
33335
33512
|
if (ref.parent_scope_start_line != null && ref.parent_scope_start_column != null) {
|
|
33336
|
-
|
|
33513
|
+
chain2.push({ startLine: ref.parent_scope_start_line, startColumn: ref.parent_scope_start_column });
|
|
33337
33514
|
}
|
|
33338
|
-
return
|
|
33515
|
+
return chain2;
|
|
33339
33516
|
}
|
|
33340
33517
|
return [];
|
|
33341
33518
|
}
|
|
@@ -33346,17 +33523,17 @@ function defAtScopeAnchor(def, anchor) {
|
|
|
33346
33523
|
return scopesMatch(def.scope_start_line, def.scope_start_column, anchor.startLine, anchor.startColumn) || scopesMatch(def.start_line, def.start_column, anchor.startLine, anchor.startColumn);
|
|
33347
33524
|
}
|
|
33348
33525
|
function defVisibleInRefScopeChain(def, ref) {
|
|
33349
|
-
const
|
|
33350
|
-
if (
|
|
33351
|
-
return anchorInScopeChain(def.scope_start_line, def.scope_start_column,
|
|
33526
|
+
const chain2 = refScopeChain(ref);
|
|
33527
|
+
if (chain2.length === 0) return isModuleLevelDef2(def);
|
|
33528
|
+
return anchorInScopeChain(def.scope_start_line, def.scope_start_column, chain2) || anchorInScopeChain(def.start_line, def.start_column, chain2.slice(1));
|
|
33352
33529
|
}
|
|
33353
33530
|
function scopeDepthInChain(def, ref) {
|
|
33354
|
-
const
|
|
33355
|
-
for (let index = 0; index <
|
|
33356
|
-
const anchor =
|
|
33531
|
+
const chain2 = refScopeChain(ref);
|
|
33532
|
+
for (let index = 0; index < chain2.length; index++) {
|
|
33533
|
+
const anchor = chain2[index];
|
|
33357
33534
|
if (defAtScopeAnchor(def, anchor)) return index;
|
|
33358
33535
|
}
|
|
33359
|
-
return
|
|
33536
|
+
return chain2.length;
|
|
33360
33537
|
}
|
|
33361
33538
|
|
|
33362
33539
|
// src/code-nav/resolution/navigation/confidence.ts
|
|
@@ -33522,9 +33699,9 @@ function resolveScopeLevelCandidates(defs) {
|
|
|
33522
33699
|
function resolveLocalDefinitions(ref, fileDefs) {
|
|
33523
33700
|
const named = fileDefs.filter((def) => def.name === ref.name && declaredBeforeRef(def, ref));
|
|
33524
33701
|
if (named.length === 0) return [];
|
|
33525
|
-
const
|
|
33526
|
-
if (
|
|
33527
|
-
for (const anchor of
|
|
33702
|
+
const chain2 = refScopeChain(ref);
|
|
33703
|
+
if (chain2.length > 0) {
|
|
33704
|
+
for (const anchor of chain2) {
|
|
33528
33705
|
const atLevel = named.filter((def) => defAtScopeAnchor(def, anchor));
|
|
33529
33706
|
if (atLevel.length > 0) return resolveScopeLevelCandidates(atLevel);
|
|
33530
33707
|
}
|
|
@@ -33539,10 +33716,10 @@ function resolveLocalDefinitions(ref, fileDefs) {
|
|
|
33539
33716
|
function resolveLocalDefinitionCandidates(ref, fileDefs) {
|
|
33540
33717
|
const named = fileDefs.filter((def) => def.name === ref.name && declaredBeforeRef(def, ref));
|
|
33541
33718
|
if (named.length === 0) return [];
|
|
33542
|
-
const
|
|
33543
|
-
if (
|
|
33719
|
+
const chain2 = refScopeChain(ref);
|
|
33720
|
+
if (chain2.length === 0) return resolveScopeLevelCandidates(named.filter((def) => isModuleLevelDef2(def)));
|
|
33544
33721
|
const visible = named.filter((def) => {
|
|
33545
|
-
if (
|
|
33722
|
+
if (chain2.some((anchor) => defAtScopeAnchor(def, anchor))) return true;
|
|
33546
33723
|
if (defVisibleInRefScopeChain(def, ref)) return true;
|
|
33547
33724
|
return isModuleLevelDef2(def);
|
|
33548
33725
|
});
|
|
@@ -33723,32 +33900,41 @@ function pickPrimaryTagAtPosition(rows, filePath, line, column) {
|
|
|
33723
33900
|
async function queryDefinitionsNavigation(parentPath, filePath, line, column) {
|
|
33724
33901
|
await yieldToEventLoop();
|
|
33725
33902
|
const resolved = normalizeResolvedPath(parentPath);
|
|
33726
|
-
const
|
|
33903
|
+
const snapshot = await withCodeNavCacheSqlite((db) => {
|
|
33727
33904
|
const ctx = getSymbolIndexParentContext(db, resolved);
|
|
33728
33905
|
if (ctx == null) return null;
|
|
33729
33906
|
const fileRows = loadFileTags(db, ctx, filePath);
|
|
33730
33907
|
const primary = pickPrimaryTagAtPosition(fileRows, filePath, line, column);
|
|
33731
33908
|
if (!primary) return null;
|
|
33732
33909
|
const atPos = findTagsAtPosition(fileRows, filePath, line, column);
|
|
33733
|
-
|
|
33734
|
-
return { definitions: [modulePathLocation(primary)], confidentTarget: true };
|
|
33735
|
-
}
|
|
33736
|
-
const onDefinition = atPos.some((row) => row.role === "def");
|
|
33737
|
-
if (onDefinition) {
|
|
33738
|
-
const defs = atPos.filter((row) => row.role === "def").map(rowToLocation);
|
|
33739
|
-
return { definitions: defs, confidentTarget: defs.length === 1 };
|
|
33740
|
-
}
|
|
33741
|
-
const lookups = createNavigationLookups(db, ctx.parentId);
|
|
33910
|
+
const lookups = createSnapshotNavigationLookups(db, ctx.parentId);
|
|
33742
33911
|
const workspaceFiles = listWorkspaceFiles(db, resolved, filePath);
|
|
33743
|
-
|
|
33744
|
-
const navigation = resolveNavigation(navCtx);
|
|
33745
|
-
return {
|
|
33746
|
-
definitions: navigation.definitions.map(rowToLocation),
|
|
33747
|
-
confidentTarget: navigation.confidentTarget
|
|
33748
|
-
};
|
|
33912
|
+
return { primary, atPos, lookups, workspaceFiles };
|
|
33749
33913
|
});
|
|
33914
|
+
if (snapshot == null) {
|
|
33915
|
+
await yieldToEventLoop();
|
|
33916
|
+
return { definitions: [], confidentTarget: false };
|
|
33917
|
+
}
|
|
33918
|
+
const result = resolveDefinitionsFromSnapshot(filePath, snapshot);
|
|
33750
33919
|
await yieldToEventLoop();
|
|
33751
|
-
return result
|
|
33920
|
+
return result;
|
|
33921
|
+
}
|
|
33922
|
+
function resolveDefinitionsFromSnapshot(filePath, snapshot) {
|
|
33923
|
+
const { primary, atPos, lookups, workspaceFiles } = snapshot;
|
|
33924
|
+
if (primary.kind === "module" && primary.nav_target_path) {
|
|
33925
|
+
return { definitions: [modulePathLocation(primary)], confidentTarget: true };
|
|
33926
|
+
}
|
|
33927
|
+
const onDefinition = atPos.some((row) => row.role === "def");
|
|
33928
|
+
if (onDefinition) {
|
|
33929
|
+
const defs = atPos.filter((row) => row.role === "def").map(rowToLocation);
|
|
33930
|
+
return { definitions: defs, confidentTarget: defs.length === 1 };
|
|
33931
|
+
}
|
|
33932
|
+
const navCtx = buildNavigationContext(filePath, primary, lookups, workspaceFiles);
|
|
33933
|
+
const navigation = resolveNavigation(navCtx);
|
|
33934
|
+
return {
|
|
33935
|
+
definitions: navigation.definitions.map(rowToLocation),
|
|
33936
|
+
confidentTarget: navigation.confidentTarget
|
|
33937
|
+
};
|
|
33752
33938
|
}
|
|
33753
33939
|
async function queryDefinitionsAt(parentPath, filePath, line, column) {
|
|
33754
33940
|
return (await queryDefinitionsNavigation(parentPath, filePath, line, column)).definitions;
|
|
@@ -33761,7 +33947,7 @@ async function queryDefinitionAt(parentPath, filePath, line, column) {
|
|
|
33761
33947
|
async function queryReferencesAt(parentPath, filePath, line, column) {
|
|
33762
33948
|
await yieldToEventLoop();
|
|
33763
33949
|
const resolved = normalizeResolvedPath(parentPath);
|
|
33764
|
-
const rows =
|
|
33950
|
+
const rows = await withCodeNavCacheSqlite((db) => {
|
|
33765
33951
|
const ctx = getSymbolIndexParentContext(db, resolved);
|
|
33766
33952
|
if (ctx == null) return null;
|
|
33767
33953
|
const fileRows = loadFileTags(db, ctx, filePath);
|
|
@@ -33796,23 +33982,28 @@ function rowToSymbolSpan(row, clickable) {
|
|
|
33796
33982
|
async function querySymbolsInFile(parentPath, filePath) {
|
|
33797
33983
|
await yieldToEventLoop();
|
|
33798
33984
|
const resolved = normalizeResolvedPath(parentPath);
|
|
33799
|
-
const
|
|
33985
|
+
const snapshot = await withCodeNavCacheSqlite((db) => {
|
|
33800
33986
|
const ctx = getSymbolIndexParentContext(db, resolved);
|
|
33801
|
-
if (ctx == null) return
|
|
33987
|
+
if (ctx == null) return null;
|
|
33802
33988
|
const rows = loadFileTags(db, ctx, filePath);
|
|
33803
|
-
if (rows.length === 0) return
|
|
33804
|
-
const lookups =
|
|
33989
|
+
if (rows.length === 0) return null;
|
|
33990
|
+
const lookups = createSnapshotNavigationLookups(db, ctx.parentId);
|
|
33805
33991
|
const workspaceFiles = listWorkspaceFiles(db, resolved, filePath);
|
|
33806
|
-
|
|
33807
|
-
|
|
33808
|
-
|
|
33809
|
-
|
|
33810
|
-
|
|
33811
|
-
|
|
33812
|
-
|
|
33813
|
-
|
|
33814
|
-
|
|
33815
|
-
|
|
33992
|
+
return { rows, lookups, workspaceFiles };
|
|
33993
|
+
});
|
|
33994
|
+
if (snapshot == null) {
|
|
33995
|
+
await yieldToEventLoop();
|
|
33996
|
+
return [];
|
|
33997
|
+
}
|
|
33998
|
+
const baseCtx = buildNavigationContext(
|
|
33999
|
+
filePath,
|
|
34000
|
+
snapshot.rows[0] ?? emptyRefRow(filePath),
|
|
34001
|
+
snapshot.lookups,
|
|
34002
|
+
snapshot.workspaceFiles
|
|
34003
|
+
);
|
|
34004
|
+
const spans = snapshot.rows.map((row) => {
|
|
34005
|
+
const navCtx = { ...baseCtx, ref: row };
|
|
34006
|
+
return rowToSymbolSpan(row, refHasResolvableDefinitions(navCtx));
|
|
33816
34007
|
});
|
|
33817
34008
|
await yieldToEventLoop();
|
|
33818
34009
|
return spans;
|
|
@@ -34815,8 +35006,8 @@ async function execGitFile(args, options) {
|
|
|
34815
35006
|
}
|
|
34816
35007
|
|
|
34817
35008
|
// src/git/changes/parse/normalize-git-diff-path.ts
|
|
34818
|
-
function normalizeGitDiffPath(
|
|
34819
|
-
return
|
|
35009
|
+
function normalizeGitDiffPath(path75) {
|
|
35010
|
+
return path75.replace(/\\/g, "/").replace(/\/ +/g, "/").trim();
|
|
34820
35011
|
}
|
|
34821
35012
|
|
|
34822
35013
|
// src/git/changes/parse/parse-name-status-entries.ts
|
|
@@ -35103,9 +35294,9 @@ async function collectTurnGitDiffFromPreTurnSnapshot(options) {
|
|
|
35103
35294
|
// src/agents/acp/put-summarize-change-summaries.ts
|
|
35104
35295
|
async function putEncryptedChangeSummaryRows(params) {
|
|
35105
35296
|
const base = params.apiBaseUrl.replace(/\/+$/, "");
|
|
35106
|
-
const entries = params.rows.map(({ path:
|
|
35297
|
+
const entries = params.rows.map(({ path: path75, summary }) => {
|
|
35107
35298
|
const enc = params.e2ee.encryptFields({ summary }, ["summary"]);
|
|
35108
|
-
return { path:
|
|
35299
|
+
return { path: path75, summary: JSON.stringify(enc) };
|
|
35109
35300
|
});
|
|
35110
35301
|
const res = await fetch(
|
|
35111
35302
|
`${base}/internal/sessions/${encodeURIComponent(params.sessionId)}/follow-ups/summarize-changes`,
|
|
@@ -35940,8 +36131,8 @@ function pathspec(...paths) {
|
|
|
35940
36131
|
cache.set(key, paths);
|
|
35941
36132
|
return key;
|
|
35942
36133
|
}
|
|
35943
|
-
function isPathSpec(
|
|
35944
|
-
return
|
|
36134
|
+
function isPathSpec(path75) {
|
|
36135
|
+
return path75 instanceof String && cache.has(path75);
|
|
35945
36136
|
}
|
|
35946
36137
|
function toPaths(pathSpec) {
|
|
35947
36138
|
return cache.get(pathSpec) || [];
|
|
@@ -36030,8 +36221,8 @@ function toLinesWithContent(input = "", trimmed2 = true, separator = "\n") {
|
|
|
36030
36221
|
function forEachLineWithContent(input, callback) {
|
|
36031
36222
|
return toLinesWithContent(input, true).map((line) => callback(line));
|
|
36032
36223
|
}
|
|
36033
|
-
function folderExists(
|
|
36034
|
-
return (0, import_file_exists.exists)(
|
|
36224
|
+
function folderExists(path75) {
|
|
36225
|
+
return (0, import_file_exists.exists)(path75, import_file_exists.FOLDER);
|
|
36035
36226
|
}
|
|
36036
36227
|
function append(target, item) {
|
|
36037
36228
|
if (Array.isArray(target)) {
|
|
@@ -36435,8 +36626,8 @@ function checkIsRepoRootTask() {
|
|
|
36435
36626
|
commands,
|
|
36436
36627
|
format: "utf-8",
|
|
36437
36628
|
onError,
|
|
36438
|
-
parser(
|
|
36439
|
-
return /^\.(git)?$/.test(
|
|
36629
|
+
parser(path75) {
|
|
36630
|
+
return /^\.(git)?$/.test(path75.trim());
|
|
36440
36631
|
}
|
|
36441
36632
|
};
|
|
36442
36633
|
}
|
|
@@ -36870,11 +37061,11 @@ function parseGrep(grep) {
|
|
|
36870
37061
|
const paths = /* @__PURE__ */ new Set();
|
|
36871
37062
|
const results = {};
|
|
36872
37063
|
forEachLineWithContent(grep, (input) => {
|
|
36873
|
-
const [
|
|
36874
|
-
paths.add(
|
|
36875
|
-
(results[
|
|
37064
|
+
const [path75, line, preview] = input.split(NULL);
|
|
37065
|
+
paths.add(path75);
|
|
37066
|
+
(results[path75] = results[path75] || []).push({
|
|
36876
37067
|
line: asNumber(line),
|
|
36877
|
-
path:
|
|
37068
|
+
path: path75,
|
|
36878
37069
|
preview
|
|
36879
37070
|
});
|
|
36880
37071
|
});
|
|
@@ -37639,14 +37830,14 @@ var init_hash_object = __esm2({
|
|
|
37639
37830
|
init_task();
|
|
37640
37831
|
}
|
|
37641
37832
|
});
|
|
37642
|
-
function parseInit(bare,
|
|
37833
|
+
function parseInit(bare, path75, text) {
|
|
37643
37834
|
const response = String(text).trim();
|
|
37644
37835
|
let result;
|
|
37645
37836
|
if (result = initResponseRegex.exec(response)) {
|
|
37646
|
-
return new InitSummary(bare,
|
|
37837
|
+
return new InitSummary(bare, path75, false, result[1]);
|
|
37647
37838
|
}
|
|
37648
37839
|
if (result = reInitResponseRegex.exec(response)) {
|
|
37649
|
-
return new InitSummary(bare,
|
|
37840
|
+
return new InitSummary(bare, path75, true, result[1]);
|
|
37650
37841
|
}
|
|
37651
37842
|
let gitDir = "";
|
|
37652
37843
|
const tokens = response.split(" ");
|
|
@@ -37657,7 +37848,7 @@ function parseInit(bare, path73, text) {
|
|
|
37657
37848
|
break;
|
|
37658
37849
|
}
|
|
37659
37850
|
}
|
|
37660
|
-
return new InitSummary(bare,
|
|
37851
|
+
return new InitSummary(bare, path75, /^re/i.test(response), gitDir);
|
|
37661
37852
|
}
|
|
37662
37853
|
var InitSummary;
|
|
37663
37854
|
var initResponseRegex;
|
|
@@ -37666,9 +37857,9 @@ var init_InitSummary = __esm2({
|
|
|
37666
37857
|
"src/lib/responses/InitSummary.ts"() {
|
|
37667
37858
|
"use strict";
|
|
37668
37859
|
InitSummary = class {
|
|
37669
|
-
constructor(bare,
|
|
37860
|
+
constructor(bare, path75, existing, gitDir) {
|
|
37670
37861
|
this.bare = bare;
|
|
37671
|
-
this.path =
|
|
37862
|
+
this.path = path75;
|
|
37672
37863
|
this.existing = existing;
|
|
37673
37864
|
this.gitDir = gitDir;
|
|
37674
37865
|
}
|
|
@@ -37680,7 +37871,7 @@ var init_InitSummary = __esm2({
|
|
|
37680
37871
|
function hasBareCommand(command) {
|
|
37681
37872
|
return command.includes(bareCommand);
|
|
37682
37873
|
}
|
|
37683
|
-
function initTask(bare = false,
|
|
37874
|
+
function initTask(bare = false, path75, customArgs) {
|
|
37684
37875
|
const commands = ["init", ...customArgs];
|
|
37685
37876
|
if (bare && !hasBareCommand(commands)) {
|
|
37686
37877
|
commands.splice(1, 0, bareCommand);
|
|
@@ -37689,7 +37880,7 @@ function initTask(bare = false, path73, customArgs) {
|
|
|
37689
37880
|
commands,
|
|
37690
37881
|
format: "utf-8",
|
|
37691
37882
|
parser(text) {
|
|
37692
|
-
return parseInit(commands.includes("--bare"),
|
|
37883
|
+
return parseInit(commands.includes("--bare"), path75, text);
|
|
37693
37884
|
}
|
|
37694
37885
|
};
|
|
37695
37886
|
}
|
|
@@ -38505,12 +38696,12 @@ var init_FileStatusSummary = __esm2({
|
|
|
38505
38696
|
"use strict";
|
|
38506
38697
|
fromPathRegex = /^(.+)\0(.+)$/;
|
|
38507
38698
|
FileStatusSummary = class {
|
|
38508
|
-
constructor(
|
|
38509
|
-
this.path =
|
|
38699
|
+
constructor(path75, index, working_dir) {
|
|
38700
|
+
this.path = path75;
|
|
38510
38701
|
this.index = index;
|
|
38511
38702
|
this.working_dir = working_dir;
|
|
38512
38703
|
if (index === "R" || working_dir === "R") {
|
|
38513
|
-
const detail = fromPathRegex.exec(
|
|
38704
|
+
const detail = fromPathRegex.exec(path75) || [null, path75, path75];
|
|
38514
38705
|
this.from = detail[2] || "";
|
|
38515
38706
|
this.path = detail[1] || "";
|
|
38516
38707
|
}
|
|
@@ -38541,14 +38732,14 @@ function splitLine(result, lineStr) {
|
|
|
38541
38732
|
default:
|
|
38542
38733
|
return;
|
|
38543
38734
|
}
|
|
38544
|
-
function data(index, workingDir,
|
|
38735
|
+
function data(index, workingDir, path75) {
|
|
38545
38736
|
const raw = `${index}${workingDir}`;
|
|
38546
38737
|
const handler = parsers6.get(raw);
|
|
38547
38738
|
if (handler) {
|
|
38548
|
-
handler(result,
|
|
38739
|
+
handler(result, path75);
|
|
38549
38740
|
}
|
|
38550
38741
|
if (raw !== "##" && raw !== "!!") {
|
|
38551
|
-
result.files.push(new FileStatusSummary(
|
|
38742
|
+
result.files.push(new FileStatusSummary(path75, index, workingDir));
|
|
38552
38743
|
}
|
|
38553
38744
|
}
|
|
38554
38745
|
}
|
|
@@ -38821,15 +39012,15 @@ var init_simple_git_api = __esm2({
|
|
|
38821
39012
|
this._executor = _executor;
|
|
38822
39013
|
}
|
|
38823
39014
|
_runTask(task, then) {
|
|
38824
|
-
const
|
|
38825
|
-
const promise2 =
|
|
39015
|
+
const chain2 = this._executor.chain();
|
|
39016
|
+
const promise2 = chain2.push(task);
|
|
38826
39017
|
if (then) {
|
|
38827
39018
|
taskCallback(task, promise2, then);
|
|
38828
39019
|
}
|
|
38829
39020
|
return Object.create(this, {
|
|
38830
39021
|
then: { value: promise2.then.bind(promise2) },
|
|
38831
39022
|
catch: { value: promise2.catch.bind(promise2) },
|
|
38832
|
-
_executor: { value:
|
|
39023
|
+
_executor: { value: chain2 }
|
|
38833
39024
|
});
|
|
38834
39025
|
}
|
|
38835
39026
|
add(files) {
|
|
@@ -38857,9 +39048,9 @@ var init_simple_git_api = __esm2({
|
|
|
38857
39048
|
next
|
|
38858
39049
|
);
|
|
38859
39050
|
}
|
|
38860
|
-
hashObject(
|
|
39051
|
+
hashObject(path75, write) {
|
|
38861
39052
|
return this._runTask(
|
|
38862
|
-
hashObjectTask(
|
|
39053
|
+
hashObjectTask(path75, write === true),
|
|
38863
39054
|
trailingFunctionArgument(arguments)
|
|
38864
39055
|
);
|
|
38865
39056
|
}
|
|
@@ -39212,8 +39403,8 @@ var init_branch = __esm2({
|
|
|
39212
39403
|
}
|
|
39213
39404
|
});
|
|
39214
39405
|
function toPath(input) {
|
|
39215
|
-
const
|
|
39216
|
-
return
|
|
39406
|
+
const path75 = input.trim().replace(/^["']|["']$/g, "");
|
|
39407
|
+
return path75 && normalize3(path75);
|
|
39217
39408
|
}
|
|
39218
39409
|
var parseCheckIgnore;
|
|
39219
39410
|
var init_CheckIgnore = __esm2({
|
|
@@ -39527,8 +39718,8 @@ __export2(sub_module_exports, {
|
|
|
39527
39718
|
subModuleTask: () => subModuleTask,
|
|
39528
39719
|
updateSubModuleTask: () => updateSubModuleTask
|
|
39529
39720
|
});
|
|
39530
|
-
function addSubModuleTask(repo,
|
|
39531
|
-
return subModuleTask(["add", repo,
|
|
39721
|
+
function addSubModuleTask(repo, path75) {
|
|
39722
|
+
return subModuleTask(["add", repo, path75]);
|
|
39532
39723
|
}
|
|
39533
39724
|
function initSubModuleTask(customArgs) {
|
|
39534
39725
|
return subModuleTask(["init", ...customArgs]);
|
|
@@ -39861,8 +40052,8 @@ var require_git = __commonJS2({
|
|
|
39861
40052
|
}
|
|
39862
40053
|
return this._runTask(straightThroughStringTask2(command, this._trimmed), next);
|
|
39863
40054
|
};
|
|
39864
|
-
Git2.prototype.submoduleAdd = function(repo,
|
|
39865
|
-
return this._runTask(addSubModuleTask2(repo,
|
|
40055
|
+
Git2.prototype.submoduleAdd = function(repo, path75, then) {
|
|
40056
|
+
return this._runTask(addSubModuleTask2(repo, path75), trailingFunctionArgument2(arguments));
|
|
39866
40057
|
};
|
|
39867
40058
|
Git2.prototype.submoduleUpdate = function(args, then) {
|
|
39868
40059
|
return this._runTask(
|
|
@@ -40598,8 +40789,8 @@ function parseNumstatEntries(lines) {
|
|
|
40598
40789
|
}
|
|
40599
40790
|
function parseNumstat(lines) {
|
|
40600
40791
|
const m = /* @__PURE__ */ new Map();
|
|
40601
|
-
for (const [
|
|
40602
|
-
m.set(
|
|
40792
|
+
for (const [path75, entry] of parseNumstatEntries(lines)) {
|
|
40793
|
+
m.set(path75, { additions: entry.additions, deletions: entry.deletions });
|
|
40603
40794
|
}
|
|
40604
40795
|
return m;
|
|
40605
40796
|
}
|
|
@@ -42643,37 +42834,16 @@ function defaultWorktreesRootPath() {
|
|
|
42643
42834
|
}
|
|
42644
42835
|
|
|
42645
42836
|
// src/files/watch-file-index.ts
|
|
42646
|
-
import
|
|
42647
|
-
import { watch } from "node:fs";
|
|
42648
|
-
import path57 from "node:path";
|
|
42837
|
+
import path59 from "node:path";
|
|
42649
42838
|
|
|
42650
42839
|
// src/files/index/build-file-index.ts
|
|
42651
42840
|
import path55 from "node:path";
|
|
42652
42841
|
|
|
42653
42842
|
// src/files/index/file-index-sqlite-lock.ts
|
|
42654
|
-
|
|
42655
|
-
function isSqliteCorruptError2(e) {
|
|
42656
|
-
const msg = e instanceof Error ? e.message : String(e);
|
|
42657
|
-
return msg.includes("malformed") || msg.includes("database disk image is malformed") || msg.includes("corrupt");
|
|
42658
|
-
}
|
|
42659
|
-
var chain2 = Promise.resolve();
|
|
42843
|
+
var fileIndexChain = Promise.resolve();
|
|
42660
42844
|
function withFileIndexSqliteLock(fn) {
|
|
42661
|
-
const
|
|
42662
|
-
|
|
42663
|
-
return await Promise.resolve(fn());
|
|
42664
|
-
} catch (e) {
|
|
42665
|
-
if (!isSqliteCorruptError2(e)) throw e;
|
|
42666
|
-
closeAllCodeNavCacheSqliteConnections();
|
|
42667
|
-
try {
|
|
42668
|
-
fs36.unlinkSync(getCodeNavCacheSqlitePath());
|
|
42669
|
-
} catch {
|
|
42670
|
-
}
|
|
42671
|
-
chain2 = Promise.resolve();
|
|
42672
|
-
return await Promise.resolve(fn());
|
|
42673
|
-
}
|
|
42674
|
-
};
|
|
42675
|
-
const next = chain2.then(run);
|
|
42676
|
-
chain2 = next.then(
|
|
42845
|
+
const next = fileIndexChain.then(() => Promise.resolve(fn()));
|
|
42846
|
+
fileIndexChain = next.then(
|
|
42677
42847
|
() => void 0,
|
|
42678
42848
|
() => void 0
|
|
42679
42849
|
);
|
|
@@ -42694,6 +42864,14 @@ async function collectWorkspacePathsAsync(resolved) {
|
|
|
42694
42864
|
return paths;
|
|
42695
42865
|
}
|
|
42696
42866
|
|
|
42867
|
+
// src/files/index/file-index-persist-constants.ts
|
|
42868
|
+
var FILE_INDEX_INSERT_BUFFER = 2048;
|
|
42869
|
+
|
|
42870
|
+
// src/files/index/file-index-persist-shutdown.ts
|
|
42871
|
+
function assertFileIndexPersistNotShutdown() {
|
|
42872
|
+
if (isCliImmediateShutdownRequested()) throw new CliSqliteInterrupted();
|
|
42873
|
+
}
|
|
42874
|
+
|
|
42697
42875
|
// src/files/index/file-index-parent-path.ts
|
|
42698
42876
|
function upsertFileIndexParentPath(db, resolved) {
|
|
42699
42877
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -42708,57 +42886,56 @@ function upsertFileIndexParentPath(db, resolved) {
|
|
|
42708
42886
|
return Number(row.id);
|
|
42709
42887
|
}
|
|
42710
42888
|
|
|
42711
|
-
// src/files/index/
|
|
42712
|
-
|
|
42713
|
-
|
|
42714
|
-
|
|
42889
|
+
// src/files/index/file-index-persist-transaction.ts
|
|
42890
|
+
function clearFileIndexChildPaths(db, resolved) {
|
|
42891
|
+
runCodeNavCacheWriteTransaction(db, () => {
|
|
42892
|
+
const parentId = upsertFileIndexParentPath(db, resolved);
|
|
42893
|
+
db.run("DELETE FROM file_index_child_path WHERE parent_id = ?", [parentId]);
|
|
42894
|
+
});
|
|
42715
42895
|
}
|
|
42716
|
-
function
|
|
42717
|
-
return
|
|
42718
|
-
|
|
42719
|
-
db.
|
|
42896
|
+
function insertFileIndexChildPathBatch(db, resolved, paths) {
|
|
42897
|
+
return runCodeNavCacheWriteTransaction(db, () => {
|
|
42898
|
+
const parentId = upsertFileIndexParentPath(db, resolved);
|
|
42899
|
+
const ins = db.prepare(
|
|
42900
|
+
"INSERT INTO file_index_child_path (parent_id, path) VALUES (?, ?)"
|
|
42901
|
+
);
|
|
42720
42902
|
try {
|
|
42721
|
-
const
|
|
42722
|
-
|
|
42723
|
-
const ins = db.prepare("INSERT INTO file_index_child_path (parent_id, path) VALUES (?, ?)");
|
|
42724
|
-
try {
|
|
42725
|
-
let batch = 0;
|
|
42726
|
-
for (const rel of paths) {
|
|
42727
|
-
if (++batch >= FILE_INDEX_INTERRUPT_CHECK_EVERY) {
|
|
42728
|
-
batch = 0;
|
|
42729
|
-
assertNotShutdown2();
|
|
42730
|
-
}
|
|
42731
|
-
ins.run([parentId, rel]);
|
|
42732
|
-
pathCount += 1;
|
|
42733
|
-
}
|
|
42734
|
-
} finally {
|
|
42735
|
-
ins.finalize();
|
|
42903
|
+
for (const rel of paths) {
|
|
42904
|
+
ins.run([parentId, rel]);
|
|
42736
42905
|
}
|
|
42737
|
-
|
|
42738
|
-
}
|
|
42739
|
-
|
|
42740
|
-
db.run("ROLLBACK");
|
|
42741
|
-
} catch {
|
|
42742
|
-
}
|
|
42743
|
-
throw e;
|
|
42906
|
+
return paths.length;
|
|
42907
|
+
} finally {
|
|
42908
|
+
ins.finalize();
|
|
42744
42909
|
}
|
|
42745
|
-
return pathCount;
|
|
42746
42910
|
});
|
|
42747
42911
|
}
|
|
42748
42912
|
|
|
42913
|
+
// src/files/index/persist-file-index-paths.ts
|
|
42914
|
+
async function persistFileIndexPathsAsync(resolved, paths) {
|
|
42915
|
+
await withCodeNavCacheSqlite((db) => clearFileIndexChildPaths(db, resolved));
|
|
42916
|
+
let pathCount = 0;
|
|
42917
|
+
for (let offset = 0; offset < paths.length; offset += FILE_INDEX_INSERT_BUFFER) {
|
|
42918
|
+
assertFileIndexPersistNotShutdown();
|
|
42919
|
+
const batch = paths.slice(offset, offset + FILE_INDEX_INSERT_BUFFER);
|
|
42920
|
+
pathCount += await withCodeNavCacheSqlite((db) => insertFileIndexChildPathBatch(db, resolved, batch));
|
|
42921
|
+
await yieldToEventLoop();
|
|
42922
|
+
}
|
|
42923
|
+
return pathCount;
|
|
42924
|
+
}
|
|
42925
|
+
|
|
42749
42926
|
// src/files/index/build-file-index.ts
|
|
42750
|
-
function
|
|
42927
|
+
function assertNotShutdown2() {
|
|
42751
42928
|
if (isCliImmediateShutdownRequested()) throw new CliSqliteInterrupted();
|
|
42752
42929
|
}
|
|
42753
42930
|
async function buildFileIndexAsync(cwd) {
|
|
42754
|
-
|
|
42755
|
-
|
|
42756
|
-
|
|
42757
|
-
|
|
42758
|
-
|
|
42759
|
-
|
|
42760
|
-
|
|
42761
|
-
const pathCount =
|
|
42931
|
+
const resolved = path55.resolve(cwd);
|
|
42932
|
+
await yieldToEventLoop();
|
|
42933
|
+
assertNotShutdown2();
|
|
42934
|
+
const paths = await collectWorkspacePathsAsync(resolved);
|
|
42935
|
+
await yieldToEventLoop();
|
|
42936
|
+
assertNotShutdown2();
|
|
42937
|
+
return await withFileIndexSqliteLock(async () => {
|
|
42938
|
+
const pathCount = await persistFileIndexPathsAsync(resolved, paths);
|
|
42762
42939
|
return { pathCount };
|
|
42763
42940
|
});
|
|
42764
42941
|
}
|
|
@@ -42823,8 +43000,9 @@ async function ensureFileIndexAsync(cwd) {
|
|
|
42823
43000
|
return { ...await buildFileIndexAsync(resolved), fromCache: false };
|
|
42824
43001
|
}
|
|
42825
43002
|
|
|
42826
|
-
// src/files/
|
|
42827
|
-
|
|
43003
|
+
// src/files/index/file-index-fs-watcher.ts
|
|
43004
|
+
import { watch } from "node:fs";
|
|
43005
|
+
var FILE_INDEX_WATCH_DEBOUNCE_MS = 900;
|
|
42828
43006
|
function shouldIgnoreRelative(rel) {
|
|
42829
43007
|
const n = rel.replace(/\\/g, "/");
|
|
42830
43008
|
return n.split("/").some((segment) => shouldSkipWorkspaceWalkEntry(segment));
|
|
@@ -42834,7 +43012,7 @@ function attachWatchErrorLog(w) {
|
|
|
42834
43012
|
console.error("[file-index] File watcher error:", err);
|
|
42835
43013
|
});
|
|
42836
43014
|
}
|
|
42837
|
-
function
|
|
43015
|
+
function createFileIndexFsWatcher(resolved, schedule) {
|
|
42838
43016
|
const onEvent = (_event, filename) => {
|
|
42839
43017
|
if (filename != null) {
|
|
42840
43018
|
const rel = typeof filename === "string" ? filename.replace(/\\/g, "/") : filename.toString("utf8").replace(/\\/g, "/");
|
|
@@ -42861,11 +43039,15 @@ function createFsWatcher(resolved, schedule) {
|
|
|
42861
43039
|
throw e;
|
|
42862
43040
|
}
|
|
42863
43041
|
}
|
|
43042
|
+
|
|
43043
|
+
// src/files/index/file-index-incremental-symbol-updates.ts
|
|
43044
|
+
import fs36 from "node:fs";
|
|
43045
|
+
import path57 from "node:path";
|
|
42864
43046
|
async function applyIncrementalSymbolIndexUpdates(resolved, relPaths) {
|
|
42865
43047
|
for (const rel of relPaths) {
|
|
42866
43048
|
const absPath = path57.join(resolved, rel);
|
|
42867
43049
|
try {
|
|
42868
|
-
const stat3 = await
|
|
43050
|
+
const stat3 = await fs36.promises.stat(absPath);
|
|
42869
43051
|
if (stat3.isFile()) {
|
|
42870
43052
|
await updateSymbolIndexForFile(resolved, absPath);
|
|
42871
43053
|
} else {
|
|
@@ -42881,54 +43063,80 @@ async function applyIncrementalSymbolIndexUpdates(resolved, relPaths) {
|
|
|
42881
43063
|
await yieldToEventLoop();
|
|
42882
43064
|
}
|
|
42883
43065
|
}
|
|
42884
|
-
|
|
42885
|
-
|
|
42886
|
-
|
|
43066
|
+
|
|
43067
|
+
// src/files/index/file-index-initial-builds.ts
|
|
43068
|
+
import path58 from "node:path";
|
|
43069
|
+
async function runInitialIndexBuilds(cwd = getBridgeRoot()) {
|
|
43070
|
+
const resolved = path58.resolve(cwd);
|
|
43071
|
+
try {
|
|
43072
|
+
await buildFileIndexAsync(resolved);
|
|
43073
|
+
await buildSymbolIndexAsync(resolved);
|
|
43074
|
+
} catch (e) {
|
|
42887
43075
|
if (e instanceof CliSqliteInterrupted) return;
|
|
42888
43076
|
console.error("[file-index] Initial index build failed:", e);
|
|
43077
|
+
}
|
|
43078
|
+
}
|
|
43079
|
+
function scheduleInitialIndexBuilds(cwd = getBridgeRoot()) {
|
|
43080
|
+
setImmediate(() => {
|
|
43081
|
+
void runInitialIndexBuilds(cwd);
|
|
42889
43082
|
});
|
|
42890
|
-
|
|
42891
|
-
|
|
42892
|
-
|
|
42893
|
-
|
|
43083
|
+
}
|
|
43084
|
+
|
|
43085
|
+
// src/files/watch-file-index.ts
|
|
43086
|
+
var MAX_INCREMENTAL_SYMBOL_UPDATES = 512;
|
|
43087
|
+
function startFileIndexWatcher(cwd = getBridgeRoot()) {
|
|
43088
|
+
const resolved = path59.resolve(cwd);
|
|
42894
43089
|
let timer = null;
|
|
42895
43090
|
const pendingSymbolUpdates = /* @__PURE__ */ new Set();
|
|
42896
43091
|
let needsFullSymbolRebuild = false;
|
|
43092
|
+
let rebuildRunning = false;
|
|
43093
|
+
let rebuildQueued = false;
|
|
42897
43094
|
const runRebuild = () => {
|
|
42898
|
-
|
|
42899
|
-
|
|
42900
|
-
console.error("[file-index] Watch rebuild failed:", e);
|
|
42901
|
-
});
|
|
42902
|
-
if (needsFullSymbolRebuild) {
|
|
42903
|
-
needsFullSymbolRebuild = false;
|
|
42904
|
-
pendingSymbolUpdates.clear();
|
|
42905
|
-
void buildSymbolIndexAsync(resolved).catch((e) => {
|
|
42906
|
-
if (e instanceof CliSqliteInterrupted) return;
|
|
42907
|
-
console.error("[code-nav] Watch rebuild failed:", e);
|
|
42908
|
-
});
|
|
43095
|
+
if (rebuildRunning) {
|
|
43096
|
+
rebuildQueued = true;
|
|
42909
43097
|
return;
|
|
42910
43098
|
}
|
|
42911
|
-
|
|
43099
|
+
rebuildRunning = true;
|
|
43100
|
+
const fullSymbol = needsFullSymbolRebuild;
|
|
43101
|
+
needsFullSymbolRebuild = false;
|
|
43102
|
+
const relPaths = fullSymbol ? [] : [...pendingSymbolUpdates];
|
|
42912
43103
|
pendingSymbolUpdates.clear();
|
|
42913
|
-
|
|
42914
|
-
|
|
43104
|
+
void buildFileIndexAsync(resolved).then(async () => {
|
|
43105
|
+
if (fullSymbol) {
|
|
43106
|
+
await buildSymbolIndexAsync(resolved);
|
|
43107
|
+
return;
|
|
43108
|
+
}
|
|
43109
|
+
if (relPaths.length === 0) return;
|
|
43110
|
+
await applyIncrementalSymbolIndexUpdates(resolved, relPaths);
|
|
43111
|
+
}).catch((e) => {
|
|
42915
43112
|
if (e instanceof CliSqliteInterrupted) return;
|
|
42916
|
-
console.error("[
|
|
43113
|
+
console.error("[file-index] Watch rebuild failed:", e);
|
|
43114
|
+
}).finally(() => {
|
|
43115
|
+
rebuildRunning = false;
|
|
43116
|
+
if (rebuildQueued || needsFullSymbolRebuild || pendingSymbolUpdates.size > 0) {
|
|
43117
|
+
rebuildQueued = false;
|
|
43118
|
+
setImmediate(runRebuild);
|
|
43119
|
+
}
|
|
42917
43120
|
});
|
|
42918
43121
|
};
|
|
42919
43122
|
const schedule = (relPath) => {
|
|
42920
|
-
if (relPath != null) {
|
|
43123
|
+
if (relPath != null && !needsFullSymbolRebuild) {
|
|
42921
43124
|
pendingSymbolUpdates.add(relPath);
|
|
43125
|
+
if (pendingSymbolUpdates.size > MAX_INCREMENTAL_SYMBOL_UPDATES) {
|
|
43126
|
+
pendingSymbolUpdates.clear();
|
|
43127
|
+
needsFullSymbolRebuild = true;
|
|
43128
|
+
}
|
|
42922
43129
|
} else {
|
|
43130
|
+
pendingSymbolUpdates.clear();
|
|
42923
43131
|
needsFullSymbolRebuild = true;
|
|
42924
43132
|
}
|
|
42925
43133
|
if (timer) clearTimeout(timer);
|
|
42926
43134
|
timer = setTimeout(() => {
|
|
42927
43135
|
timer = null;
|
|
42928
43136
|
runRebuild();
|
|
42929
|
-
},
|
|
43137
|
+
}, FILE_INDEX_WATCH_DEBOUNCE_MS);
|
|
42930
43138
|
};
|
|
42931
|
-
const watcher =
|
|
43139
|
+
const watcher = createFileIndexFsWatcher(resolved, schedule);
|
|
42932
43140
|
return () => {
|
|
42933
43141
|
if (timer) {
|
|
42934
43142
|
clearTimeout(timer);
|
|
@@ -42939,7 +43147,7 @@ function startFileIndexWatcher(cwd = getBridgeRoot()) {
|
|
|
42939
43147
|
}
|
|
42940
43148
|
|
|
42941
43149
|
// src/connection/create-bridge-connection.ts
|
|
42942
|
-
import * as
|
|
43150
|
+
import * as path73 from "node:path";
|
|
42943
43151
|
|
|
42944
43152
|
// src/dev-servers/manager/dev-server-manager.ts
|
|
42945
43153
|
import { rm as rm2 } from "node:fs/promises";
|
|
@@ -42983,7 +43191,7 @@ function forceKillChild(proc, log2, shortId, graceMs) {
|
|
|
42983
43191
|
}
|
|
42984
43192
|
|
|
42985
43193
|
// src/dev-servers/process/wire-dev-server-child-process.ts
|
|
42986
|
-
import
|
|
43194
|
+
import fs37 from "node:fs";
|
|
42987
43195
|
|
|
42988
43196
|
// src/dev-servers/manager/forward-pipe.ts
|
|
42989
43197
|
function forwardChildPipe(childReadable, terminal, onData) {
|
|
@@ -43019,7 +43227,7 @@ function wireDevServerChildProcess(d) {
|
|
|
43019
43227
|
d.setPollInterval(void 0);
|
|
43020
43228
|
return;
|
|
43021
43229
|
}
|
|
43022
|
-
|
|
43230
|
+
fs37.readFile(d.mergedLogPath, (err, buf) => {
|
|
43023
43231
|
if (err || (d.getSpawnGeneration() ?? 0) !== d.scheduledGen) return;
|
|
43024
43232
|
if (buf.length <= d.mergedReadPos.value) return;
|
|
43025
43233
|
const chunk = Buffer.from(buf.subarray(d.mergedReadPos.value));
|
|
@@ -43057,7 +43265,7 @@ ${errTail}` : ""}`);
|
|
|
43057
43265
|
d.sendStatus(code === 0 || code == null ? "stopped" : "error", detail, tails);
|
|
43058
43266
|
};
|
|
43059
43267
|
if (mergedPath) {
|
|
43060
|
-
|
|
43268
|
+
fs37.readFile(mergedPath, (err, buf) => {
|
|
43061
43269
|
if (!err && buf.length > d.mergedReadPos.value) {
|
|
43062
43270
|
const chunk = Buffer.from(buf.subarray(d.mergedReadPos.value));
|
|
43063
43271
|
if (chunk.length > 0) {
|
|
@@ -43159,13 +43367,13 @@ function parseDevServerDefs(servers) {
|
|
|
43159
43367
|
}
|
|
43160
43368
|
|
|
43161
43369
|
// src/dev-servers/manager/shell-spawn/utils.ts
|
|
43162
|
-
import
|
|
43370
|
+
import fs38 from "node:fs";
|
|
43163
43371
|
function isSpawnEbadf(e) {
|
|
43164
43372
|
return typeof e === "object" && e !== null && "code" in e && e.code === "EBADF";
|
|
43165
43373
|
}
|
|
43166
43374
|
function rmDirQuiet(dir) {
|
|
43167
43375
|
try {
|
|
43168
|
-
|
|
43376
|
+
fs38.rmSync(dir, { recursive: true, force: true });
|
|
43169
43377
|
} catch {
|
|
43170
43378
|
}
|
|
43171
43379
|
}
|
|
@@ -43173,7 +43381,7 @@ var cachedDevNullReadFd;
|
|
|
43173
43381
|
function devNullReadFd() {
|
|
43174
43382
|
if (cachedDevNullReadFd === void 0) {
|
|
43175
43383
|
const devPath = process.platform === "win32" ? "nul" : "/dev/null";
|
|
43176
|
-
cachedDevNullReadFd =
|
|
43384
|
+
cachedDevNullReadFd = fs38.openSync(devPath, "r");
|
|
43177
43385
|
}
|
|
43178
43386
|
return cachedDevNullReadFd;
|
|
43179
43387
|
}
|
|
@@ -43247,15 +43455,15 @@ function trySpawnShellTruePiped(command, env, cwd, devNullFd, signal) {
|
|
|
43247
43455
|
|
|
43248
43456
|
// src/dev-servers/manager/shell-spawn/try-spawn-merged-log-file.ts
|
|
43249
43457
|
import { spawn as spawn7 } from "node:child_process";
|
|
43250
|
-
import
|
|
43458
|
+
import fs39 from "node:fs";
|
|
43251
43459
|
import { tmpdir } from "node:os";
|
|
43252
|
-
import
|
|
43460
|
+
import path60 from "node:path";
|
|
43253
43461
|
function trySpawnMergedLogFile(command, env, cwd, signal) {
|
|
43254
|
-
const tmpRoot =
|
|
43255
|
-
const logPath =
|
|
43462
|
+
const tmpRoot = fs39.mkdtempSync(path60.join(tmpdir(), "ba-devsrv-log-"));
|
|
43463
|
+
const logPath = path60.join(tmpRoot, "combined.log");
|
|
43256
43464
|
let logFd;
|
|
43257
43465
|
try {
|
|
43258
|
-
logFd =
|
|
43466
|
+
logFd = fs39.openSync(logPath, "a");
|
|
43259
43467
|
} catch {
|
|
43260
43468
|
rmDirQuiet(tmpRoot);
|
|
43261
43469
|
return null;
|
|
@@ -43274,7 +43482,7 @@ function trySpawnMergedLogFile(command, env, cwd, signal) {
|
|
|
43274
43482
|
} else {
|
|
43275
43483
|
proc = spawn7("/bin/sh", ["-c", command], { env, cwd, stdio, ...signal ? { signal } : {} });
|
|
43276
43484
|
}
|
|
43277
|
-
|
|
43485
|
+
fs39.closeSync(logFd);
|
|
43278
43486
|
return {
|
|
43279
43487
|
proc,
|
|
43280
43488
|
pipedStdoutStderr: true,
|
|
@@ -43283,7 +43491,7 @@ function trySpawnMergedLogFile(command, env, cwd, signal) {
|
|
|
43283
43491
|
};
|
|
43284
43492
|
} catch (e) {
|
|
43285
43493
|
try {
|
|
43286
|
-
|
|
43494
|
+
fs39.closeSync(logFd);
|
|
43287
43495
|
} catch {
|
|
43288
43496
|
}
|
|
43289
43497
|
rmDirQuiet(tmpRoot);
|
|
@@ -43294,22 +43502,22 @@ function trySpawnMergedLogFile(command, env, cwd, signal) {
|
|
|
43294
43502
|
|
|
43295
43503
|
// src/dev-servers/manager/shell-spawn/try-spawn-shell-script-log-redirect.ts
|
|
43296
43504
|
import { spawn as spawn8 } from "node:child_process";
|
|
43297
|
-
import
|
|
43505
|
+
import fs40 from "node:fs";
|
|
43298
43506
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
43299
|
-
import
|
|
43507
|
+
import path61 from "node:path";
|
|
43300
43508
|
function shSingleQuote(s) {
|
|
43301
43509
|
return `'${s.replace(/'/g, `'\\''`)}'`;
|
|
43302
43510
|
}
|
|
43303
43511
|
function trySpawnShellScriptLogRedirectUnix(command, env, cwd, signal) {
|
|
43304
|
-
const tmpRoot =
|
|
43305
|
-
const logPath =
|
|
43306
|
-
const innerPath =
|
|
43307
|
-
const runnerPath =
|
|
43512
|
+
const tmpRoot = fs40.mkdtempSync(path61.join(tmpdir2(), "ba-devsrv-sh-"));
|
|
43513
|
+
const logPath = path61.join(tmpRoot, "combined.log");
|
|
43514
|
+
const innerPath = path61.join(tmpRoot, "_cmd.sh");
|
|
43515
|
+
const runnerPath = path61.join(tmpRoot, "_run.sh");
|
|
43308
43516
|
try {
|
|
43309
|
-
|
|
43517
|
+
fs40.writeFileSync(innerPath, `#!/bin/sh
|
|
43310
43518
|
${command}
|
|
43311
43519
|
`);
|
|
43312
|
-
|
|
43520
|
+
fs40.writeFileSync(
|
|
43313
43521
|
runnerPath,
|
|
43314
43522
|
`#!/bin/sh
|
|
43315
43523
|
cd ${shSingleQuote(cwd)}
|
|
@@ -43335,13 +43543,13 @@ cd ${shSingleQuote(cwd)}
|
|
|
43335
43543
|
}
|
|
43336
43544
|
}
|
|
43337
43545
|
function trySpawnShellScriptLogRedirectWin(command, env, cwd, signal) {
|
|
43338
|
-
const tmpRoot =
|
|
43339
|
-
const logPath =
|
|
43340
|
-
const runnerPath =
|
|
43546
|
+
const tmpRoot = fs40.mkdtempSync(path61.join(tmpdir2(), "ba-devsrv-sh-"));
|
|
43547
|
+
const logPath = path61.join(tmpRoot, "combined.log");
|
|
43548
|
+
const runnerPath = path61.join(tmpRoot, "_run.bat");
|
|
43341
43549
|
const q = (p) => `"${p.replace(/"/g, '""')}"`;
|
|
43342
43550
|
const com = process.env.ComSpec || "cmd.exe";
|
|
43343
43551
|
try {
|
|
43344
|
-
|
|
43552
|
+
fs40.writeFileSync(
|
|
43345
43553
|
runnerPath,
|
|
43346
43554
|
`@ECHO OFF\r
|
|
43347
43555
|
CD /D ${q(cwd)}\r
|
|
@@ -44166,7 +44374,7 @@ function attachFirehoseAfterIdentified(ctx, params) {
|
|
|
44166
44374
|
function scheduleFirehoseRetryAfterDrop(closeMeta) {
|
|
44167
44375
|
if (state.closedByUser) return;
|
|
44168
44376
|
const meta = closeMeta ?? state.lastFirehoseReconnectCloseMeta ?? void 0;
|
|
44169
|
-
const
|
|
44377
|
+
const delay3 = applyTieredReconnectPlanAndLog(
|
|
44170
44378
|
state.firehoseOutage,
|
|
44171
44379
|
logFn,
|
|
44172
44380
|
PREVIEW_TUNNEL_SERVICE_LABEL,
|
|
@@ -44175,7 +44383,7 @@ function attachFirehoseAfterIdentified(ctx, params) {
|
|
|
44175
44383
|
meta?.reason
|
|
44176
44384
|
);
|
|
44177
44385
|
armReconnectDelayTimer({
|
|
44178
|
-
delayMs:
|
|
44386
|
+
delayMs: delay3,
|
|
44179
44387
|
bumpAttempt: () => {
|
|
44180
44388
|
state.firehoseReconnectAttempt += 1;
|
|
44181
44389
|
},
|
|
@@ -44286,17 +44494,17 @@ async function yieldSkillDiscoveryWork(entryCount) {
|
|
|
44286
44494
|
}
|
|
44287
44495
|
|
|
44288
44496
|
// src/skills/discovery/discover-local-skills.ts
|
|
44289
|
-
import
|
|
44290
|
-
import
|
|
44497
|
+
import fs41 from "node:fs";
|
|
44498
|
+
import path62 from "node:path";
|
|
44291
44499
|
function collectSkillFromDir(rel, base, name, seenKeys, out) {
|
|
44292
|
-
const dir =
|
|
44500
|
+
const dir = path62.join(base, name);
|
|
44293
44501
|
try {
|
|
44294
|
-
if (!
|
|
44502
|
+
if (!fs41.statSync(dir).isDirectory()) return;
|
|
44295
44503
|
} catch {
|
|
44296
44504
|
return;
|
|
44297
44505
|
}
|
|
44298
|
-
const skillMd =
|
|
44299
|
-
if (!
|
|
44506
|
+
const skillMd = path62.join(dir, "SKILL.md");
|
|
44507
|
+
if (!fs41.existsSync(skillMd)) return;
|
|
44300
44508
|
const key = `${rel}/${name}`;
|
|
44301
44509
|
if (seenKeys.has(key)) return;
|
|
44302
44510
|
seenKeys.add(key);
|
|
@@ -44308,11 +44516,11 @@ async function discoverLocalSkillsAsync(cwd) {
|
|
|
44308
44516
|
let work = 0;
|
|
44309
44517
|
for (const rel of SKILL_DISCOVERY_ROOTS) {
|
|
44310
44518
|
await yieldSkillDiscoveryWork(++work);
|
|
44311
|
-
const base =
|
|
44312
|
-
if (!
|
|
44519
|
+
const base = path62.join(cwd, rel);
|
|
44520
|
+
if (!fs41.existsSync(base) || !fs41.statSync(base).isDirectory()) continue;
|
|
44313
44521
|
let entries = [];
|
|
44314
44522
|
try {
|
|
44315
|
-
entries =
|
|
44523
|
+
entries = fs41.readdirSync(base);
|
|
44316
44524
|
} catch {
|
|
44317
44525
|
continue;
|
|
44318
44526
|
}
|
|
@@ -44325,16 +44533,16 @@ async function discoverLocalSkillsAsync(cwd) {
|
|
|
44325
44533
|
}
|
|
44326
44534
|
|
|
44327
44535
|
// src/skills/discovery/discover-skill-layout-roots.ts
|
|
44328
|
-
import
|
|
44329
|
-
import
|
|
44536
|
+
import fs42 from "node:fs";
|
|
44537
|
+
import path63 from "node:path";
|
|
44330
44538
|
function collectLayoutSkill(rel, base, name, skills2) {
|
|
44331
|
-
const dir =
|
|
44539
|
+
const dir = path63.join(base, name);
|
|
44332
44540
|
try {
|
|
44333
|
-
if (!
|
|
44541
|
+
if (!fs42.statSync(dir).isDirectory()) return;
|
|
44334
44542
|
} catch {
|
|
44335
44543
|
return;
|
|
44336
44544
|
}
|
|
44337
|
-
if (!
|
|
44545
|
+
if (!fs42.existsSync(path63.join(dir, "SKILL.md"))) return;
|
|
44338
44546
|
const relPath = `${rel}/${name}`.replace(/\\/g, "/");
|
|
44339
44547
|
skills2.push({ name, relPath });
|
|
44340
44548
|
}
|
|
@@ -44343,11 +44551,11 @@ async function discoverSkillLayoutRootsAsync(cwd) {
|
|
|
44343
44551
|
let work = 0;
|
|
44344
44552
|
for (const rel of SKILL_DISCOVERY_ROOTS) {
|
|
44345
44553
|
await yieldSkillDiscoveryWork(++work);
|
|
44346
|
-
const base =
|
|
44347
|
-
if (!
|
|
44554
|
+
const base = path63.join(cwd, rel);
|
|
44555
|
+
if (!fs42.existsSync(base) || !fs42.statSync(base).isDirectory()) continue;
|
|
44348
44556
|
let entries = [];
|
|
44349
44557
|
try {
|
|
44350
|
-
entries =
|
|
44558
|
+
entries = fs42.readdirSync(base);
|
|
44351
44559
|
} catch {
|
|
44352
44560
|
continue;
|
|
44353
44561
|
}
|
|
@@ -44435,27 +44643,6 @@ function buildBridgeUrl(apiUrl, workspaceId, authToken) {
|
|
|
44435
44643
|
return `${base}/ws/bridge?${params.toString()}`;
|
|
44436
44644
|
}
|
|
44437
44645
|
|
|
44438
|
-
// src/connection/report-git-repos.ts
|
|
44439
|
-
function reportGitRepos(getWs, log2) {
|
|
44440
|
-
setImmediate(() => {
|
|
44441
|
-
discoverGitRepos().then((repos) => {
|
|
44442
|
-
if (repos.length > 0) {
|
|
44443
|
-
const socket = getWs();
|
|
44444
|
-
if (socket) {
|
|
44445
|
-
sendWsMessage(socket, {
|
|
44446
|
-
type: "git_repos",
|
|
44447
|
-
repos: repos.map((r) => ({ absolutePath: r.absolutePath, remoteUrl: r.remoteUrl }))
|
|
44448
|
-
});
|
|
44449
|
-
}
|
|
44450
|
-
}
|
|
44451
|
-
}).catch((err) => {
|
|
44452
|
-
log2(
|
|
44453
|
-
`[Bridge service] Git repository discovery failed: ${err instanceof Error ? err.message : String(err)}`
|
|
44454
|
-
);
|
|
44455
|
-
});
|
|
44456
|
-
});
|
|
44457
|
-
}
|
|
44458
|
-
|
|
44459
44646
|
// src/types/api-to-bridge-messages.ts
|
|
44460
44647
|
var API_TO_BRIDGE_MESSAGE_TYPES = [
|
|
44461
44648
|
"auth_token",
|
|
@@ -44712,11 +44899,11 @@ function syncRunningTurnQueueKeys(turns, queueKey) {
|
|
|
44712
44899
|
}
|
|
44713
44900
|
|
|
44714
44901
|
// src/prompt-turn-queue/runner/run-local-revert-before-queued-prompt.ts
|
|
44715
|
-
import
|
|
44902
|
+
import fs44 from "node:fs";
|
|
44716
44903
|
|
|
44717
44904
|
// src/git/snapshot/capture.ts
|
|
44718
|
-
import * as
|
|
44719
|
-
import * as
|
|
44905
|
+
import * as fs43 from "node:fs";
|
|
44906
|
+
import * as path64 from "node:path";
|
|
44720
44907
|
|
|
44721
44908
|
// src/git/snapshot/git.ts
|
|
44722
44909
|
async function gitStashCreate(repoRoot, log2) {
|
|
@@ -44756,7 +44943,7 @@ async function gitRun(repoRoot, args, log2, label) {
|
|
|
44756
44943
|
async function resolveSnapshotRepoRoots(options) {
|
|
44757
44944
|
const { worktreePaths, fallbackCwd, sessionId, log: log2 } = options;
|
|
44758
44945
|
if (worktreePaths?.length) {
|
|
44759
|
-
const uniq = [...new Set(worktreePaths.map((p) =>
|
|
44946
|
+
const uniq = [...new Set(worktreePaths.map((p) => path64.resolve(p)))];
|
|
44760
44947
|
return uniq;
|
|
44761
44948
|
}
|
|
44762
44949
|
try {
|
|
@@ -44764,7 +44951,7 @@ async function resolveSnapshotRepoRoots(options) {
|
|
|
44764
44951
|
const mapped = repos.map((r) => r.absolutePath);
|
|
44765
44952
|
const sid = sessionId?.trim();
|
|
44766
44953
|
if (sid) {
|
|
44767
|
-
const filtered = mapped.filter((root) =>
|
|
44954
|
+
const filtered = mapped.filter((root) => path64.basename(root) === sid);
|
|
44768
44955
|
if (filtered.length > 0) return filtered;
|
|
44769
44956
|
}
|
|
44770
44957
|
return mapped;
|
|
@@ -44786,7 +44973,7 @@ async function capturePreTurnSnapshot(options) {
|
|
|
44786
44973
|
});
|
|
44787
44974
|
const dir = snapshotsDirForCwd(agentCwd);
|
|
44788
44975
|
try {
|
|
44789
|
-
|
|
44976
|
+
fs43.mkdirSync(dir, { recursive: true });
|
|
44790
44977
|
} catch (e) {
|
|
44791
44978
|
return { ok: false, error: e instanceof Error ? e.message : String(e) };
|
|
44792
44979
|
}
|
|
@@ -44795,9 +44982,9 @@ async function capturePreTurnSnapshot(options) {
|
|
|
44795
44982
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
44796
44983
|
repos
|
|
44797
44984
|
};
|
|
44798
|
-
const filePath =
|
|
44985
|
+
const filePath = path64.join(dir, `${runId}.json`);
|
|
44799
44986
|
try {
|
|
44800
|
-
|
|
44987
|
+
fs43.writeFileSync(filePath, JSON.stringify(payload, null, 2), "utf8");
|
|
44801
44988
|
} catch (e) {
|
|
44802
44989
|
return { ok: false, error: e instanceof Error ? e.message : String(e) };
|
|
44803
44990
|
}
|
|
@@ -44810,7 +44997,7 @@ async function capturePreTurnSnapshot(options) {
|
|
|
44810
44997
|
async function applyPreTurnSnapshot(filePath, log2) {
|
|
44811
44998
|
let data;
|
|
44812
44999
|
try {
|
|
44813
|
-
const raw =
|
|
45000
|
+
const raw = fs43.readFileSync(filePath, "utf8");
|
|
44814
45001
|
data = JSON.parse(raw);
|
|
44815
45002
|
} catch (e) {
|
|
44816
45003
|
return { ok: false, error: e instanceof Error ? e.message : String(e) };
|
|
@@ -44850,7 +45037,7 @@ async function runLocalRevertBeforeQueuedPrompt(next, deps) {
|
|
|
44850
45037
|
const agentBase = deps.sessionWorktreeManager.getSessionWorktreeRootForSession(sid) ?? getBridgeRoot();
|
|
44851
45038
|
const file2 = snapshotFilePath(agentBase, tid);
|
|
44852
45039
|
try {
|
|
44853
|
-
await
|
|
45040
|
+
await fs44.promises.access(file2, fs44.constants.F_OK);
|
|
44854
45041
|
} catch {
|
|
44855
45042
|
deps.log(
|
|
44856
45043
|
`[Queue] requeued_with_revert: no pre-turn snapshot for ${tid.slice(0, 8)}\u2026; continuing without revert.`
|
|
@@ -45138,9 +45325,9 @@ function parseChangeSummarySnapshots(raw) {
|
|
|
45138
45325
|
for (const item of raw) {
|
|
45139
45326
|
if (!item || typeof item !== "object") continue;
|
|
45140
45327
|
const o = item;
|
|
45141
|
-
const
|
|
45142
|
-
if (!
|
|
45143
|
-
const row = { path:
|
|
45328
|
+
const path75 = typeof o.path === "string" && o.path.trim() !== "" ? o.path.trim() : "";
|
|
45329
|
+
if (!path75) continue;
|
|
45330
|
+
const row = { path: path75 };
|
|
45144
45331
|
if (typeof o.patchContent === "string") row.patchContent = o.patchContent;
|
|
45145
45332
|
if (typeof o.oldText === "string") row.oldText = o.oldText;
|
|
45146
45333
|
if (typeof o.newText === "string") row.newText = o.newText;
|
|
@@ -45350,8 +45537,8 @@ function randomSecret() {
|
|
|
45350
45537
|
}
|
|
45351
45538
|
return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
45352
45539
|
}
|
|
45353
|
-
async function requestPreviewApi(port, secret, method,
|
|
45354
|
-
const url2 = `http://127.0.0.1:${port}${
|
|
45540
|
+
async function requestPreviewApi(port, secret, method, path75, body) {
|
|
45541
|
+
const url2 = `http://127.0.0.1:${port}${path75}`;
|
|
45355
45542
|
const headers = {
|
|
45356
45543
|
[PREVIEW_SECRET_HEADER]: secret,
|
|
45357
45544
|
"Content-Type": "application/json"
|
|
@@ -45363,7 +45550,7 @@ async function requestPreviewApi(port, secret, method, path73, body) {
|
|
|
45363
45550
|
});
|
|
45364
45551
|
const data = await res.json().catch(() => ({}));
|
|
45365
45552
|
if (!res.ok) {
|
|
45366
|
-
throw new Error(data?.error ?? `Preview API ${method} ${
|
|
45553
|
+
throw new Error(data?.error ?? `Preview API ${method} ${path75}: ${res.status}`);
|
|
45367
45554
|
}
|
|
45368
45555
|
return data;
|
|
45369
45556
|
}
|
|
@@ -45539,14 +45726,14 @@ async function resolveFileBrowserSessionParent(sessionWorktreeManager, sessionId
|
|
|
45539
45726
|
}
|
|
45540
45727
|
|
|
45541
45728
|
// src/files/list-dir/index.ts
|
|
45542
|
-
import
|
|
45729
|
+
import fs46 from "node:fs";
|
|
45543
45730
|
|
|
45544
45731
|
// src/files/ensure-under-cwd.ts
|
|
45545
|
-
import
|
|
45732
|
+
import path65 from "node:path";
|
|
45546
45733
|
function ensureUnderCwd(relativePath, cwd = getBridgeRoot()) {
|
|
45547
|
-
const normalized =
|
|
45548
|
-
const resolved =
|
|
45549
|
-
if (!resolved.startsWith(cwd +
|
|
45734
|
+
const normalized = path65.normalize(relativePath).replace(/^(\.\/)+/, "");
|
|
45735
|
+
const resolved = path65.resolve(cwd, normalized);
|
|
45736
|
+
if (!resolved.startsWith(cwd + path65.sep) && resolved !== cwd) {
|
|
45550
45737
|
return null;
|
|
45551
45738
|
}
|
|
45552
45739
|
return resolved;
|
|
@@ -45556,15 +45743,15 @@ function ensureUnderCwd(relativePath, cwd = getBridgeRoot()) {
|
|
|
45556
45743
|
var LIST_DIR_YIELD_EVERY = 256;
|
|
45557
45744
|
|
|
45558
45745
|
// src/files/list-dir/map-dir-entry.ts
|
|
45559
|
-
import
|
|
45560
|
-
import
|
|
45746
|
+
import path66 from "node:path";
|
|
45747
|
+
import fs45 from "node:fs";
|
|
45561
45748
|
async function mapDirEntry(d, relativePath, resolved) {
|
|
45562
|
-
const entryPath =
|
|
45563
|
-
const fullPath =
|
|
45749
|
+
const entryPath = path66.join(relativePath || ".", d.name).replace(/\\/g, "/");
|
|
45750
|
+
const fullPath = path66.join(resolved, d.name);
|
|
45564
45751
|
let isDir = d.isDirectory();
|
|
45565
45752
|
if (d.isSymbolicLink()) {
|
|
45566
45753
|
try {
|
|
45567
|
-
const targetStat = await
|
|
45754
|
+
const targetStat = await fs45.promises.stat(fullPath);
|
|
45568
45755
|
isDir = targetStat.isDirectory();
|
|
45569
45756
|
} catch {
|
|
45570
45757
|
isDir = false;
|
|
@@ -45594,7 +45781,7 @@ async function listDirAsync(relativePath, sessionParentPath = getBridgeRoot()) {
|
|
|
45594
45781
|
return { error: "Path is outside working directory" };
|
|
45595
45782
|
}
|
|
45596
45783
|
try {
|
|
45597
|
-
const names = await
|
|
45784
|
+
const names = await fs46.promises.readdir(resolved, { withFileTypes: true });
|
|
45598
45785
|
const entries = [];
|
|
45599
45786
|
for (let i = 0; i < names.length; i++) {
|
|
45600
45787
|
if (i > 0 && i % LIST_DIR_YIELD_EVERY === 0) {
|
|
@@ -45610,13 +45797,13 @@ async function listDirAsync(relativePath, sessionParentPath = getBridgeRoot()) {
|
|
|
45610
45797
|
}
|
|
45611
45798
|
|
|
45612
45799
|
// src/files/handle-file-browser-search.ts
|
|
45613
|
-
import
|
|
45800
|
+
import path67 from "node:path";
|
|
45614
45801
|
var SEARCH_LIMIT = 100;
|
|
45615
45802
|
function handleFileBrowserSearch(msg, socket, e2ee, sessionWorktreeManager) {
|
|
45616
45803
|
void (async () => {
|
|
45617
45804
|
await yieldToEventLoop();
|
|
45618
45805
|
const q = typeof msg.q === "string" ? msg.q : "";
|
|
45619
|
-
const sessionParentPath =
|
|
45806
|
+
const sessionParentPath = path67.resolve(
|
|
45620
45807
|
sessionWorktreeManager != null ? await resolveFileBrowserSessionParent(sessionWorktreeManager, msg.sessionId) : getBridgeRoot()
|
|
45621
45808
|
);
|
|
45622
45809
|
if (!await bridgeFileIndexIsPopulated(sessionParentPath)) {
|
|
@@ -45720,6 +45907,19 @@ async function resolveCodeNavParentPath(sessionWorktreeManager, sessionId) {
|
|
|
45720
45907
|
}
|
|
45721
45908
|
|
|
45722
45909
|
// src/code-nav/handlers/prepare-code-nav-request.ts
|
|
45910
|
+
var CODE_NAV_INDEX_READY_WAIT_MS = 75;
|
|
45911
|
+
var CODE_NAV_INDEX_READY_POLL_MS = 15;
|
|
45912
|
+
function delay2(ms) {
|
|
45913
|
+
return new Promise((resolve34) => setTimeout(resolve34, ms));
|
|
45914
|
+
}
|
|
45915
|
+
async function waitForSymbolIndexReady(sessionParentPath, reqPath) {
|
|
45916
|
+
const deadline = Date.now() + CODE_NAV_INDEX_READY_WAIT_MS;
|
|
45917
|
+
do {
|
|
45918
|
+
if (await symbolIndexFileIsReadyAsync(sessionParentPath, reqPath)) return true;
|
|
45919
|
+
await delay2(CODE_NAV_INDEX_READY_POLL_MS);
|
|
45920
|
+
} while (Date.now() < deadline);
|
|
45921
|
+
return await symbolIndexFileIsReadyAsync(sessionParentPath, reqPath);
|
|
45922
|
+
}
|
|
45723
45923
|
async function prepareCodeNavRequest(msg, socket, e2ee, sessionWorktreeManager) {
|
|
45724
45924
|
await yieldToEventLoop();
|
|
45725
45925
|
const reqPath = msg.path.replace(/^\/+/, "") || "";
|
|
@@ -45732,12 +45932,15 @@ async function prepareCodeNavRequest(msg, socket, e2ee, sessionWorktreeManager)
|
|
|
45732
45932
|
return null;
|
|
45733
45933
|
}
|
|
45734
45934
|
const sessionParentPath = await resolveCodeNavParentPath(sessionWorktreeManager, msg.sessionId);
|
|
45735
|
-
|
|
45736
|
-
|
|
45935
|
+
await registerSymbolIndexParentAsync(sessionParentPath);
|
|
45936
|
+
scheduleSymbolIndexFile(sessionParentPath, reqPath);
|
|
45937
|
+
const indexReady = await waitForSymbolIndexReady(sessionParentPath, reqPath);
|
|
45938
|
+
if (indexReady) {
|
|
45939
|
+
const importTargets = await listDirectImportTargetsForFileAsync(sessionParentPath, reqPath);
|
|
45940
|
+
scheduleSymbolIndexImportNeighbors(sessionParentPath, importTargets);
|
|
45941
|
+
}
|
|
45942
|
+
scheduleSymbolIndexWarmup(sessionParentPath);
|
|
45737
45943
|
await yieldToEventLoop();
|
|
45738
|
-
const importTargets = listDirectImportTargetsForFile(sessionParentPath, reqPath);
|
|
45739
|
-
scheduleSymbolIndexForRequest(sessionParentPath, reqPath, importTargets);
|
|
45740
|
-
const indexReady = symbolIndexFileIsReady(sessionParentPath, reqPath);
|
|
45741
45944
|
return {
|
|
45742
45945
|
socket,
|
|
45743
45946
|
e2ee,
|
|
@@ -45801,20 +46004,22 @@ function handleCodeNavRequest(msg, socket, e2ee, sessionWorktreeManager) {
|
|
|
45801
46004
|
// src/code-nav/handlers/trigger-symbol-index-build.ts
|
|
45802
46005
|
function triggerSymbolIndexBuild(parentPath) {
|
|
45803
46006
|
setImmediate(() => {
|
|
45804
|
-
|
|
45805
|
-
|
|
45806
|
-
|
|
46007
|
+
void (async () => {
|
|
46008
|
+
const resolved = normalizeResolvedPath(parentPath);
|
|
46009
|
+
await registerSymbolIndexParentAsync(resolved);
|
|
46010
|
+
scheduleSymbolIndexWarmup(resolved);
|
|
46011
|
+
})();
|
|
45807
46012
|
});
|
|
45808
46013
|
}
|
|
45809
46014
|
|
|
45810
46015
|
// src/git/tree/resolve-repo-abs-path.ts
|
|
45811
|
-
import * as
|
|
46016
|
+
import * as path68 from "node:path";
|
|
45812
46017
|
function resolveRepoAbsPathFromBridge(repoRelPath, bridgeRoot = getBridgeRoot()) {
|
|
45813
|
-
const bridgeResolved =
|
|
46018
|
+
const bridgeResolved = path68.resolve(bridgeRoot);
|
|
45814
46019
|
const rel = repoRelPath.trim() === "." ? "" : repoRelPath.trim().replace(/\\/g, "/");
|
|
45815
|
-
const repoPath = rel === "" ? bridgeResolved :
|
|
45816
|
-
const resolved =
|
|
45817
|
-
if (!resolved.startsWith(bridgeResolved +
|
|
46020
|
+
const repoPath = rel === "" ? bridgeResolved : path68.join(bridgeResolved, rel);
|
|
46021
|
+
const resolved = path68.resolve(repoPath);
|
|
46022
|
+
if (!resolved.startsWith(bridgeResolved + path68.sep) && resolved !== bridgeResolved) {
|
|
45818
46023
|
return null;
|
|
45819
46024
|
}
|
|
45820
46025
|
return resolved;
|
|
@@ -46212,18 +46417,18 @@ async function handleFileBrowserList(socket, e2ee, id, reqPath, sessionParentPat
|
|
|
46212
46417
|
}
|
|
46213
46418
|
|
|
46214
46419
|
// src/files/read-file/resolve-file-path.ts
|
|
46215
|
-
import
|
|
46420
|
+
import fs47 from "node:fs";
|
|
46216
46421
|
async function resolveFilePathAsync(relativePath, sessionParentPath = getBridgeRoot()) {
|
|
46217
46422
|
const resolved = ensureUnderCwd(relativePath, sessionParentPath);
|
|
46218
46423
|
if (!resolved) return { error: "Path is outside working directory" };
|
|
46219
46424
|
let real;
|
|
46220
46425
|
try {
|
|
46221
|
-
real = await
|
|
46426
|
+
real = await fs47.promises.realpath(resolved);
|
|
46222
46427
|
} catch {
|
|
46223
46428
|
real = resolved;
|
|
46224
46429
|
}
|
|
46225
46430
|
try {
|
|
46226
|
-
const stat3 = await
|
|
46431
|
+
const stat3 = await fs47.promises.stat(real);
|
|
46227
46432
|
if (!stat3.isFile()) return { error: "Not a file" };
|
|
46228
46433
|
return real;
|
|
46229
46434
|
} catch (err) {
|
|
@@ -46232,11 +46437,11 @@ async function resolveFilePathAsync(relativePath, sessionParentPath = getBridgeR
|
|
|
46232
46437
|
}
|
|
46233
46438
|
|
|
46234
46439
|
// src/files/read-file/read-file-range-async.ts
|
|
46235
|
-
import
|
|
46440
|
+
import fs48 from "node:fs";
|
|
46236
46441
|
import { StringDecoder as StringDecoder2 } from "node:string_decoder";
|
|
46237
46442
|
async function readFileRangeAsync(filePath, startLine, endLine, lineOffsetIn, lineChunkSize = LINE_CHUNK_SIZE) {
|
|
46238
|
-
const fileSize = (await
|
|
46239
|
-
const fd = await
|
|
46443
|
+
const fileSize = (await fs48.promises.stat(filePath)).size;
|
|
46444
|
+
const fd = await fs48.promises.open(filePath, "r");
|
|
46240
46445
|
const bufSize = 64 * 1024;
|
|
46241
46446
|
const buf = Buffer.alloc(bufSize);
|
|
46242
46447
|
const decoder = new StringDecoder2("utf8");
|
|
@@ -46398,11 +46603,11 @@ async function readFileRangeAsync(filePath, startLine, endLine, lineOffsetIn, li
|
|
|
46398
46603
|
}
|
|
46399
46604
|
|
|
46400
46605
|
// src/files/read-file/read-file-buffer-full-async.ts
|
|
46401
|
-
import
|
|
46606
|
+
import fs49 from "node:fs";
|
|
46402
46607
|
var READ_CHUNK_BYTES = 256 * 1024;
|
|
46403
46608
|
async function readFileBufferFullAsync(filePath) {
|
|
46404
|
-
const stat3 = await
|
|
46405
|
-
const fd = await
|
|
46609
|
+
const stat3 = await fs49.promises.stat(filePath);
|
|
46610
|
+
const fd = await fs49.promises.open(filePath, "r");
|
|
46406
46611
|
const chunks = [];
|
|
46407
46612
|
let position = 0;
|
|
46408
46613
|
let bytesSinceYield = 0;
|
|
@@ -46596,8 +46801,8 @@ function isValidRemoteSkillInstallItem(item) {
|
|
|
46596
46801
|
}
|
|
46597
46802
|
|
|
46598
46803
|
// src/skills/install/install-remote-skills-async.ts
|
|
46599
|
-
import
|
|
46600
|
-
import
|
|
46804
|
+
import fs50 from "node:fs";
|
|
46805
|
+
import path69 from "node:path";
|
|
46601
46806
|
|
|
46602
46807
|
// src/skills/install/constants.ts
|
|
46603
46808
|
var INSTALL_SKILLS_YIELD_EVERY = 16;
|
|
@@ -46608,12 +46813,12 @@ async function writeInstallFileAsync(skillDir, f, filesWritten) {
|
|
|
46608
46813
|
if (++filesWritten.count % INSTALL_SKILLS_YIELD_EVERY === 0) {
|
|
46609
46814
|
await yieldToEventLoop();
|
|
46610
46815
|
}
|
|
46611
|
-
const dest =
|
|
46612
|
-
await
|
|
46816
|
+
const dest = path69.join(skillDir, f.path);
|
|
46817
|
+
await fs50.promises.mkdir(path69.dirname(dest), { recursive: true });
|
|
46613
46818
|
if (f.text !== void 0) {
|
|
46614
|
-
await
|
|
46819
|
+
await fs50.promises.writeFile(dest, f.text, "utf8");
|
|
46615
46820
|
} else if (f.base64) {
|
|
46616
|
-
await
|
|
46821
|
+
await fs50.promises.writeFile(dest, Buffer.from(f.base64, "base64"));
|
|
46617
46822
|
}
|
|
46618
46823
|
}
|
|
46619
46824
|
async function installRemoteSkillsAsync(cwd, targetDir, items) {
|
|
@@ -46625,7 +46830,7 @@ async function installRemoteSkillsAsync(cwd, targetDir, items) {
|
|
|
46625
46830
|
try {
|
|
46626
46831
|
for (const item of items) {
|
|
46627
46832
|
if (!isValidRemoteSkillInstallItem(item)) continue;
|
|
46628
|
-
const skillDir =
|
|
46833
|
+
const skillDir = path69.join(cwd, targetDir, item.skillName);
|
|
46629
46834
|
for (const f of item.files) {
|
|
46630
46835
|
await writeInstallFileAsync(skillDir, f, filesWritten);
|
|
46631
46836
|
}
|
|
@@ -46907,7 +47112,7 @@ var handleSessionDiscardedMessage = (msg, deps) => {
|
|
|
46907
47112
|
};
|
|
46908
47113
|
|
|
46909
47114
|
// src/routing/handlers/revert-turn-snapshot.ts
|
|
46910
|
-
import * as
|
|
47115
|
+
import * as fs51 from "node:fs";
|
|
46911
47116
|
var handleRevertTurnSnapshotMessage = (msg, deps) => {
|
|
46912
47117
|
const id = typeof msg.id === "string" ? msg.id : "";
|
|
46913
47118
|
const sessionId = typeof msg.sessionId === "string" ? msg.sessionId : "";
|
|
@@ -46920,7 +47125,7 @@ var handleRevertTurnSnapshotMessage = (msg, deps) => {
|
|
|
46920
47125
|
const agentBase = sessionWorktreeManager.getSessionWorktreeRootForSession(sessionId) ?? getBridgeRoot();
|
|
46921
47126
|
const file2 = snapshotFilePath(agentBase, turnId);
|
|
46922
47127
|
try {
|
|
46923
|
-
await
|
|
47128
|
+
await fs51.promises.access(file2, fs51.constants.F_OK);
|
|
46924
47129
|
} catch {
|
|
46925
47130
|
sendWsMessage(s, {
|
|
46926
47131
|
type: "revert_turn_snapshot_result",
|
|
@@ -46964,7 +47169,7 @@ var handleDevServersConfig = (msg, deps) => {
|
|
|
46964
47169
|
};
|
|
46965
47170
|
|
|
46966
47171
|
// src/git/bridge-git-context.ts
|
|
46967
|
-
import * as
|
|
47172
|
+
import * as path70 from "node:path";
|
|
46968
47173
|
|
|
46969
47174
|
// src/git/branches/get-current-branch.ts
|
|
46970
47175
|
async function getCurrentBranch(repoPath) {
|
|
@@ -47014,12 +47219,12 @@ async function listRepoBranchRefs(repoPath) {
|
|
|
47014
47219
|
// src/git/bridge-git-context.ts
|
|
47015
47220
|
function folderNameForRelPath(relPath, bridgeRoot) {
|
|
47016
47221
|
if (relPath === "." || relPath === "") {
|
|
47017
|
-
return
|
|
47222
|
+
return path70.basename(path70.resolve(bridgeRoot)) || "repo";
|
|
47018
47223
|
}
|
|
47019
|
-
return
|
|
47224
|
+
return path70.basename(relPath) || relPath;
|
|
47020
47225
|
}
|
|
47021
47226
|
async function discoverGitReposForBridgeContext(bridgeRoot) {
|
|
47022
|
-
const root =
|
|
47227
|
+
const root = path70.resolve(bridgeRoot);
|
|
47023
47228
|
if (await isGitRepoDirectory(root)) {
|
|
47024
47229
|
const remoteUrl = await getRemoteOriginUrl(root);
|
|
47025
47230
|
return [{ absolutePath: root, remoteUrl }];
|
|
@@ -47027,19 +47232,19 @@ async function discoverGitReposForBridgeContext(bridgeRoot) {
|
|
|
47027
47232
|
const [deep, shallow] = await Promise.all([discoverGitReposUnderRoot(root), discoverGitRepos(root)]);
|
|
47028
47233
|
const byPath = /* @__PURE__ */ new Map();
|
|
47029
47234
|
for (const repo of [...deep, ...shallow]) {
|
|
47030
|
-
byPath.set(
|
|
47235
|
+
byPath.set(path70.resolve(repo.absolutePath), repo);
|
|
47031
47236
|
}
|
|
47032
47237
|
return [...byPath.values()];
|
|
47033
47238
|
}
|
|
47034
47239
|
async function getBridgeGitContext(bridgeRoot = getBridgeRoot()) {
|
|
47035
|
-
const bridgeResolved =
|
|
47240
|
+
const bridgeResolved = path70.resolve(bridgeRoot);
|
|
47036
47241
|
const repos = await discoverGitReposForBridgeContext(bridgeResolved);
|
|
47037
47242
|
const rows = [];
|
|
47038
47243
|
for (let i = 0; i < repos.length; i++) {
|
|
47039
47244
|
if (i > 0) await yieldToEventLoop();
|
|
47040
47245
|
const repo = repos[i];
|
|
47041
|
-
let rel =
|
|
47042
|
-
if (rel.startsWith("..") ||
|
|
47246
|
+
let rel = path70.relative(bridgeResolved, repo.absolutePath);
|
|
47247
|
+
if (rel.startsWith("..") || path70.isAbsolute(rel)) continue;
|
|
47043
47248
|
const relPath = rel === "" ? "." : rel.replace(/\\/g, "/");
|
|
47044
47249
|
const currentBranch = await getCurrentBranch(repo.absolutePath);
|
|
47045
47250
|
const remoteUrl = repo.remoteUrl.trim() || null;
|
|
@@ -47054,11 +47259,11 @@ async function getBridgeGitContext(bridgeRoot = getBridgeRoot()) {
|
|
|
47054
47259
|
return rows;
|
|
47055
47260
|
}
|
|
47056
47261
|
async function listRepoBranchesForBridge(repoRelPath, bridgeRoot = getBridgeRoot()) {
|
|
47057
|
-
const bridgeResolved =
|
|
47262
|
+
const bridgeResolved = path70.resolve(bridgeRoot);
|
|
47058
47263
|
const rel = repoRelPath.trim() === "." ? "" : repoRelPath.trim().replace(/\\/g, "/");
|
|
47059
|
-
const repoPath = rel === "" ? bridgeResolved :
|
|
47060
|
-
const resolved =
|
|
47061
|
-
if (!resolved.startsWith(bridgeResolved +
|
|
47264
|
+
const repoPath = rel === "" ? bridgeResolved : path70.join(bridgeResolved, rel);
|
|
47265
|
+
const resolved = path70.resolve(repoPath);
|
|
47266
|
+
if (!resolved.startsWith(bridgeResolved + path70.sep) && resolved !== bridgeResolved) {
|
|
47062
47267
|
return [];
|
|
47063
47268
|
}
|
|
47064
47269
|
return listRepoBranchRefs(resolved);
|
|
@@ -47227,25 +47432,127 @@ async function refreshBridgeTokens(params) {
|
|
|
47227
47432
|
}
|
|
47228
47433
|
}
|
|
47229
47434
|
|
|
47230
|
-
// src/connection/main-bridge-
|
|
47231
|
-
function
|
|
47435
|
+
// src/connection/main-bridge-auth-refresh-handler.ts
|
|
47436
|
+
function resetAfterAuthInvalid(params) {
|
|
47437
|
+
const { state } = params;
|
|
47438
|
+
state.reconnectAttempt = 0;
|
|
47439
|
+
resetReconnectOutageTracker(state.mainOutage);
|
|
47440
|
+
state.lastReconnectCloseMeta = null;
|
|
47441
|
+
}
|
|
47442
|
+
function createMainBridgeAuthRefreshHandler(params, connect) {
|
|
47443
|
+
const { apiUrl, workspaceId, logFn, tokens, persistTokens, onAuthInvalid } = params;
|
|
47444
|
+
let authRefreshInFlight = false;
|
|
47445
|
+
return () => {
|
|
47446
|
+
if (authRefreshInFlight) return;
|
|
47447
|
+
void (async () => {
|
|
47448
|
+
authRefreshInFlight = true;
|
|
47449
|
+
try {
|
|
47450
|
+
if (tokens.refreshToken) {
|
|
47451
|
+
const next = await refreshBridgeTokens({
|
|
47452
|
+
apiUrl,
|
|
47453
|
+
workspaceId,
|
|
47454
|
+
refreshToken: tokens.refreshToken
|
|
47455
|
+
});
|
|
47456
|
+
if (next?.token && next.refreshToken) {
|
|
47457
|
+
tokens.accessToken = next.token;
|
|
47458
|
+
tokens.refreshToken = next.refreshToken;
|
|
47459
|
+
persistTokens?.({ token: tokens.accessToken, refreshToken: tokens.refreshToken });
|
|
47460
|
+
try {
|
|
47461
|
+
logFn("[Bridge service] Access token refreshed; reconnecting\u2026");
|
|
47462
|
+
} catch {
|
|
47463
|
+
}
|
|
47464
|
+
resetAfterAuthInvalid(params);
|
|
47465
|
+
params.state.logBridgeOpenAsReconnect = true;
|
|
47466
|
+
authRefreshInFlight = false;
|
|
47467
|
+
connect();
|
|
47468
|
+
return;
|
|
47469
|
+
}
|
|
47470
|
+
}
|
|
47471
|
+
authRefreshInFlight = false;
|
|
47472
|
+
resetAfterAuthInvalid(params);
|
|
47473
|
+
onAuthInvalid();
|
|
47474
|
+
} catch {
|
|
47475
|
+
authRefreshInFlight = false;
|
|
47476
|
+
resetAfterAuthInvalid(params);
|
|
47477
|
+
onAuthInvalid();
|
|
47478
|
+
}
|
|
47479
|
+
})();
|
|
47480
|
+
};
|
|
47481
|
+
}
|
|
47482
|
+
|
|
47483
|
+
// src/connection/main-bridge-ws-close-handler.ts
|
|
47484
|
+
function createMainBridgeCloseHandler(params, connect) {
|
|
47485
|
+
const { state, logFn, bridgeHeartbeat } = params;
|
|
47486
|
+
return (code, reason) => {
|
|
47487
|
+
bridgeHeartbeat?.stop();
|
|
47488
|
+
try {
|
|
47489
|
+
const was = state.currentWs;
|
|
47490
|
+
state.currentWs = null;
|
|
47491
|
+
if (was) was.removeAllListeners();
|
|
47492
|
+
const willReconnect = !state.closedByUser;
|
|
47493
|
+
if (willReconnect) {
|
|
47494
|
+
const duplicateResult = evaluateDuplicateBridgeDisconnect(
|
|
47495
|
+
state.duplicateBridgeFlap,
|
|
47496
|
+
Date.now(),
|
|
47497
|
+
code,
|
|
47498
|
+
reason
|
|
47499
|
+
);
|
|
47500
|
+
logDuplicateBridgeWarning(logFn, duplicateResult);
|
|
47501
|
+
}
|
|
47502
|
+
beginMainBridgeDeferredDisconnect(state, code, reason, logFn, willReconnect);
|
|
47503
|
+
if (willReconnect) {
|
|
47504
|
+
state.lastReconnectCloseMeta = { code, reason };
|
|
47505
|
+
try {
|
|
47506
|
+
scheduleMainBridgeReconnect(state, connect, logFn, { code, reason });
|
|
47507
|
+
} catch {
|
|
47508
|
+
}
|
|
47509
|
+
}
|
|
47510
|
+
} catch {
|
|
47511
|
+
if (!state.closedByUser) {
|
|
47512
|
+
try {
|
|
47513
|
+
scheduleMainBridgeReconnect(state, connect, logFn);
|
|
47514
|
+
} catch {
|
|
47515
|
+
}
|
|
47516
|
+
}
|
|
47517
|
+
}
|
|
47518
|
+
};
|
|
47519
|
+
}
|
|
47520
|
+
|
|
47521
|
+
// src/connection/report-git-repos.ts
|
|
47522
|
+
function reportGitRepos(getWs, log2) {
|
|
47523
|
+
setImmediate(() => {
|
|
47524
|
+
discoverGitRepos().then((repos) => {
|
|
47525
|
+
if (repos.length > 0) {
|
|
47526
|
+
const socket = getWs();
|
|
47527
|
+
if (socket) {
|
|
47528
|
+
sendWsMessage(socket, {
|
|
47529
|
+
type: "git_repos",
|
|
47530
|
+
repos: repos.map((r) => ({ absolutePath: r.absolutePath, remoteUrl: r.remoteUrl }))
|
|
47531
|
+
});
|
|
47532
|
+
}
|
|
47533
|
+
}
|
|
47534
|
+
}).catch((err) => {
|
|
47535
|
+
log2(
|
|
47536
|
+
`[Bridge service] Git repository discovery failed: ${err instanceof Error ? err.message : String(err)}`
|
|
47537
|
+
);
|
|
47538
|
+
});
|
|
47539
|
+
});
|
|
47540
|
+
}
|
|
47541
|
+
|
|
47542
|
+
// src/connection/main-bridge-ws-open-handler.ts
|
|
47543
|
+
function createMainBridgeOpenHandler(params) {
|
|
47232
47544
|
const {
|
|
47233
47545
|
state,
|
|
47234
47546
|
getWs,
|
|
47235
|
-
apiUrl,
|
|
47236
47547
|
workspaceId,
|
|
47237
47548
|
justAuthenticated,
|
|
47238
47549
|
logFn,
|
|
47239
|
-
messageDeps,
|
|
47240
47550
|
tokens,
|
|
47241
|
-
persistTokens,
|
|
47242
|
-
onAuthInvalid,
|
|
47243
47551
|
e2ee,
|
|
47244
47552
|
identifyReportedPaths,
|
|
47245
|
-
|
|
47553
|
+
onBridgeSocketOpen
|
|
47246
47554
|
} = params;
|
|
47247
|
-
|
|
47248
|
-
function handleOpen() {
|
|
47555
|
+
return () => {
|
|
47249
47556
|
recordBridgeSessionOpened(state.duplicateBridgeFlap, Date.now());
|
|
47250
47557
|
const logOpenAsPostRefreshReconnect = state.logBridgeOpenAsReconnect;
|
|
47251
47558
|
clearMainBridgeReconnectQuietOnOpen(state, logFn);
|
|
@@ -47265,6 +47572,10 @@ function createMainBridgeWebSocketLifecycle(params) {
|
|
|
47265
47572
|
...e2ee ? { e: e2ee.handshake } : {}
|
|
47266
47573
|
});
|
|
47267
47574
|
reportGitRepos(getWs, logFn);
|
|
47575
|
+
try {
|
|
47576
|
+
onBridgeSocketOpen?.();
|
|
47577
|
+
} catch {
|
|
47578
|
+
}
|
|
47268
47579
|
}
|
|
47269
47580
|
if (justAuthenticated && socket) {
|
|
47270
47581
|
logFn(
|
|
@@ -47273,41 +47584,25 @@ function createMainBridgeWebSocketLifecycle(params) {
|
|
|
47273
47584
|
logFn(` export BUILDAUTOMATON_AUTH_TOKEN="${tokens.accessToken}"`);
|
|
47274
47585
|
logFn(` export BUILDAUTOMATON_WORKSPACE_ID="${workspaceId}"`);
|
|
47275
47586
|
}
|
|
47276
|
-
}
|
|
47277
|
-
|
|
47278
|
-
|
|
47279
|
-
|
|
47280
|
-
|
|
47281
|
-
|
|
47282
|
-
|
|
47283
|
-
|
|
47284
|
-
|
|
47285
|
-
|
|
47286
|
-
|
|
47287
|
-
|
|
47288
|
-
|
|
47289
|
-
|
|
47290
|
-
|
|
47291
|
-
|
|
47292
|
-
|
|
47293
|
-
|
|
47294
|
-
|
|
47295
|
-
state.lastReconnectCloseMeta = { code, reason };
|
|
47296
|
-
try {
|
|
47297
|
-
scheduleMainBridgeReconnect(state, connect, logFn, { code, reason });
|
|
47298
|
-
} catch {
|
|
47299
|
-
}
|
|
47300
|
-
}
|
|
47301
|
-
} catch {
|
|
47302
|
-
if (!state.closedByUser) {
|
|
47303
|
-
try {
|
|
47304
|
-
scheduleMainBridgeReconnect(state, connect, logFn);
|
|
47305
|
-
} catch {
|
|
47306
|
-
}
|
|
47307
|
-
}
|
|
47308
|
-
}
|
|
47309
|
-
}
|
|
47310
|
-
function connect() {
|
|
47587
|
+
};
|
|
47588
|
+
}
|
|
47589
|
+
|
|
47590
|
+
// src/connection/main-bridge-ws-lifecycle.ts
|
|
47591
|
+
function createMainBridgeWebSocketLifecycle(params) {
|
|
47592
|
+
const {
|
|
47593
|
+
state,
|
|
47594
|
+
apiUrl,
|
|
47595
|
+
workspaceId,
|
|
47596
|
+
logFn,
|
|
47597
|
+
messageDeps,
|
|
47598
|
+
tokens,
|
|
47599
|
+
bridgeHeartbeat
|
|
47600
|
+
} = params;
|
|
47601
|
+
let connect;
|
|
47602
|
+
const handleOpen = createMainBridgeOpenHandler(params);
|
|
47603
|
+
const handleClose = createMainBridgeCloseHandler(params, () => connect());
|
|
47604
|
+
const handleAuthInvalid = createMainBridgeAuthRefreshHandler(params, () => connect());
|
|
47605
|
+
connect = () => {
|
|
47311
47606
|
if (state.closedByUser) return;
|
|
47312
47607
|
if (state.reconnectTimeout != null) {
|
|
47313
47608
|
clearTimeout(state.reconnectTimeout);
|
|
@@ -47343,48 +47638,7 @@ function createMainBridgeWebSocketLifecycle(params) {
|
|
|
47343
47638
|
onCompactHeartbeatAck: (seq) => {
|
|
47344
47639
|
messageDeps.onBridgeHeartbeatAck?.(seq);
|
|
47345
47640
|
},
|
|
47346
|
-
onAuthInvalid:
|
|
47347
|
-
if (authRefreshInFlight) return;
|
|
47348
|
-
void (async () => {
|
|
47349
|
-
authRefreshInFlight = true;
|
|
47350
|
-
try {
|
|
47351
|
-
if (tokens.refreshToken) {
|
|
47352
|
-
const next = await refreshBridgeTokens({
|
|
47353
|
-
apiUrl,
|
|
47354
|
-
workspaceId,
|
|
47355
|
-
refreshToken: tokens.refreshToken
|
|
47356
|
-
});
|
|
47357
|
-
if (next?.token && next.refreshToken) {
|
|
47358
|
-
tokens.accessToken = next.token;
|
|
47359
|
-
tokens.refreshToken = next.refreshToken;
|
|
47360
|
-
persistTokens?.({ token: tokens.accessToken, refreshToken: tokens.refreshToken });
|
|
47361
|
-
try {
|
|
47362
|
-
logFn("[Bridge service] Access token refreshed; reconnecting\u2026");
|
|
47363
|
-
} catch {
|
|
47364
|
-
}
|
|
47365
|
-
state.reconnectAttempt = 0;
|
|
47366
|
-
resetReconnectOutageTracker(state.mainOutage);
|
|
47367
|
-
state.lastReconnectCloseMeta = null;
|
|
47368
|
-
state.logBridgeOpenAsReconnect = true;
|
|
47369
|
-
authRefreshInFlight = false;
|
|
47370
|
-
connect();
|
|
47371
|
-
return;
|
|
47372
|
-
}
|
|
47373
|
-
}
|
|
47374
|
-
authRefreshInFlight = false;
|
|
47375
|
-
state.reconnectAttempt = 0;
|
|
47376
|
-
resetReconnectOutageTracker(state.mainOutage);
|
|
47377
|
-
state.lastReconnectCloseMeta = null;
|
|
47378
|
-
onAuthInvalid();
|
|
47379
|
-
} catch {
|
|
47380
|
-
authRefreshInFlight = false;
|
|
47381
|
-
state.reconnectAttempt = 0;
|
|
47382
|
-
resetReconnectOutageTracker(state.mainOutage);
|
|
47383
|
-
state.lastReconnectCloseMeta = null;
|
|
47384
|
-
onAuthInvalid();
|
|
47385
|
-
}
|
|
47386
|
-
})();
|
|
47387
|
-
},
|
|
47641
|
+
onAuthInvalid: handleAuthInvalid,
|
|
47388
47642
|
onOpen: handleOpen,
|
|
47389
47643
|
onClose: handleClose,
|
|
47390
47644
|
onError: (err) => {
|
|
@@ -47411,7 +47665,7 @@ function createMainBridgeWebSocketLifecycle(params) {
|
|
|
47411
47665
|
}
|
|
47412
47666
|
}
|
|
47413
47667
|
}
|
|
47414
|
-
}
|
|
47668
|
+
};
|
|
47415
47669
|
return { connect };
|
|
47416
47670
|
}
|
|
47417
47671
|
|
|
@@ -47501,256 +47755,6 @@ function createBridgeHeartbeatController(params) {
|
|
|
47501
47755
|
};
|
|
47502
47756
|
}
|
|
47503
47757
|
|
|
47504
|
-
// src/sqlite/hash-json-sha256.ts
|
|
47505
|
-
import { createHash as createHash2 } from "node:crypto";
|
|
47506
|
-
function hashJsonUtf8Sha256(value) {
|
|
47507
|
-
return createHash2("sha256").update(JSON.stringify(value), "utf8").digest("hex");
|
|
47508
|
-
}
|
|
47509
|
-
|
|
47510
|
-
// src/sqlite/agent-capability-cache.ts
|
|
47511
|
-
function hasNonEmptyAgentCapabilityCache(db, workspaceId, agentType) {
|
|
47512
|
-
const t = agentType.trim();
|
|
47513
|
-
if (!t) return false;
|
|
47514
|
-
try {
|
|
47515
|
-
const row = db.get(
|
|
47516
|
-
`SELECT config_options_json FROM agent_capabilities WHERE workspace_id = ? AND agent_type = ?`,
|
|
47517
|
-
[workspaceId, t]
|
|
47518
|
-
);
|
|
47519
|
-
if (row?.config_options_json == null || row.config_options_json === "") return false;
|
|
47520
|
-
const parsed = JSON.parse(row.config_options_json);
|
|
47521
|
-
return Array.isArray(parsed) && parsed.length > 0;
|
|
47522
|
-
} catch {
|
|
47523
|
-
return false;
|
|
47524
|
-
}
|
|
47525
|
-
}
|
|
47526
|
-
function upsertCliAgentCapabilityCache(db, row) {
|
|
47527
|
-
const t = row.agentType.trim();
|
|
47528
|
-
if (!t) return false;
|
|
47529
|
-
const hash = hashJsonUtf8Sha256(row.configOptions);
|
|
47530
|
-
try {
|
|
47531
|
-
const prev = db.get(
|
|
47532
|
-
`SELECT content_hash FROM agent_capabilities WHERE workspace_id = ? AND agent_type = ?`,
|
|
47533
|
-
[row.workspaceId, t]
|
|
47534
|
-
);
|
|
47535
|
-
if (prev?.content_hash === hash) return false;
|
|
47536
|
-
} catch {
|
|
47537
|
-
}
|
|
47538
|
-
const json2 = JSON.stringify(row.configOptions);
|
|
47539
|
-
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
47540
|
-
db.run(
|
|
47541
|
-
`INSERT INTO agent_capabilities (workspace_id, agent_type, config_options_json, content_hash, updated_at)
|
|
47542
|
-
VALUES (?, ?, ?, ?, ?)
|
|
47543
|
-
ON CONFLICT(workspace_id, agent_type) DO UPDATE SET
|
|
47544
|
-
config_options_json = excluded.config_options_json,
|
|
47545
|
-
content_hash = excluded.content_hash,
|
|
47546
|
-
updated_at = excluded.updated_at`,
|
|
47547
|
-
[row.workspaceId, t, json2, hash, now]
|
|
47548
|
-
);
|
|
47549
|
-
return true;
|
|
47550
|
-
}
|
|
47551
|
-
function listCliAgentCapabilityCacheForWorkspace(db, workspaceId) {
|
|
47552
|
-
const rows = db.all(
|
|
47553
|
-
`SELECT agent_type, config_options_json FROM agent_capabilities WHERE workspace_id = ?`,
|
|
47554
|
-
[workspaceId]
|
|
47555
|
-
);
|
|
47556
|
-
const out = [];
|
|
47557
|
-
for (const r of rows) {
|
|
47558
|
-
try {
|
|
47559
|
-
const parsed = JSON.parse(r.config_options_json);
|
|
47560
|
-
if (!Array.isArray(parsed) || parsed.length === 0) continue;
|
|
47561
|
-
out.push({ agentType: r.agent_type, configOptions: parsed });
|
|
47562
|
-
} catch {
|
|
47563
|
-
}
|
|
47564
|
-
}
|
|
47565
|
-
return out;
|
|
47566
|
-
}
|
|
47567
|
-
|
|
47568
|
-
// src/agents/capabilities/warmup-agent-capabilities-on-connect.ts
|
|
47569
|
-
import * as path70 from "node:path";
|
|
47570
|
-
|
|
47571
|
-
// src/agents/capabilities/probe-one-agent-type-for-capabilities.ts
|
|
47572
|
-
import * as path69 from "node:path";
|
|
47573
|
-
async function probeOneAgentTypeForCapabilities(params) {
|
|
47574
|
-
const { agentType, cwd, workspaceId, log: log2, reportAgentCapabilities, bridgeReport = true, shouldContinue } = params;
|
|
47575
|
-
const canContinue = () => shouldContinue?.() !== false;
|
|
47576
|
-
if (!canContinue()) return false;
|
|
47577
|
-
const resolved = resolveAgentCommand(agentType);
|
|
47578
|
-
if (!resolved) return false;
|
|
47579
|
-
let sqliteChanged = false;
|
|
47580
|
-
const reportedRef = { done: false };
|
|
47581
|
-
const tryReport = (co) => {
|
|
47582
|
-
if (reportedRef.done) return;
|
|
47583
|
-
if (!Array.isArray(co) || co.length === 0) return;
|
|
47584
|
-
reportedRef.done = true;
|
|
47585
|
-
let changed = false;
|
|
47586
|
-
try {
|
|
47587
|
-
changed = withCliSqliteSync(
|
|
47588
|
-
(db) => upsertCliAgentCapabilityCache(db, {
|
|
47589
|
-
workspaceId,
|
|
47590
|
-
agentType,
|
|
47591
|
-
configOptions: co
|
|
47592
|
-
})
|
|
47593
|
-
);
|
|
47594
|
-
} catch {
|
|
47595
|
-
}
|
|
47596
|
-
sqliteChanged ||= changed;
|
|
47597
|
-
if (bridgeReport && changed) {
|
|
47598
|
-
reportAgentCapabilities?.({ agentType, configOptions: co });
|
|
47599
|
-
}
|
|
47600
|
-
};
|
|
47601
|
-
let handle = null;
|
|
47602
|
-
const killTimer = setTimeout(() => {
|
|
47603
|
-
void handle?.disconnectGracefully();
|
|
47604
|
-
}, 28e3);
|
|
47605
|
-
killTimer.unref?.();
|
|
47606
|
-
try {
|
|
47607
|
-
if (!canContinue()) return false;
|
|
47608
|
-
handle = await resolved.createClient({
|
|
47609
|
-
command: resolved.command,
|
|
47610
|
-
cwd: path69.resolve(cwd),
|
|
47611
|
-
backendAgentType: agentType,
|
|
47612
|
-
sessionMode: "agent",
|
|
47613
|
-
persistedAcpSessionId: null,
|
|
47614
|
-
agentConfig: null,
|
|
47615
|
-
getActiveConfigOptions: () => null,
|
|
47616
|
-
onAcpSessionEstablished: (info) => {
|
|
47617
|
-
tryReport(info.configOptions ?? null);
|
|
47618
|
-
},
|
|
47619
|
-
onAcpConfigOptionsUpdated: (co) => {
|
|
47620
|
-
tryReport(co);
|
|
47621
|
-
},
|
|
47622
|
-
onAgentSubprocessExit: () => {
|
|
47623
|
-
},
|
|
47624
|
-
onSessionUpdate: () => {
|
|
47625
|
-
}
|
|
47626
|
-
});
|
|
47627
|
-
if (!await delayMsUnlessShutdownRequested(1200) || !canContinue()) return false;
|
|
47628
|
-
} catch (e) {
|
|
47629
|
-
log2(
|
|
47630
|
-
`[Bridge service] Agent capability probe (${agentType}): ${e instanceof Error ? e.message : String(e)}`
|
|
47631
|
-
);
|
|
47632
|
-
} finally {
|
|
47633
|
-
clearTimeout(killTimer);
|
|
47634
|
-
try {
|
|
47635
|
-
await handle?.disconnectGracefully();
|
|
47636
|
-
} catch {
|
|
47637
|
-
}
|
|
47638
|
-
}
|
|
47639
|
-
return sqliteChanged;
|
|
47640
|
-
}
|
|
47641
|
-
|
|
47642
|
-
// src/agents/capabilities/probe-agent-capabilities-for-types.ts
|
|
47643
|
-
async function probeAgentCapabilitiesForDetectedTypes(params) {
|
|
47644
|
-
const {
|
|
47645
|
-
agentTypes,
|
|
47646
|
-
cwd,
|
|
47647
|
-
workspaceId,
|
|
47648
|
-
log: log2,
|
|
47649
|
-
reportAgentCapabilities,
|
|
47650
|
-
bridgeReport = true,
|
|
47651
|
-
forceAllTypes = false,
|
|
47652
|
-
shouldContinue
|
|
47653
|
-
} = params;
|
|
47654
|
-
const canContinue = () => !isCliImmediateShutdownRequested() && shouldContinue?.() !== false;
|
|
47655
|
-
let changedCount = 0;
|
|
47656
|
-
for (let i = 0; i < agentTypes.length; i++) {
|
|
47657
|
-
if (!canContinue()) return changedCount;
|
|
47658
|
-
if (i > 0) await yieldToEventLoop();
|
|
47659
|
-
const agentType = agentTypes[i];
|
|
47660
|
-
if (!agentType.trim()) continue;
|
|
47661
|
-
if (!forceAllTypes) {
|
|
47662
|
-
try {
|
|
47663
|
-
if (process.env.BUILDAUTOMATON_FORCE_PROBE_ACP_CAPABILITIES !== "1" && await withCliSqlite((db) => hasNonEmptyAgentCapabilityCache(db, workspaceId, agentType))) {
|
|
47664
|
-
continue;
|
|
47665
|
-
}
|
|
47666
|
-
} catch {
|
|
47667
|
-
}
|
|
47668
|
-
}
|
|
47669
|
-
const changed = await probeOneAgentTypeForCapabilities({
|
|
47670
|
-
agentType,
|
|
47671
|
-
cwd,
|
|
47672
|
-
workspaceId,
|
|
47673
|
-
log: log2,
|
|
47674
|
-
reportAgentCapabilities,
|
|
47675
|
-
bridgeReport,
|
|
47676
|
-
shouldContinue: canContinue
|
|
47677
|
-
});
|
|
47678
|
-
if (changed) changedCount += 1;
|
|
47679
|
-
}
|
|
47680
|
-
return changedCount;
|
|
47681
|
-
}
|
|
47682
|
-
|
|
47683
|
-
// src/agents/capabilities/warmup-agent-capabilities-on-connect.ts
|
|
47684
|
-
async function warmupAgentCapabilitiesOnConnect(params) {
|
|
47685
|
-
const { workspaceId, log: log2, getWs } = params;
|
|
47686
|
-
const isCurrent = beginAgentCapabilityWarmupRun();
|
|
47687
|
-
if (!isCurrent()) return;
|
|
47688
|
-
const cwd = path70.resolve(getBridgeRoot());
|
|
47689
|
-
async function sendBatchFromCache() {
|
|
47690
|
-
if (!isCurrent()) return;
|
|
47691
|
-
const socket = getWs();
|
|
47692
|
-
if (!socket || socket.readyState !== wrapper_default.OPEN) return;
|
|
47693
|
-
try {
|
|
47694
|
-
const rows = await withCliSqlite((db) => listCliAgentCapabilityCacheForWorkspace(db, workspaceId));
|
|
47695
|
-
if (!isCurrent()) return;
|
|
47696
|
-
if (rows.length === 0) return;
|
|
47697
|
-
sendWsMessage(socket, {
|
|
47698
|
-
type: "agent_capabilities_batch",
|
|
47699
|
-
items: rows.map((r) => ({ agentType: r.agentType, configOptions: r.configOptions }))
|
|
47700
|
-
});
|
|
47701
|
-
} catch (e) {
|
|
47702
|
-
if (e instanceof CliSqliteInterrupted) return;
|
|
47703
|
-
log2(
|
|
47704
|
-
`[Bridge service] Agent capability batch to bridge failed: ${e instanceof Error ? e.message : String(e)}`
|
|
47705
|
-
);
|
|
47706
|
-
}
|
|
47707
|
-
}
|
|
47708
|
-
await sendBatchFromCache();
|
|
47709
|
-
if (!isCurrent()) return;
|
|
47710
|
-
let types = [];
|
|
47711
|
-
try {
|
|
47712
|
-
types = [...await detectLocalAgentTypes()];
|
|
47713
|
-
} catch (e) {
|
|
47714
|
-
log2(`[Bridge service] detectLocalAgentTypes failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
47715
|
-
}
|
|
47716
|
-
if (!isCurrent()) return;
|
|
47717
|
-
try {
|
|
47718
|
-
const n = await probeAgentCapabilitiesForDetectedTypes({
|
|
47719
|
-
agentTypes: types,
|
|
47720
|
-
cwd,
|
|
47721
|
-
workspaceId,
|
|
47722
|
-
log: log2,
|
|
47723
|
-
bridgeReport: false,
|
|
47724
|
-
forceAllTypes: false,
|
|
47725
|
-
shouldContinue: isCurrent
|
|
47726
|
-
});
|
|
47727
|
-
if (n > 0) await sendBatchFromCache();
|
|
47728
|
-
} catch (e) {
|
|
47729
|
-
if (e instanceof CliSqliteInterrupted) return;
|
|
47730
|
-
log2(`[Bridge service] Agent capability probe (missing cache) failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
47731
|
-
}
|
|
47732
|
-
if (!isCurrent()) return;
|
|
47733
|
-
void (async () => {
|
|
47734
|
-
try {
|
|
47735
|
-
await yieldToEventLoop();
|
|
47736
|
-
if (!isCurrent()) return;
|
|
47737
|
-
const n = await probeAgentCapabilitiesForDetectedTypes({
|
|
47738
|
-
agentTypes: types,
|
|
47739
|
-
cwd,
|
|
47740
|
-
workspaceId,
|
|
47741
|
-
log: log2,
|
|
47742
|
-
bridgeReport: false,
|
|
47743
|
-
forceAllTypes: true,
|
|
47744
|
-
shouldContinue: isCurrent
|
|
47745
|
-
});
|
|
47746
|
-
if (n > 0) await sendBatchFromCache();
|
|
47747
|
-
} catch (e) {
|
|
47748
|
-
if (e instanceof CliSqliteInterrupted) return;
|
|
47749
|
-
log2(`[Bridge service] Agent capability lazy refresh failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
47750
|
-
}
|
|
47751
|
-
})();
|
|
47752
|
-
}
|
|
47753
|
-
|
|
47754
47758
|
// src/mcp/tools/session-history/fork/mcp-text-result.ts
|
|
47755
47759
|
function mcpTextResult(text, isError = false) {
|
|
47756
47760
|
return { content: [{ type: "text", text }], ...isError ? { isError: true } : {} };
|
|
@@ -48135,6 +48139,327 @@ async function createBridgeAccessState(options = {}) {
|
|
|
48135
48139
|
};
|
|
48136
48140
|
}
|
|
48137
48141
|
|
|
48142
|
+
// src/agents/capabilities/warmup-agent-capabilities-on-connect.ts
|
|
48143
|
+
import * as path72 from "node:path";
|
|
48144
|
+
|
|
48145
|
+
// src/sqlite/hash-json-sha256.ts
|
|
48146
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
48147
|
+
function hashJsonUtf8Sha256(value) {
|
|
48148
|
+
return createHash2("sha256").update(JSON.stringify(value), "utf8").digest("hex");
|
|
48149
|
+
}
|
|
48150
|
+
|
|
48151
|
+
// src/sqlite/agent-capability-cache.ts
|
|
48152
|
+
function hasNonEmptyAgentCapabilityCache(db, workspaceId, agentType) {
|
|
48153
|
+
const t = agentType.trim();
|
|
48154
|
+
if (!t) return false;
|
|
48155
|
+
try {
|
|
48156
|
+
const row = db.get(
|
|
48157
|
+
`SELECT config_options_json FROM agent_capabilities WHERE workspace_id = ? AND agent_type = ?`,
|
|
48158
|
+
[workspaceId, t]
|
|
48159
|
+
);
|
|
48160
|
+
if (row?.config_options_json == null || row.config_options_json === "") return false;
|
|
48161
|
+
const parsed = JSON.parse(row.config_options_json);
|
|
48162
|
+
return Array.isArray(parsed) && parsed.length > 0;
|
|
48163
|
+
} catch {
|
|
48164
|
+
return false;
|
|
48165
|
+
}
|
|
48166
|
+
}
|
|
48167
|
+
function upsertCliAgentCapabilityCache(db, row) {
|
|
48168
|
+
const t = row.agentType.trim();
|
|
48169
|
+
if (!t) return false;
|
|
48170
|
+
const hash = hashJsonUtf8Sha256(row.configOptions);
|
|
48171
|
+
try {
|
|
48172
|
+
const prev = db.get(
|
|
48173
|
+
`SELECT content_hash FROM agent_capabilities WHERE workspace_id = ? AND agent_type = ?`,
|
|
48174
|
+
[row.workspaceId, t]
|
|
48175
|
+
);
|
|
48176
|
+
if (prev?.content_hash === hash) return false;
|
|
48177
|
+
} catch {
|
|
48178
|
+
}
|
|
48179
|
+
const json2 = JSON.stringify(row.configOptions);
|
|
48180
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
48181
|
+
db.run(
|
|
48182
|
+
`INSERT INTO agent_capabilities (workspace_id, agent_type, config_options_json, content_hash, updated_at)
|
|
48183
|
+
VALUES (?, ?, ?, ?, ?)
|
|
48184
|
+
ON CONFLICT(workspace_id, agent_type) DO UPDATE SET
|
|
48185
|
+
config_options_json = excluded.config_options_json,
|
|
48186
|
+
content_hash = excluded.content_hash,
|
|
48187
|
+
updated_at = excluded.updated_at`,
|
|
48188
|
+
[row.workspaceId, t, json2, hash, now]
|
|
48189
|
+
);
|
|
48190
|
+
return true;
|
|
48191
|
+
}
|
|
48192
|
+
function listCliAgentCapabilityCacheForWorkspace(db, workspaceId) {
|
|
48193
|
+
const rows = db.all(
|
|
48194
|
+
`SELECT agent_type, config_options_json FROM agent_capabilities WHERE workspace_id = ?`,
|
|
48195
|
+
[workspaceId]
|
|
48196
|
+
);
|
|
48197
|
+
const out = [];
|
|
48198
|
+
for (const r of rows) {
|
|
48199
|
+
try {
|
|
48200
|
+
const parsed = JSON.parse(r.config_options_json);
|
|
48201
|
+
if (!Array.isArray(parsed) || parsed.length === 0) continue;
|
|
48202
|
+
out.push({ agentType: r.agent_type, configOptions: parsed });
|
|
48203
|
+
} catch {
|
|
48204
|
+
}
|
|
48205
|
+
}
|
|
48206
|
+
return out;
|
|
48207
|
+
}
|
|
48208
|
+
|
|
48209
|
+
// src/agents/capabilities/probe-one-agent-type-for-capabilities.ts
|
|
48210
|
+
import * as path71 from "node:path";
|
|
48211
|
+
async function probeOneAgentTypeForCapabilities(params) {
|
|
48212
|
+
const { agentType, cwd, workspaceId, log: log2, reportAgentCapabilities, bridgeReport = true, shouldContinue } = params;
|
|
48213
|
+
const canContinue = () => shouldContinue?.() !== false;
|
|
48214
|
+
if (!canContinue()) return false;
|
|
48215
|
+
const resolved = resolveAgentCommand(agentType);
|
|
48216
|
+
if (!resolved) return false;
|
|
48217
|
+
let sqliteChanged = false;
|
|
48218
|
+
const reportedRef = { done: false };
|
|
48219
|
+
const tryReport = (co) => {
|
|
48220
|
+
if (reportedRef.done) return;
|
|
48221
|
+
if (!Array.isArray(co) || co.length === 0) return;
|
|
48222
|
+
reportedRef.done = true;
|
|
48223
|
+
let changed = false;
|
|
48224
|
+
try {
|
|
48225
|
+
changed = withCliSqliteSync(
|
|
48226
|
+
(db) => upsertCliAgentCapabilityCache(db, {
|
|
48227
|
+
workspaceId,
|
|
48228
|
+
agentType,
|
|
48229
|
+
configOptions: co
|
|
48230
|
+
})
|
|
48231
|
+
);
|
|
48232
|
+
} catch {
|
|
48233
|
+
}
|
|
48234
|
+
sqliteChanged ||= changed;
|
|
48235
|
+
if (bridgeReport && changed) {
|
|
48236
|
+
reportAgentCapabilities?.({ agentType, configOptions: co });
|
|
48237
|
+
}
|
|
48238
|
+
};
|
|
48239
|
+
let handle = null;
|
|
48240
|
+
const killTimer = setTimeout(() => {
|
|
48241
|
+
void handle?.disconnectGracefully();
|
|
48242
|
+
}, 28e3);
|
|
48243
|
+
killTimer.unref?.();
|
|
48244
|
+
try {
|
|
48245
|
+
if (!canContinue()) return false;
|
|
48246
|
+
handle = await resolved.createClient({
|
|
48247
|
+
command: resolved.command,
|
|
48248
|
+
cwd: path71.resolve(cwd),
|
|
48249
|
+
backendAgentType: agentType,
|
|
48250
|
+
sessionMode: "agent",
|
|
48251
|
+
persistedAcpSessionId: null,
|
|
48252
|
+
agentConfig: null,
|
|
48253
|
+
getActiveConfigOptions: () => null,
|
|
48254
|
+
onAcpSessionEstablished: (info) => {
|
|
48255
|
+
tryReport(info.configOptions ?? null);
|
|
48256
|
+
},
|
|
48257
|
+
onAcpConfigOptionsUpdated: (co) => {
|
|
48258
|
+
tryReport(co);
|
|
48259
|
+
},
|
|
48260
|
+
onAgentSubprocessExit: () => {
|
|
48261
|
+
},
|
|
48262
|
+
onSessionUpdate: () => {
|
|
48263
|
+
}
|
|
48264
|
+
});
|
|
48265
|
+
if (!await delayMsUnlessShutdownRequested(1200) || !canContinue()) return false;
|
|
48266
|
+
} catch (e) {
|
|
48267
|
+
log2(
|
|
48268
|
+
`[Bridge service] Agent capability probe (${agentType}): ${e instanceof Error ? e.message : String(e)}`
|
|
48269
|
+
);
|
|
48270
|
+
} finally {
|
|
48271
|
+
clearTimeout(killTimer);
|
|
48272
|
+
try {
|
|
48273
|
+
await handle?.disconnectGracefully();
|
|
48274
|
+
} catch {
|
|
48275
|
+
}
|
|
48276
|
+
}
|
|
48277
|
+
return sqliteChanged;
|
|
48278
|
+
}
|
|
48279
|
+
|
|
48280
|
+
// src/agents/capabilities/probe-agent-capabilities-for-types.ts
|
|
48281
|
+
async function probeAgentCapabilitiesForDetectedTypes(params) {
|
|
48282
|
+
const {
|
|
48283
|
+
agentTypes,
|
|
48284
|
+
cwd,
|
|
48285
|
+
workspaceId,
|
|
48286
|
+
log: log2,
|
|
48287
|
+
reportAgentCapabilities,
|
|
48288
|
+
bridgeReport = true,
|
|
48289
|
+
forceAllTypes = false,
|
|
48290
|
+
shouldContinue
|
|
48291
|
+
} = params;
|
|
48292
|
+
const canContinue = () => !isCliImmediateShutdownRequested() && shouldContinue?.() !== false;
|
|
48293
|
+
let changedCount = 0;
|
|
48294
|
+
for (let i = 0; i < agentTypes.length; i++) {
|
|
48295
|
+
if (!canContinue()) return changedCount;
|
|
48296
|
+
if (i > 0) await yieldToEventLoop();
|
|
48297
|
+
const agentType = agentTypes[i];
|
|
48298
|
+
if (!agentType.trim()) continue;
|
|
48299
|
+
if (!forceAllTypes) {
|
|
48300
|
+
try {
|
|
48301
|
+
if (process.env.BUILDAUTOMATON_FORCE_PROBE_ACP_CAPABILITIES !== "1" && await withCliSqlite((db) => hasNonEmptyAgentCapabilityCache(db, workspaceId, agentType))) {
|
|
48302
|
+
continue;
|
|
48303
|
+
}
|
|
48304
|
+
} catch {
|
|
48305
|
+
}
|
|
48306
|
+
}
|
|
48307
|
+
const changed = await probeOneAgentTypeForCapabilities({
|
|
48308
|
+
agentType,
|
|
48309
|
+
cwd,
|
|
48310
|
+
workspaceId,
|
|
48311
|
+
log: log2,
|
|
48312
|
+
reportAgentCapabilities,
|
|
48313
|
+
bridgeReport,
|
|
48314
|
+
shouldContinue: canContinue
|
|
48315
|
+
});
|
|
48316
|
+
if (changed) changedCount += 1;
|
|
48317
|
+
}
|
|
48318
|
+
return changedCount;
|
|
48319
|
+
}
|
|
48320
|
+
|
|
48321
|
+
// src/agents/capabilities/warmup-agent-capabilities-on-connect.ts
|
|
48322
|
+
async function warmupAgentCapabilitiesOnConnect(params) {
|
|
48323
|
+
const { workspaceId, log: log2, getWs } = params;
|
|
48324
|
+
const isCurrent = beginAgentCapabilityWarmupRun();
|
|
48325
|
+
if (!isCurrent()) return;
|
|
48326
|
+
const cwd = path72.resolve(getBridgeRoot());
|
|
48327
|
+
async function sendBatchFromCache() {
|
|
48328
|
+
if (!isCurrent()) return;
|
|
48329
|
+
const socket = getWs();
|
|
48330
|
+
if (!socket || socket.readyState !== wrapper_default.OPEN) return;
|
|
48331
|
+
try {
|
|
48332
|
+
const rows = await withCliSqlite((db) => listCliAgentCapabilityCacheForWorkspace(db, workspaceId));
|
|
48333
|
+
if (!isCurrent()) return;
|
|
48334
|
+
if (rows.length === 0) return;
|
|
48335
|
+
sendWsMessage(socket, {
|
|
48336
|
+
type: "agent_capabilities_batch",
|
|
48337
|
+
items: rows.map((r) => ({ agentType: r.agentType, configOptions: r.configOptions }))
|
|
48338
|
+
});
|
|
48339
|
+
} catch (e) {
|
|
48340
|
+
if (e instanceof CliSqliteInterrupted) return;
|
|
48341
|
+
log2(
|
|
48342
|
+
`[Bridge service] Agent capability batch to bridge failed: ${e instanceof Error ? e.message : String(e)}`
|
|
48343
|
+
);
|
|
48344
|
+
}
|
|
48345
|
+
}
|
|
48346
|
+
await sendBatchFromCache();
|
|
48347
|
+
if (!isCurrent()) return;
|
|
48348
|
+
let types = [];
|
|
48349
|
+
try {
|
|
48350
|
+
types = [...await detectLocalAgentTypes()];
|
|
48351
|
+
} catch (e) {
|
|
48352
|
+
log2(`[Bridge service] detectLocalAgentTypes failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
48353
|
+
}
|
|
48354
|
+
if (!isCurrent()) return;
|
|
48355
|
+
try {
|
|
48356
|
+
const n = await probeAgentCapabilitiesForDetectedTypes({
|
|
48357
|
+
agentTypes: types,
|
|
48358
|
+
cwd,
|
|
48359
|
+
workspaceId,
|
|
48360
|
+
log: log2,
|
|
48361
|
+
bridgeReport: false,
|
|
48362
|
+
forceAllTypes: false,
|
|
48363
|
+
shouldContinue: isCurrent
|
|
48364
|
+
});
|
|
48365
|
+
if (n > 0) await sendBatchFromCache();
|
|
48366
|
+
} catch (e) {
|
|
48367
|
+
if (e instanceof CliSqliteInterrupted) return;
|
|
48368
|
+
log2(`[Bridge service] Agent capability probe (missing cache) failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
48369
|
+
}
|
|
48370
|
+
if (!isCurrent()) return;
|
|
48371
|
+
void (async () => {
|
|
48372
|
+
try {
|
|
48373
|
+
await yieldToEventLoop();
|
|
48374
|
+
if (!isCurrent()) return;
|
|
48375
|
+
const n = await probeAgentCapabilitiesForDetectedTypes({
|
|
48376
|
+
agentTypes: types,
|
|
48377
|
+
cwd,
|
|
48378
|
+
workspaceId,
|
|
48379
|
+
log: log2,
|
|
48380
|
+
bridgeReport: false,
|
|
48381
|
+
forceAllTypes: true,
|
|
48382
|
+
shouldContinue: isCurrent
|
|
48383
|
+
});
|
|
48384
|
+
if (n > 0) await sendBatchFromCache();
|
|
48385
|
+
} catch (e) {
|
|
48386
|
+
if (e instanceof CliSqliteInterrupted) return;
|
|
48387
|
+
log2(`[Bridge service] Agent capability lazy refresh failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
48388
|
+
}
|
|
48389
|
+
})();
|
|
48390
|
+
}
|
|
48391
|
+
|
|
48392
|
+
// src/connection/create-bridge-agent-capabilities-reporter.ts
|
|
48393
|
+
function createAgentCapabilitiesReporter(params) {
|
|
48394
|
+
const { workspaceId, getWs } = params;
|
|
48395
|
+
return (info) => {
|
|
48396
|
+
if (!Array.isArray(info.configOptions) || info.configOptions.length === 0) return;
|
|
48397
|
+
setImmediate(() => {
|
|
48398
|
+
let changed = false;
|
|
48399
|
+
try {
|
|
48400
|
+
changed = withCliSqliteSync(
|
|
48401
|
+
(db) => upsertCliAgentCapabilityCache(db, {
|
|
48402
|
+
workspaceId,
|
|
48403
|
+
agentType: info.agentType,
|
|
48404
|
+
configOptions: info.configOptions
|
|
48405
|
+
})
|
|
48406
|
+
);
|
|
48407
|
+
} catch (e) {
|
|
48408
|
+
if (e instanceof CliSqliteInterrupted) return;
|
|
48409
|
+
}
|
|
48410
|
+
if (!changed) return;
|
|
48411
|
+
const socket = getWs();
|
|
48412
|
+
if (!socket || socket.readyState !== wrapper_default.OPEN) return;
|
|
48413
|
+
sendWsMessage(socket, {
|
|
48414
|
+
type: "agent_capabilities",
|
|
48415
|
+
agentType: info.agentType,
|
|
48416
|
+
configOptions: info.configOptions
|
|
48417
|
+
});
|
|
48418
|
+
});
|
|
48419
|
+
};
|
|
48420
|
+
}
|
|
48421
|
+
function createWarmupAgentCapabilitiesOnConnect(params) {
|
|
48422
|
+
return async () => {
|
|
48423
|
+
await warmupAgentCapabilitiesOnConnect(params);
|
|
48424
|
+
};
|
|
48425
|
+
}
|
|
48426
|
+
|
|
48427
|
+
// src/connection/create-bridge-message-deps.ts
|
|
48428
|
+
function createBridgeMessageDeps(params) {
|
|
48429
|
+
const {
|
|
48430
|
+
getWs,
|
|
48431
|
+
log: log2,
|
|
48432
|
+
acpManager,
|
|
48433
|
+
sessionWorktreeManager,
|
|
48434
|
+
onBridgeIdentified,
|
|
48435
|
+
bridgeHeartbeat,
|
|
48436
|
+
sendLocalSkillsReport,
|
|
48437
|
+
reportAutoDetectedAgents,
|
|
48438
|
+
warmupAgentCapabilitiesOnConnect: warmupAgentCapabilitiesOnConnect2,
|
|
48439
|
+
devServerManager,
|
|
48440
|
+
e2ee,
|
|
48441
|
+
cloudApiBaseUrl,
|
|
48442
|
+
getCloudAccessToken
|
|
48443
|
+
} = params;
|
|
48444
|
+
return {
|
|
48445
|
+
getWs,
|
|
48446
|
+
log: log2,
|
|
48447
|
+
acpManager,
|
|
48448
|
+
sessionWorktreeManager,
|
|
48449
|
+
onBridgeIdentified,
|
|
48450
|
+
onBridgeHeartbeatAck: (seq) => {
|
|
48451
|
+
bridgeHeartbeat.onAck(seq);
|
|
48452
|
+
},
|
|
48453
|
+
sendLocalSkillsReport,
|
|
48454
|
+
reportAutoDetectedAgents,
|
|
48455
|
+
warmupAgentCapabilitiesOnConnect: warmupAgentCapabilitiesOnConnect2,
|
|
48456
|
+
devServerManager,
|
|
48457
|
+
e2ee,
|
|
48458
|
+
cloudApiBaseUrl,
|
|
48459
|
+
getCloudAccessToken
|
|
48460
|
+
};
|
|
48461
|
+
}
|
|
48462
|
+
|
|
48138
48463
|
// src/connection/create-bridge-connection.ts
|
|
48139
48464
|
async function createBridgeConnection(options) {
|
|
48140
48465
|
const { apiUrl, workspaceId, justAuthenticated, onAuthInvalid, persistTokens } = options;
|
|
@@ -48168,48 +48493,36 @@ async function createBridgeConnection(options) {
|
|
|
48168
48493
|
function getWs() {
|
|
48169
48494
|
return state.currentWs;
|
|
48170
48495
|
}
|
|
48171
|
-
|
|
48172
|
-
if (!Array.isArray(info.configOptions) || info.configOptions.length === 0) return;
|
|
48173
|
-
setImmediate(() => {
|
|
48174
|
-
let changed = false;
|
|
48175
|
-
try {
|
|
48176
|
-
changed = withCliSqliteSync(
|
|
48177
|
-
(db) => upsertCliAgentCapabilityCache(db, {
|
|
48178
|
-
workspaceId,
|
|
48179
|
-
agentType: info.agentType,
|
|
48180
|
-
configOptions: info.configOptions
|
|
48181
|
-
})
|
|
48182
|
-
);
|
|
48183
|
-
} catch (e) {
|
|
48184
|
-
if (e instanceof CliSqliteInterrupted) return;
|
|
48185
|
-
}
|
|
48186
|
-
if (!changed) return;
|
|
48187
|
-
const socket = getWs();
|
|
48188
|
-
if (!socket || socket.readyState !== wrapper_default.OPEN) return;
|
|
48189
|
-
sendWsMessage(socket, {
|
|
48190
|
-
type: "agent_capabilities",
|
|
48191
|
-
agentType: info.agentType,
|
|
48192
|
-
configOptions: info.configOptions
|
|
48193
|
-
});
|
|
48194
|
-
});
|
|
48195
|
-
}
|
|
48496
|
+
const sendAgentCapabilitiesToBridge = createAgentCapabilitiesReporter({ workspaceId, getWs });
|
|
48196
48497
|
const worktreesRootPath = options.worktreesRootPath ?? defaultWorktreesRootPath();
|
|
48197
48498
|
const sessionWorktreeManager = new SessionWorktreeManager({
|
|
48198
48499
|
worktreesRootPath,
|
|
48199
48500
|
log: logFn
|
|
48200
48501
|
});
|
|
48201
48502
|
const e2ee = options.e2eCertificate ? createCliE2eeRuntime(options.e2eCertificate) : void 0;
|
|
48202
|
-
const
|
|
48503
|
+
const bridgeAccessRef = {
|
|
48504
|
+
current: null
|
|
48505
|
+
};
|
|
48506
|
+
const bridgeAccessPromise = createBridgeAccessState({
|
|
48203
48507
|
cloudApiBaseUrl: apiUrl,
|
|
48204
48508
|
getCloudAccessToken: () => tokens.accessToken,
|
|
48205
48509
|
e2ee
|
|
48510
|
+
}).then((bridgeAccess2) => {
|
|
48511
|
+
bridgeAccessRef.current = bridgeAccess2;
|
|
48512
|
+
return bridgeAccess2;
|
|
48206
48513
|
});
|
|
48207
48514
|
const acpManager = await createAcpManager({
|
|
48208
48515
|
log: logFn,
|
|
48209
|
-
getBridgeAccessPort: () =>
|
|
48516
|
+
getBridgeAccessPort: () => bridgeAccessRef.current?.getPort() ?? 0,
|
|
48210
48517
|
reportAgentCapabilities: sendAgentCapabilitiesToBridge
|
|
48211
48518
|
});
|
|
48212
48519
|
logFn("CLI running. Press Ctrl+C to exit.");
|
|
48520
|
+
let initialIndexBuildsScheduled = false;
|
|
48521
|
+
const scheduleInitialIndexBuildsOnce = () => {
|
|
48522
|
+
if (initialIndexBuildsScheduled) return;
|
|
48523
|
+
initialIndexBuildsScheduled = true;
|
|
48524
|
+
scheduleInitialIndexBuilds(getBridgeRoot());
|
|
48525
|
+
};
|
|
48213
48526
|
const devServerManager = new DevServerManager({ getWs, log: logFn, getBridgeRoot, e2ee });
|
|
48214
48527
|
const bridgeHeartbeat = createBridgeHeartbeatController({ getWs, log: logFn });
|
|
48215
48528
|
const baseOnBridgeIdentified = createOnBridgeIdentified({
|
|
@@ -48225,32 +48538,28 @@ async function createBridgeConnection(options) {
|
|
|
48225
48538
|
};
|
|
48226
48539
|
const sendLocalSkillsReport = createSendLocalSkillsReport(getWs, logFn);
|
|
48227
48540
|
const reportAutoDetectedAgents = createReportAutoDetectedAgents(getWs, logFn);
|
|
48228
|
-
const messageDeps = {
|
|
48541
|
+
const messageDeps = createBridgeMessageDeps({
|
|
48229
48542
|
getWs,
|
|
48230
48543
|
log: logFn,
|
|
48231
48544
|
acpManager,
|
|
48232
48545
|
sessionWorktreeManager,
|
|
48233
48546
|
onBridgeIdentified,
|
|
48234
|
-
|
|
48235
|
-
bridgeHeartbeat.onAck(seq);
|
|
48236
|
-
},
|
|
48547
|
+
bridgeHeartbeat,
|
|
48237
48548
|
sendLocalSkillsReport,
|
|
48238
48549
|
reportAutoDetectedAgents,
|
|
48239
|
-
warmupAgentCapabilitiesOnConnect:
|
|
48240
|
-
|
|
48241
|
-
|
|
48242
|
-
|
|
48243
|
-
|
|
48244
|
-
});
|
|
48245
|
-
},
|
|
48550
|
+
warmupAgentCapabilitiesOnConnect: createWarmupAgentCapabilitiesOnConnect({
|
|
48551
|
+
workspaceId,
|
|
48552
|
+
log: logFn,
|
|
48553
|
+
getWs
|
|
48554
|
+
}),
|
|
48246
48555
|
devServerManager,
|
|
48247
48556
|
e2ee,
|
|
48248
48557
|
cloudApiBaseUrl: apiUrl,
|
|
48249
48558
|
getCloudAccessToken: () => tokens.accessToken
|
|
48250
|
-
};
|
|
48559
|
+
});
|
|
48251
48560
|
const identifyReportedPaths = {
|
|
48252
|
-
bridgeRootPath:
|
|
48253
|
-
worktreesRootPath:
|
|
48561
|
+
bridgeRootPath: path73.resolve(getBridgeRoot()),
|
|
48562
|
+
worktreesRootPath: path73.resolve(worktreesRootPath)
|
|
48254
48563
|
};
|
|
48255
48564
|
const { connect } = createMainBridgeWebSocketLifecycle({
|
|
48256
48565
|
state,
|
|
@@ -48265,10 +48574,12 @@ async function createBridgeConnection(options) {
|
|
|
48265
48574
|
onAuthInvalid,
|
|
48266
48575
|
e2ee,
|
|
48267
48576
|
identifyReportedPaths,
|
|
48268
|
-
bridgeHeartbeat
|
|
48577
|
+
bridgeHeartbeat,
|
|
48578
|
+
onBridgeSocketOpen: scheduleInitialIndexBuildsOnce
|
|
48269
48579
|
});
|
|
48270
48580
|
connect();
|
|
48271
48581
|
const stopFileIndexWatcher = startFileIndexWatcher(getBridgeRoot());
|
|
48582
|
+
const bridgeAccess = await bridgeAccessPromise;
|
|
48272
48583
|
return {
|
|
48273
48584
|
close: async () => {
|
|
48274
48585
|
requestCliImmediateShutdown();
|
|
@@ -48505,9 +48816,9 @@ async function runCliAction(program2, opts) {
|
|
|
48505
48816
|
const firehoseServerUrl = opts.firehoseUrl ?? opts.proxyUrl ?? process.env.BUILDAUTOMATON_FIREHOSE_URL ?? process.env.BUILDAUTOMATON_PROXY_URL ?? DEFAULT_FIREHOSE_URL;
|
|
48506
48817
|
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);
|
|
48507
48818
|
if (bridgeRootOpt) {
|
|
48508
|
-
const resolvedBridgeRoot =
|
|
48819
|
+
const resolvedBridgeRoot = path74.resolve(process.cwd(), bridgeRootOpt);
|
|
48509
48820
|
try {
|
|
48510
|
-
const st =
|
|
48821
|
+
const st = fs52.statSync(resolvedBridgeRoot);
|
|
48511
48822
|
if (!st.isDirectory()) {
|
|
48512
48823
|
console.error(`Bridge root is not a directory: ${resolvedBridgeRoot}`);
|
|
48513
48824
|
process.exit(1);
|
|
@@ -48527,7 +48838,7 @@ async function runCliAction(program2, opts) {
|
|
|
48527
48838
|
);
|
|
48528
48839
|
let worktreesRootPath;
|
|
48529
48840
|
if (opts.worktreesRoot && opts.worktreesRoot.trim()) {
|
|
48530
|
-
worktreesRootPath =
|
|
48841
|
+
worktreesRootPath = path74.resolve(opts.worktreesRoot.trim());
|
|
48531
48842
|
}
|
|
48532
48843
|
const e2eCertificates = opts.e2eeCertificatesDir?.trim() ? await loadOrCreateE2eCertificates(opts.e2eeCertificatesDir.trim()) : void 0;
|
|
48533
48844
|
if (e2eCertificates) {
|