@buildautomaton/cli 0.1.63 → 0.1.64

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 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 path81 = __require("node:path");
977
- var fs56 = __require("node:fs");
976
+ var path84 = __require("node:path");
977
+ var fs59 = __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 = path81.resolve(baseDir, baseName);
1910
- if (fs56.existsSync(localBin)) return localBin;
1911
- if (sourceExt.includes(path81.extname(baseName))) return void 0;
1909
+ const localBin = path84.resolve(baseDir, baseName);
1910
+ if (fs59.existsSync(localBin)) return localBin;
1911
+ if (sourceExt.includes(path84.extname(baseName))) return void 0;
1912
1912
  const foundExt = sourceExt.find(
1913
- (ext) => fs56.existsSync(`${localBin}${ext}`)
1913
+ (ext) => fs59.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 = fs56.realpathSync(this._scriptPath);
1925
+ resolvedScriptPath = fs59.realpathSync(this._scriptPath);
1926
1926
  } catch (err) {
1927
1927
  resolvedScriptPath = this._scriptPath;
1928
1928
  }
1929
- executableDir = path81.resolve(
1930
- path81.dirname(resolvedScriptPath),
1929
+ executableDir = path84.resolve(
1930
+ path84.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 = path81.basename(
1937
+ const legacyName = path84.basename(
1938
1938
  this._scriptPath,
1939
- path81.extname(this._scriptPath)
1939
+ path84.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(path81.extname(executableFile));
1950
+ launchWithNode = sourceExt.includes(path84.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 = path81.basename(filename, path81.extname(filename));
2790
+ this._name = path84.basename(filename, path84.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(path82) {
2805
- if (path82 === void 0) return this._executableDir;
2806
- this._executableDir = path82;
2804
+ executableDir(path85) {
2805
+ if (path85 === void 0) return this._executableDir;
2806
+ this._executableDir = path85;
2807
2807
  return this;
2808
2808
  }
2809
2809
  /**
@@ -3033,6 +3033,50 @@ var require_commander = __commonJS({
3033
3033
  }
3034
3034
  });
3035
3035
 
3036
+ // src/paths/normalize-resolved-path.ts
3037
+ import fs3 from "node:fs";
3038
+ import path3 from "node:path";
3039
+ function normalizeResolvedPath(resolved) {
3040
+ const abs = path3.resolve(resolved);
3041
+ try {
3042
+ return fs3.realpathSync.native(abs);
3043
+ } catch {
3044
+ return abs;
3045
+ }
3046
+ }
3047
+ var init_normalize_resolved_path = __esm({
3048
+ "src/paths/normalize-resolved-path.ts"() {
3049
+ "use strict";
3050
+ }
3051
+ });
3052
+
3053
+ // src/files/cwd/bridge-root.ts
3054
+ function initBridgeRoot() {
3055
+ bridgeRootPath = normalizeResolvedPath(process.cwd());
3056
+ }
3057
+ function getBridgeRoot() {
3058
+ if (bridgeRootPath == null) {
3059
+ bridgeRootPath = normalizeResolvedPath(process.cwd());
3060
+ }
3061
+ return bridgeRootPath;
3062
+ }
3063
+ var bridgeRootPath;
3064
+ var init_bridge_root = __esm({
3065
+ "src/files/cwd/bridge-root.ts"() {
3066
+ "use strict";
3067
+ init_normalize_resolved_path();
3068
+ bridgeRootPath = null;
3069
+ }
3070
+ });
3071
+
3072
+ // src/files/cwd/index.ts
3073
+ var init_cwd = __esm({
3074
+ "src/files/cwd/index.ts"() {
3075
+ "use strict";
3076
+ init_bridge_root();
3077
+ }
3078
+ });
3079
+
3036
3080
  // ../../node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/constants.js
3037
3081
  var require_constants = __commonJS({
3038
3082
  "../../node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/constants.js"(exports, module) {
@@ -6649,6 +6693,16 @@ var require_websocket_server = __commonJS({
6649
6693
  }
6650
6694
  });
6651
6695
 
6696
+ // src/runtime/yield-to-event-loop.ts
6697
+ function yieldToEventLoop() {
6698
+ return new Promise((resolve37) => setImmediate(resolve37));
6699
+ }
6700
+ var init_yield_to_event_loop = __esm({
6701
+ "src/runtime/yield-to-event-loop.ts"() {
6702
+ "use strict";
6703
+ }
6704
+ });
6705
+
6652
6706
  // ../../node_modules/.pnpm/ignore@7.0.5/node_modules/ignore/index.js
6653
6707
  var require_ignore = __commonJS({
6654
6708
  "../../node_modules/.pnpm/ignore@7.0.5/node_modules/ignore/index.js"(exports, module) {
@@ -6946,7 +7000,7 @@ var require_ignore = __commonJS({
6946
7000
  // path matching.
6947
7001
  // - check `string` either `MODE_IGNORE` or `MODE_CHECK_IGNORE`
6948
7002
  // @returns {TestResult} true if a file is ignored
6949
- test(path81, checkUnignored, mode) {
7003
+ test(path84, checkUnignored, mode) {
6950
7004
  let ignored = false;
6951
7005
  let unignored = false;
6952
7006
  let matchedRule;
@@ -6955,7 +7009,7 @@ var require_ignore = __commonJS({
6955
7009
  if (unignored === negative && ignored !== unignored || negative && !ignored && !unignored && !checkUnignored) {
6956
7010
  return;
6957
7011
  }
6958
- const matched = rule[mode].test(path81);
7012
+ const matched = rule[mode].test(path84);
6959
7013
  if (!matched) {
6960
7014
  return;
6961
7015
  }
@@ -6976,17 +7030,17 @@ var require_ignore = __commonJS({
6976
7030
  var throwError = (message, Ctor) => {
6977
7031
  throw new Ctor(message);
6978
7032
  };
6979
- var checkPath = (path81, originalPath, doThrow) => {
6980
- if (!isString(path81)) {
7033
+ var checkPath = (path84, originalPath, doThrow) => {
7034
+ if (!isString(path84)) {
6981
7035
  return doThrow(
6982
7036
  `path must be a string, but got \`${originalPath}\``,
6983
7037
  TypeError
6984
7038
  );
6985
7039
  }
6986
- if (!path81) {
7040
+ if (!path84) {
6987
7041
  return doThrow(`path must not be empty`, TypeError);
6988
7042
  }
6989
- if (checkPath.isNotRelative(path81)) {
7043
+ if (checkPath.isNotRelative(path84)) {
6990
7044
  const r = "`path.relative()`d";
6991
7045
  return doThrow(
6992
7046
  `path should be a ${r} string, but got "${originalPath}"`,
@@ -6995,7 +7049,7 @@ var require_ignore = __commonJS({
6995
7049
  }
6996
7050
  return true;
6997
7051
  };
6998
- var isNotRelative = (path81) => REGEX_TEST_INVALID_PATH.test(path81);
7052
+ var isNotRelative = (path84) => REGEX_TEST_INVALID_PATH.test(path84);
6999
7053
  checkPath.isNotRelative = isNotRelative;
7000
7054
  checkPath.convert = (p) => p;
7001
7055
  var Ignore = class {
@@ -7025,19 +7079,19 @@ var require_ignore = __commonJS({
7025
7079
  }
7026
7080
  // @returns {TestResult}
7027
7081
  _test(originalPath, cache2, checkUnignored, slices) {
7028
- const path81 = originalPath && checkPath.convert(originalPath);
7082
+ const path84 = originalPath && checkPath.convert(originalPath);
7029
7083
  checkPath(
7030
- path81,
7084
+ path84,
7031
7085
  originalPath,
7032
7086
  this._strictPathCheck ? throwError : RETURN_FALSE
7033
7087
  );
7034
- return this._t(path81, cache2, checkUnignored, slices);
7088
+ return this._t(path84, cache2, checkUnignored, slices);
7035
7089
  }
7036
- checkIgnore(path81) {
7037
- if (!REGEX_TEST_TRAILING_SLASH.test(path81)) {
7038
- return this.test(path81);
7090
+ checkIgnore(path84) {
7091
+ if (!REGEX_TEST_TRAILING_SLASH.test(path84)) {
7092
+ return this.test(path84);
7039
7093
  }
7040
- const slices = path81.split(SLASH).filter(Boolean);
7094
+ const slices = path84.split(SLASH).filter(Boolean);
7041
7095
  slices.pop();
7042
7096
  if (slices.length) {
7043
7097
  const parent = this._t(
@@ -7050,18 +7104,18 @@ var require_ignore = __commonJS({
7050
7104
  return parent;
7051
7105
  }
7052
7106
  }
7053
- return this._rules.test(path81, false, MODE_CHECK_IGNORE);
7107
+ return this._rules.test(path84, false, MODE_CHECK_IGNORE);
7054
7108
  }
7055
- _t(path81, cache2, checkUnignored, slices) {
7056
- if (path81 in cache2) {
7057
- return cache2[path81];
7109
+ _t(path84, cache2, checkUnignored, slices) {
7110
+ if (path84 in cache2) {
7111
+ return cache2[path84];
7058
7112
  }
7059
7113
  if (!slices) {
7060
- slices = path81.split(SLASH).filter(Boolean);
7114
+ slices = path84.split(SLASH).filter(Boolean);
7061
7115
  }
7062
7116
  slices.pop();
7063
7117
  if (!slices.length) {
7064
- return cache2[path81] = this._rules.test(path81, checkUnignored, MODE_IGNORE);
7118
+ return cache2[path84] = this._rules.test(path84, checkUnignored, MODE_IGNORE);
7065
7119
  }
7066
7120
  const parent = this._t(
7067
7121
  slices.join(SLASH) + SLASH,
@@ -7069,29 +7123,29 @@ var require_ignore = __commonJS({
7069
7123
  checkUnignored,
7070
7124
  slices
7071
7125
  );
7072
- return cache2[path81] = parent.ignored ? parent : this._rules.test(path81, checkUnignored, MODE_IGNORE);
7126
+ return cache2[path84] = parent.ignored ? parent : this._rules.test(path84, checkUnignored, MODE_IGNORE);
7073
7127
  }
7074
- ignores(path81) {
7075
- return this._test(path81, this._ignoreCache, false).ignored;
7128
+ ignores(path84) {
7129
+ return this._test(path84, this._ignoreCache, false).ignored;
7076
7130
  }
7077
7131
  createFilter() {
7078
- return (path81) => !this.ignores(path81);
7132
+ return (path84) => !this.ignores(path84);
7079
7133
  }
7080
7134
  filter(paths) {
7081
7135
  return makeArray(paths).filter(this.createFilter());
7082
7136
  }
7083
7137
  // @returns {TestResult}
7084
- test(path81) {
7085
- return this._test(path81, this._testCache, true);
7138
+ test(path84) {
7139
+ return this._test(path84, this._testCache, true);
7086
7140
  }
7087
7141
  };
7088
7142
  var factory = (options) => new Ignore(options);
7089
- var isPathValid = (path81) => checkPath(path81 && checkPath.convert(path81), path81, RETURN_FALSE);
7143
+ var isPathValid = (path84) => checkPath(path84 && checkPath.convert(path84), path84, RETURN_FALSE);
7090
7144
  var setupWindows = () => {
7091
7145
  const makePosix = (str) => /^\\\\\?\\/.test(str) || /["<>|\u0000-\u001F]+/u.test(str) ? str : str.replace(/\\/g, "/");
7092
7146
  checkPath.convert = makePosix;
7093
7147
  const REGEX_TEST_WINDOWS_PATH_ABSOLUTE = /^[a-z]:\//i;
7094
- checkPath.isNotRelative = (path81) => REGEX_TEST_WINDOWS_PATH_ABSOLUTE.test(path81) || isNotRelative(path81);
7148
+ checkPath.isNotRelative = (path84) => REGEX_TEST_WINDOWS_PATH_ABSOLUTE.test(path84) || isNotRelative(path84);
7095
7149
  };
7096
7150
  if (
7097
7151
  // Detect `process` so that it can run in browsers.
@@ -7518,8 +7572,8 @@ var init_parseUtil = __esm({
7518
7572
  init_errors();
7519
7573
  init_en();
7520
7574
  makeIssue = (params) => {
7521
- const { data, path: path81, errorMaps, issueData } = params;
7522
- const fullPath = [...path81, ...issueData.path || []];
7575
+ const { data, path: path84, errorMaps, issueData } = params;
7576
+ const fullPath = [...path84, ...issueData.path || []];
7523
7577
  const fullIssue = {
7524
7578
  ...issueData,
7525
7579
  path: fullPath
@@ -7827,11 +7881,11 @@ var init_types = __esm({
7827
7881
  init_parseUtil();
7828
7882
  init_util();
7829
7883
  ParseInputLazyPath = class {
7830
- constructor(parent, value, path81, key) {
7884
+ constructor(parent, value, path84, key) {
7831
7885
  this._cachedPath = [];
7832
7886
  this.parent = parent;
7833
7887
  this.data = value;
7834
- this._path = path81;
7888
+ this._path = path84;
7835
7889
  this._key = key;
7836
7890
  }
7837
7891
  get path() {
@@ -11556,10 +11610,10 @@ function assignProp(target, prop, value) {
11556
11610
  configurable: true
11557
11611
  });
11558
11612
  }
11559
- function getElementAtPath(obj, path81) {
11560
- if (!path81)
11613
+ function getElementAtPath(obj, path84) {
11614
+ if (!path84)
11561
11615
  return obj;
11562
- return path81.reduce((acc, key) => acc?.[key], obj);
11616
+ return path84.reduce((acc, key) => acc?.[key], obj);
11563
11617
  }
11564
11618
  function promiseAllObject(promisesObj) {
11565
11619
  const keys = Object.keys(promisesObj);
@@ -11808,11 +11862,11 @@ function aborted(x, startIndex = 0) {
11808
11862
  }
11809
11863
  return false;
11810
11864
  }
11811
- function prefixIssues(path81, issues) {
11865
+ function prefixIssues(path84, issues) {
11812
11866
  return issues.map((iss) => {
11813
11867
  var _a2;
11814
11868
  (_a2 = iss).path ?? (_a2.path = []);
11815
- iss.path.unshift(path81);
11869
+ iss.path.unshift(path84);
11816
11870
  return iss;
11817
11871
  });
11818
11872
  }
@@ -12001,7 +12055,7 @@ function treeifyError(error40, _mapper) {
12001
12055
  return issue2.message;
12002
12056
  };
12003
12057
  const result = { errors: [] };
12004
- const processError = (error41, path81 = []) => {
12058
+ const processError = (error41, path84 = []) => {
12005
12059
  var _a2, _b;
12006
12060
  for (const issue2 of error41.issues) {
12007
12061
  if (issue2.code === "invalid_union" && issue2.errors.length) {
@@ -12011,7 +12065,7 @@ function treeifyError(error40, _mapper) {
12011
12065
  } else if (issue2.code === "invalid_element") {
12012
12066
  processError({ issues: issue2.issues }, issue2.path);
12013
12067
  } else {
12014
- const fullpath = [...path81, ...issue2.path];
12068
+ const fullpath = [...path84, ...issue2.path];
12015
12069
  if (fullpath.length === 0) {
12016
12070
  result.errors.push(mapper(issue2));
12017
12071
  continue;
@@ -12041,9 +12095,9 @@ function treeifyError(error40, _mapper) {
12041
12095
  processError(error40);
12042
12096
  return result;
12043
12097
  }
12044
- function toDotPath(path81) {
12098
+ function toDotPath(path84) {
12045
12099
  const segs = [];
12046
- for (const seg of path81) {
12100
+ for (const seg of path84) {
12047
12101
  if (typeof seg === "number")
12048
12102
  segs.push(`[${seg}]`);
12049
12103
  else if (typeof seg === "symbol")
@@ -25526,10 +25580,10 @@ var require_src2 = __commonJS({
25526
25580
  var fs_1 = __require("fs");
25527
25581
  var debug_1 = __importDefault(require_src());
25528
25582
  var log2 = debug_1.default("@kwsites/file-exists");
25529
- function check2(path81, isFile, isDirectory) {
25530
- log2(`checking %s`, path81);
25583
+ function check2(path84, isFile, isDirectory) {
25584
+ log2(`checking %s`, path84);
25531
25585
  try {
25532
- const stat3 = fs_1.statSync(path81);
25586
+ const stat3 = fs_1.statSync(path84);
25533
25587
  if (stat3.isFile() && isFile) {
25534
25588
  log2(`[OK] path represents a file`);
25535
25589
  return true;
@@ -25549,8 +25603,8 @@ var require_src2 = __commonJS({
25549
25603
  throw e;
25550
25604
  }
25551
25605
  }
25552
- function exists2(path81, type = exports.READABLE) {
25553
- return check2(path81, (type & exports.FILE) > 0, (type & exports.FOLDER) > 0);
25606
+ function exists2(path84, type = exports.READABLE) {
25607
+ return check2(path84, (type & exports.FILE) > 0, (type & exports.FOLDER) > 0);
25554
25608
  }
25555
25609
  exports.exists = exists2;
25556
25610
  exports.FILE = 1;
@@ -25613,6 +25667,112 @@ var require_dist2 = __commonJS({
25613
25667
  }
25614
25668
  });
25615
25669
 
25670
+ // src/files/ensure-under-cwd.ts
25671
+ import path74 from "node:path";
25672
+ function ensureUnderCwd(relativePath, cwd = getBridgeRoot()) {
25673
+ const normalized = path74.normalize(relativePath).replace(/^(\.\/)+/, "");
25674
+ const resolved = path74.resolve(cwd, normalized);
25675
+ if (!resolved.startsWith(cwd + path74.sep) && resolved !== cwd) {
25676
+ return null;
25677
+ }
25678
+ return resolved;
25679
+ }
25680
+ var init_ensure_under_cwd = __esm({
25681
+ "src/files/ensure-under-cwd.ts"() {
25682
+ "use strict";
25683
+ init_cwd();
25684
+ }
25685
+ });
25686
+
25687
+ // src/files/list-dir/types.ts
25688
+ var LIST_DIR_YIELD_EVERY;
25689
+ var init_types2 = __esm({
25690
+ "src/files/list-dir/types.ts"() {
25691
+ "use strict";
25692
+ LIST_DIR_YIELD_EVERY = 256;
25693
+ }
25694
+ });
25695
+
25696
+ // src/files/list-dir/map-dir-entry.ts
25697
+ import path75 from "node:path";
25698
+ import fs48 from "node:fs";
25699
+ async function mapDirEntry(d, relativePath, resolved) {
25700
+ const entryPath = path75.join(relativePath || ".", d.name).replace(/\\/g, "/");
25701
+ const fullPath = path75.join(resolved, d.name);
25702
+ let isDir = d.isDirectory();
25703
+ if (d.isSymbolicLink()) {
25704
+ try {
25705
+ const targetStat = await fs48.promises.stat(fullPath);
25706
+ isDir = targetStat.isDirectory();
25707
+ } catch {
25708
+ isDir = false;
25709
+ }
25710
+ }
25711
+ return {
25712
+ name: d.name,
25713
+ path: entryPath,
25714
+ isDir,
25715
+ isSymlink: d.isSymbolicLink()
25716
+ };
25717
+ }
25718
+ var init_map_dir_entry = __esm({
25719
+ "src/files/list-dir/map-dir-entry.ts"() {
25720
+ "use strict";
25721
+ }
25722
+ });
25723
+
25724
+ // src/files/list-dir/sort-entries.ts
25725
+ function sortListEntries(entries) {
25726
+ return entries.sort((a, b) => {
25727
+ if (a.isDir !== b.isDir) return a.isDir ? -1 : 1;
25728
+ return a.name.localeCompare(b.name, void 0, { sensitivity: "base" });
25729
+ });
25730
+ }
25731
+ var init_sort_entries = __esm({
25732
+ "src/files/list-dir/sort-entries.ts"() {
25733
+ "use strict";
25734
+ }
25735
+ });
25736
+
25737
+ // src/files/list-dir/index.ts
25738
+ var list_dir_exports = {};
25739
+ __export(list_dir_exports, {
25740
+ listDirAsync: () => listDirAsync
25741
+ });
25742
+ import fs49 from "node:fs";
25743
+ async function listDirAsync(relativePath, sessionParentPath = getBridgeRoot()) {
25744
+ await yieldToEventLoop();
25745
+ const resolved = ensureUnderCwd(relativePath || ".", sessionParentPath);
25746
+ if (!resolved) {
25747
+ return { error: "Path is outside working directory" };
25748
+ }
25749
+ try {
25750
+ const names = await fs49.promises.readdir(resolved, { withFileTypes: true });
25751
+ const entries = [];
25752
+ for (let i = 0; i < names.length; i++) {
25753
+ if (i > 0 && i % LIST_DIR_YIELD_EVERY === 0) {
25754
+ await yieldToEventLoop();
25755
+ }
25756
+ entries.push(await mapDirEntry(names[i], relativePath, resolved));
25757
+ }
25758
+ return { entries: sortListEntries(entries) };
25759
+ } catch (err) {
25760
+ const message = err instanceof Error ? err.message : String(err);
25761
+ return { error: message };
25762
+ }
25763
+ }
25764
+ var init_list_dir = __esm({
25765
+ "src/files/list-dir/index.ts"() {
25766
+ "use strict";
25767
+ init_ensure_under_cwd();
25768
+ init_cwd();
25769
+ init_yield_to_event_loop();
25770
+ init_types2();
25771
+ init_map_dir_entry();
25772
+ init_sort_entries();
25773
+ }
25774
+ });
25775
+
25616
25776
  // ../../node_modules/.pnpm/commander@12.1.0/node_modules/commander/esm.mjs
25617
25777
  var import_index = __toESM(require_commander(), 1);
25618
25778
  var {
@@ -25631,15 +25791,15 @@ var {
25631
25791
  } = import_index.default;
25632
25792
 
25633
25793
  // src/cli-version.ts
25634
- var CLI_VERSION = "0.1.63".length > 0 ? "0.1.63" : "0.0.0-dev";
25794
+ var CLI_VERSION = "0.1.64".length > 0 ? "0.1.64" : "0.0.0-dev";
25635
25795
 
25636
25796
  // src/cli/defaults.ts
25637
25797
  var DEFAULT_API_URL = process.env.BUILDAUTOMATON_API_URL ?? "https://api.buildautomaton.com";
25638
25798
  var DEFAULT_FIREHOSE_URL = "https://buildautomaton-firehose.fly.dev";
25639
25799
 
25640
25800
  // src/cli/run-cli-action.ts
25641
- import * as fs55 from "node:fs";
25642
- import * as path80 from "node:path";
25801
+ import * as fs58 from "node:fs";
25802
+ import * as path83 from "node:path";
25643
25803
 
25644
25804
  // src/cli-log-level.ts
25645
25805
  var verbosity = "info";
@@ -26084,29 +26244,8 @@ async function loadOrCreateE2eCertificates(directory) {
26084
26244
  };
26085
26245
  }
26086
26246
 
26087
- // src/paths/normalize-resolved-path.ts
26088
- import fs3 from "node:fs";
26089
- import path3 from "node:path";
26090
- function normalizeResolvedPath(resolved) {
26091
- const abs = path3.resolve(resolved);
26092
- try {
26093
- return fs3.realpathSync.native(abs);
26094
- } catch {
26095
- return abs;
26096
- }
26097
- }
26098
-
26099
- // src/files/cwd/bridge-root.ts
26100
- var bridgeRootPath = null;
26101
- function initBridgeRoot() {
26102
- bridgeRootPath = normalizeResolvedPath(process.cwd());
26103
- }
26104
- function getBridgeRoot() {
26105
- if (bridgeRootPath == null) {
26106
- bridgeRootPath = normalizeResolvedPath(process.cwd());
26107
- }
26108
- return bridgeRootPath;
26109
- }
26247
+ // src/cli/run-cli-action.ts
26248
+ init_cwd();
26110
26249
 
26111
26250
  // src/log.ts
26112
26251
  function timestampPrefix() {
@@ -27426,7 +27565,11 @@ function runPendingAuth(options) {
27426
27565
  };
27427
27566
  }
27428
27567
 
27568
+ // src/connection/create-bridge-connection.ts
27569
+ init_cwd();
27570
+
27429
27571
  // src/files/watch-file-index.ts
27572
+ init_cwd();
27430
27573
  import path25 from "node:path";
27431
27574
 
27432
27575
  // src/files/index/paths.ts
@@ -27436,7 +27579,7 @@ import crypto2 from "node:crypto";
27436
27579
  // src/files/index/constants.ts
27437
27580
  import path5 from "node:path";
27438
27581
  import os3 from "node:os";
27439
- var INDEX_WORK_YIELD_EVERY = 256;
27582
+ var INDEX_WORK_YIELD_EVERY = 128;
27440
27583
  var INDEX_DIR = path5.join(os3.homedir(), ".buildautomaton");
27441
27584
  var INDEX_HASH_LEN = 16;
27442
27585
 
@@ -27448,9 +27591,78 @@ function getCwdHashForFileIndex(resolvedCwd) {
27448
27591
  // src/files/index/build-file-index.ts
27449
27592
  import path15 from "node:path";
27450
27593
 
27451
- // src/runtime/yield-to-event-loop.ts
27452
- function yieldToEventLoop() {
27453
- return new Promise((resolve37) => setImmediate(resolve37));
27594
+ // src/files/browser/file-browser-in-flight.ts
27595
+ init_yield_to_event_loop();
27596
+
27597
+ // src/code-nav/symbol-index/deferred-indexing.ts
27598
+ var SymbolIndexDeferredError = class extends Error {
27599
+ constructor() {
27600
+ super("Symbol indexing deferred for file browser");
27601
+ this.name = "SymbolIndexDeferredError";
27602
+ }
27603
+ };
27604
+ function isSymbolIndexDeferredError(err) {
27605
+ return err instanceof SymbolIndexDeferredError;
27606
+ }
27607
+
27608
+ // src/files/browser/file-browser-in-flight.ts
27609
+ var BROWSE_INDEX_COOLDOWN_MS = 2500;
27610
+ var inFlightFileBrowserRequests = 0;
27611
+ var lastBrowseActivityAt = 0;
27612
+ var activityListeners = /* @__PURE__ */ new Set();
27613
+ var requestStartListeners = /* @__PURE__ */ new Set();
27614
+ function touchBrowseActivity() {
27615
+ lastBrowseActivityAt = Date.now();
27616
+ }
27617
+ function registerFileBrowserActivityListener(listener) {
27618
+ activityListeners.add(listener);
27619
+ return () => {
27620
+ activityListeners.delete(listener);
27621
+ };
27622
+ }
27623
+ function registerFileBrowserRequestStartListener(listener) {
27624
+ requestStartListeners.add(listener);
27625
+ return () => {
27626
+ requestStartListeners.delete(listener);
27627
+ };
27628
+ }
27629
+ function notifyFileBrowserActivity() {
27630
+ for (const listener of activityListeners) listener();
27631
+ }
27632
+ function notifyFileBrowserRequestStart() {
27633
+ for (const listener of requestStartListeners) listener();
27634
+ }
27635
+ function beginFileBrowserRequest() {
27636
+ inFlightFileBrowserRequests += 1;
27637
+ touchBrowseActivity();
27638
+ notifyFileBrowserRequestStart();
27639
+ notifyFileBrowserActivity();
27640
+ }
27641
+ function endFileBrowserRequest() {
27642
+ inFlightFileBrowserRequests = Math.max(0, inFlightFileBrowserRequests - 1);
27643
+ touchBrowseActivity();
27644
+ }
27645
+ function fileBrowserRequestInFlight() {
27646
+ return inFlightFileBrowserRequests > 0;
27647
+ }
27648
+ function isBridgeBrowseInteractiveActive() {
27649
+ if (fileBrowserRequestInFlight()) return true;
27650
+ return Date.now() - lastBrowseActivityAt < BROWSE_INDEX_COOLDOWN_MS;
27651
+ }
27652
+ function assertBackgroundIndexingAllowed() {
27653
+ if (isBridgeBrowseInteractiveActive()) throw new SymbolIndexDeferredError();
27654
+ }
27655
+ async function yieldUntilFileBrowserIdle(pollMs = 5) {
27656
+ while (isBridgeBrowseInteractiveActive()) {
27657
+ await yieldToEventLoop();
27658
+ if (isBridgeBrowseInteractiveActive()) {
27659
+ await new Promise((resolve37) => setTimeout(resolve37, pollMs));
27660
+ }
27661
+ }
27662
+ }
27663
+ async function yieldForBridgeInteractivePriority() {
27664
+ await yieldToEventLoop();
27665
+ await yieldUntilFileBrowserIdle();
27454
27666
  }
27455
27667
 
27456
27668
  // src/runtime/cli-process-interrupt.ts
@@ -27473,7 +27685,11 @@ async function delayMsUnlessShutdownRequested(ms) {
27473
27685
  return !isCliImmediateShutdownRequested();
27474
27686
  }
27475
27687
 
27688
+ // src/sqlite/code-nav-cache/code-nav-cache-database.ts
27689
+ init_yield_to_event_loop();
27690
+
27476
27691
  // src/sqlite/create-sqlite-database-access.ts
27692
+ init_yield_to_event_loop();
27477
27693
  import sqliteWasm from "node-sqlite3-wasm";
27478
27694
 
27479
27695
  // src/sqlite/sqlite-errors.ts
@@ -27518,6 +27734,7 @@ function applySqliteMemoryPragmas(db) {
27518
27734
  }
27519
27735
 
27520
27736
  // src/sqlite/sqlite-lock-retry.ts
27737
+ init_yield_to_event_loop();
27521
27738
  var SYNC_RETRY_MAX = 40;
27522
27739
  var ASYNC_RETRY_MAX = 60;
27523
27740
  var ASYNC_BASE_DELAY_MS = 20;
@@ -27679,7 +27896,7 @@ function readMigrationSql(filename, ...searchSubdirs) {
27679
27896
  join2(moduleDir, "..", sub, filename),
27680
27897
  join2(moduleDir, "..", "..", "dist", sub, filename)
27681
27898
  ]);
27682
- const resolved = candidates.find((path81) => existsSync(path81));
27899
+ const resolved = candidates.find((path84) => existsSync(path84));
27683
27900
  if (!resolved) {
27684
27901
  throw new Error(`Missing SQLite migration SQL: ${filename} (searched ${searchSubdirs.join(", ")})`);
27685
27902
  }
@@ -28068,14 +28285,14 @@ function legacyCliDiskMigrationIsPending() {
28068
28285
  return false;
28069
28286
  }
28070
28287
  function importCliSqliteLegacyDiskData(db, log2) {
28071
- const pending2 = legacyCliDiskMigrationIsPending();
28072
- if (pending2 && log2) {
28288
+ const pending = legacyCliDiskMigrationIsPending();
28289
+ if (pending && log2) {
28073
28290
  log2("Migrating legacy on-disk CLI data to SQLite\u2026");
28074
28291
  }
28075
28292
  archiveLegacyFileIndexJsonFiles();
28076
28293
  importLegacyAgentSessionsFromDisk(db);
28077
28294
  importLegacyPromptQueuesFromDisk(db);
28078
- if (pending2 && log2) {
28295
+ if (pending && log2) {
28079
28296
  log2("Legacy on-disk CLI data migration finished.");
28080
28297
  }
28081
28298
  }
@@ -28184,7 +28401,7 @@ async function walkWorkspaceTreeAsync(dir, baseDir, onFile, state) {
28184
28401
  if (shouldSkipWorkspaceWalkEntry(name)) continue;
28185
28402
  if (state.n > 0 && state.n % INDEX_WORK_YIELD_EVERY === 0) {
28186
28403
  if (isCliImmediateShutdownRequested()) throw new CliSqliteInterrupted();
28187
- await yieldToEventLoop();
28404
+ await yieldForBridgeInteractivePriority();
28188
28405
  if (isCliImmediateShutdownRequested()) throw new CliSqliteInterrupted();
28189
28406
  }
28190
28407
  state.n++;
@@ -28291,7 +28508,7 @@ async function persistFileIndexPathsAsync(resolved, paths) {
28291
28508
  assertFileIndexPersistNotShutdown();
28292
28509
  const batch = paths.slice(offset, offset + FILE_INDEX_INSERT_BUFFER);
28293
28510
  pathCount += await withCodeNavCacheSqlite((db) => insertFileIndexChildPathBatch(db, resolved, batch));
28294
- await yieldToEventLoop();
28511
+ await yieldForBridgeInteractivePriority();
28295
28512
  }
28296
28513
  return pathCount;
28297
28514
  }
@@ -28302,10 +28519,10 @@ function assertNotShutdown2() {
28302
28519
  }
28303
28520
  async function buildFileIndexAsync(cwd) {
28304
28521
  const resolved = path15.resolve(cwd);
28305
- await yieldToEventLoop();
28522
+ await yieldForBridgeInteractivePriority();
28306
28523
  assertNotShutdown2();
28307
28524
  const paths = await collectWorkspacePathsAsync(resolved);
28308
- await yieldToEventLoop();
28525
+ await yieldForBridgeInteractivePriority();
28309
28526
  assertNotShutdown2();
28310
28527
  return await withFileIndexSqliteLock(async () => {
28311
28528
  const pathCount = await persistFileIndexPathsAsync(resolved, paths);
@@ -28317,6 +28534,7 @@ async function buildFileIndexAsync(cwd) {
28317
28534
  import path16 from "node:path";
28318
28535
 
28319
28536
  // src/files/index/search-file-index.ts
28537
+ init_yield_to_event_loop();
28320
28538
  function escapeLikePattern(fragment) {
28321
28539
  return fragment.replace(/\\/g, "\\\\").replace(/%/g, "\\%").replace(/_/g, "\\_");
28322
28540
  }
@@ -28373,8 +28591,11 @@ async function ensureFileIndexAsync(cwd) {
28373
28591
  return { ...await buildFileIndexAsync(resolved), fromCache: false };
28374
28592
  }
28375
28593
 
28594
+ // src/code-nav/symbol-index/build/build-symbol-index.ts
28595
+ init_normalize_resolved_path();
28596
+
28376
28597
  // src/code-nav/yield-during-work.ts
28377
- var CODE_NAV_YIELD_EVERY = INDEX_WORK_YIELD_EVERY;
28598
+ var CODE_NAV_YIELD_EVERY = 64;
28378
28599
  function createCodeNavYieldState() {
28379
28600
  return { n: 0 };
28380
28601
  }
@@ -28382,7 +28603,7 @@ async function yieldDuringCodeNavWork(state) {
28382
28603
  state.n++;
28383
28604
  if (state.n % CODE_NAV_YIELD_EVERY !== 0) return;
28384
28605
  if (isCliImmediateShutdownRequested()) throw new CliSqliteInterrupted();
28385
- await yieldToEventLoop();
28606
+ await yieldForBridgeInteractivePriority();
28386
28607
  if (isCliImmediateShutdownRequested()) throw new CliSqliteInterrupted();
28387
28608
  }
28388
28609
 
@@ -28515,7 +28736,7 @@ async function walkCodeNavFilesInDirectory(dir, baseDir, relDir, filter, onFile,
28515
28736
  if (shouldSkipWorkspaceWalkEntry(name)) continue;
28516
28737
  if (state.n > 0 && state.n % INDEX_WORK_YIELD_EVERY === 0) {
28517
28738
  if (isCliImmediateShutdownRequested()) throw new CliSqliteInterrupted();
28518
- await yieldToEventLoop();
28739
+ await yieldForBridgeInteractivePriority();
28519
28740
  if (isCliImmediateShutdownRequested()) throw new CliSqliteInterrupted();
28520
28741
  }
28521
28742
  state.n++;
@@ -28549,6 +28770,8 @@ async function walkCodeNavFilesAsync(rootDir, onFile, state = createWalkYieldSta
28549
28770
  var SYMBOL_INDEX_VERSION = 11;
28550
28771
 
28551
28772
  // src/code-nav/symbol-index/sqlite/parent-path.ts
28773
+ init_bridge_root();
28774
+ init_normalize_resolved_path();
28552
28775
  function normalizeParentPath(resolved) {
28553
28776
  return normalizeResolvedPath(resolved);
28554
28777
  }
@@ -28843,128 +29066,11 @@ function withSymbolIndexSqliteLock(fn) {
28843
29066
  return withCodeNavCacheSqliteWorkLock(fn);
28844
29067
  }
28845
29068
 
28846
- // src/code-nav/symbol-index/imports/star-reexport-names.ts
28847
- var STAR_LOCAL_NAME = "*";
28848
- function isModuleLevelDef(tag) {
28849
- return tag.role === "def" && tag.parentScopeStartLine == null && tag.parentScopeStartColumn == null;
28850
- }
28851
- function collectExportableNamesFromTags(tags) {
28852
- const names = /* @__PURE__ */ new Map();
28853
- for (const tag of tags) {
28854
- if (!isModuleLevelDef(tag)) continue;
28855
- if (!names.has(tag.name)) names.set(tag.name, tag.name);
28856
- }
28857
- return names;
28858
- }
28859
- function existingLocalNames(imports) {
28860
- return new Set(imports.map((binding) => binding.localName));
28861
- }
28862
- function resolveExportableNames(filePath, entriesByPath, visited) {
28863
- if (visited.has(filePath)) return /* @__PURE__ */ new Map();
28864
- visited.add(filePath);
28865
- const entry = entriesByPath.get(filePath);
28866
- if (!entry) return /* @__PURE__ */ new Map();
28867
- const out = collectExportableNamesFromTags(entry.tags);
28868
- const resolved = /* @__PURE__ */ new Map();
28869
- for (const [name, sourceName] of out) {
28870
- resolved.set(name, { sourceName, sourceFilePath: filePath });
28871
- }
28872
- for (const binding of entry.imports) {
28873
- if (binding.importKind !== "star" || !binding.sourceFilePath) continue;
28874
- const upstream = resolveExportableNames(binding.sourceFilePath, entriesByPath, visited);
28875
- for (const [name, info] of upstream) {
28876
- if (!resolved.has(name)) resolved.set(name, info);
28877
- }
28878
- }
28879
- for (const binding of entry.imports) {
28880
- if (binding.importKind !== "reexport" && binding.importKind !== "type") continue;
28881
- if (!binding.sourceFilePath) continue;
28882
- if (!resolved.has(binding.localName)) {
28883
- resolved.set(binding.localName, {
28884
- sourceName: binding.sourceName,
28885
- sourceFilePath: binding.sourceFilePath
28886
- });
28887
- }
28888
- }
28889
- return resolved;
28890
- }
28891
-
28892
- // src/code-nav/symbol-index/imports/star-reexport-upstream.ts
28893
- function collectUpstreamEntries(entry, resolveEntry) {
28894
- const entriesByPath = /* @__PURE__ */ new Map();
28895
- entriesByPath.set(entry.relPath, entry);
28896
- const visit = (filePath, visited) => {
28897
- if (visited.has(filePath)) return;
28898
- visited.add(filePath);
28899
- const resolved = resolveEntry(filePath);
28900
- if (resolved == null) return;
28901
- entriesByPath.set(filePath, resolved);
28902
- for (const binding of resolved.imports) {
28903
- if (binding.sourceFilePath) visit(binding.sourceFilePath, visited);
28904
- }
28905
- };
28906
- for (const star of entry.imports) {
28907
- if (star.importKind !== "star" || !star.sourceFilePath) continue;
28908
- visit(star.sourceFilePath, /* @__PURE__ */ new Set());
28909
- }
28910
- return [...entriesByPath.values()];
28911
- }
28912
-
28913
- // src/code-nav/symbol-index/imports/expand-star-reexports.ts
28914
- function expandStarReexportForFile(entry, resolveEntry) {
28915
- const collected = collectUpstreamEntries(entry, resolveEntry);
28916
- return expandStarReexportBindings(collected).find((row) => row.relPath === entry.relPath) ?? entry;
28917
- }
28918
- function expandStarReexportBindings(collected) {
28919
- const entriesByPath = new Map(collected.map((entry) => [entry.relPath, entry]));
28920
- return collected.map((entry) => {
28921
- const stars = entry.imports.filter((binding) => binding.importKind === "star");
28922
- if (stars.length === 0) return entry;
28923
- const localNames = existingLocalNames(entry.imports);
28924
- const materialized = [];
28925
- for (const star of stars) {
28926
- if (!star.sourceFilePath) continue;
28927
- const exportable = resolveExportableNames(star.sourceFilePath, entriesByPath, /* @__PURE__ */ new Set());
28928
- for (const [localName, info] of exportable) {
28929
- if (localName === STAR_LOCAL_NAME || localNames.has(localName)) continue;
28930
- localNames.add(localName);
28931
- materialized.push({
28932
- localName,
28933
- sourceName: info.sourceName,
28934
- moduleSpecifier: star.moduleSpecifier,
28935
- sourceFilePath: info.sourceFilePath,
28936
- importKind: star.importKind === "type" ? "type" : "reexport",
28937
- startLine: star.startLine,
28938
- startColumn: star.startColumn
28939
- });
28940
- }
28941
- }
28942
- if (materialized.length === 0) return entry;
28943
- return { ...entry, imports: [...entry.imports, ...materialized] };
28944
- });
28945
- }
29069
+ // src/code-nav/symbol-index/build/ensure-symbol-index-file.ts
29070
+ init_normalize_resolved_path();
28946
29071
 
28947
- // src/code-nav/symbol-index/persistence/persist-single-file.ts
28948
- async function persistSymbolIndexFileAsync(resolved, relPath, source, tags, imports) {
28949
- await withCodeNavCacheSqlite(async (db) => {
28950
- runCodeNavCacheWriteTransaction(db, () => {
28951
- upsertSymbolIndexParentPath(db, resolved);
28952
- const ctx = getSymbolIndexParentContext(db, resolved);
28953
- if (ctx == null) throw new Error(`Failed to resolve symbol index parent: ${resolved}`);
28954
- persistSymbolIndexFileData(db, ctx, relPath, source, tags, imports);
28955
- });
28956
- });
28957
- }
28958
- async function removeSymbolIndexFileAsync(resolved, relPath) {
28959
- await withCodeNavCacheSqlite(async (db) => {
28960
- runCodeNavCacheWriteTransaction(db, () => {
28961
- upsertSymbolIndexParentPath(db, resolved);
28962
- const ctx = getSymbolIndexParentContext(db, resolved);
28963
- if (ctx == null) throw new Error(`Failed to resolve symbol index parent: ${resolved}`);
28964
- removeSymbolIndexFileData(db, ctx, relPath);
28965
- });
28966
- });
28967
- }
29072
+ // src/code-nav/symbol-index/query/list-direct-import-targets.ts
29073
+ init_normalize_resolved_path();
28968
29074
 
28969
29075
  // src/code-nav/symbol-index/query/tag-query-shared.ts
28970
29076
  var TAG_SELECT = `file_path, name, role, kind, start_line, start_column, end_line, end_column,
@@ -29114,6 +29220,7 @@ async function listDirectImportTargetsForFileAsync(parentPath, filePath) {
29114
29220
  }
29115
29221
 
29116
29222
  // src/code-nav/symbol-index/lifecycle/symbol-index-file-ready.ts
29223
+ init_normalize_resolved_path();
29117
29224
  function symbolIndexFileIsReadyWithDb(db, parentPath, filePath) {
29118
29225
  const normalizedParent = normalizeResolvedPath(parentPath);
29119
29226
  const normalizedFile = filePath.replace(/\\/g, "/").replace(/^\/+/, "");
@@ -29143,6 +29250,129 @@ async function loadSymbolIndexReadyFileSet(parentPath) {
29143
29250
  return new Set(paths);
29144
29251
  }
29145
29252
 
29253
+ // src/code-nav/symbol-index/imports/star-reexport-names.ts
29254
+ var STAR_LOCAL_NAME = "*";
29255
+ function isModuleLevelDef(tag) {
29256
+ return tag.role === "def" && tag.parentScopeStartLine == null && tag.parentScopeStartColumn == null;
29257
+ }
29258
+ function collectExportableNamesFromTags(tags) {
29259
+ const names = /* @__PURE__ */ new Map();
29260
+ for (const tag of tags) {
29261
+ if (!isModuleLevelDef(tag)) continue;
29262
+ if (!names.has(tag.name)) names.set(tag.name, tag.name);
29263
+ }
29264
+ return names;
29265
+ }
29266
+ function existingLocalNames(imports) {
29267
+ return new Set(imports.map((binding) => binding.localName));
29268
+ }
29269
+ function resolveExportableNames(filePath, entriesByPath, visited) {
29270
+ if (visited.has(filePath)) return /* @__PURE__ */ new Map();
29271
+ visited.add(filePath);
29272
+ const entry = entriesByPath.get(filePath);
29273
+ if (!entry) return /* @__PURE__ */ new Map();
29274
+ const out = collectExportableNamesFromTags(entry.tags);
29275
+ const resolved = /* @__PURE__ */ new Map();
29276
+ for (const [name, sourceName] of out) {
29277
+ resolved.set(name, { sourceName, sourceFilePath: filePath });
29278
+ }
29279
+ for (const binding of entry.imports) {
29280
+ if (binding.importKind !== "star" || !binding.sourceFilePath) continue;
29281
+ const upstream = resolveExportableNames(binding.sourceFilePath, entriesByPath, visited);
29282
+ for (const [name, info] of upstream) {
29283
+ if (!resolved.has(name)) resolved.set(name, info);
29284
+ }
29285
+ }
29286
+ for (const binding of entry.imports) {
29287
+ if (binding.importKind !== "reexport" && binding.importKind !== "type") continue;
29288
+ if (!binding.sourceFilePath) continue;
29289
+ if (!resolved.has(binding.localName)) {
29290
+ resolved.set(binding.localName, {
29291
+ sourceName: binding.sourceName,
29292
+ sourceFilePath: binding.sourceFilePath
29293
+ });
29294
+ }
29295
+ }
29296
+ return resolved;
29297
+ }
29298
+
29299
+ // src/code-nav/symbol-index/imports/star-reexport-upstream.ts
29300
+ function collectUpstreamEntries(entry, resolveEntry) {
29301
+ const entriesByPath = /* @__PURE__ */ new Map();
29302
+ entriesByPath.set(entry.relPath, entry);
29303
+ const visit = (filePath, visited) => {
29304
+ if (visited.has(filePath)) return;
29305
+ visited.add(filePath);
29306
+ const resolved = resolveEntry(filePath);
29307
+ if (resolved == null) return;
29308
+ entriesByPath.set(filePath, resolved);
29309
+ for (const binding of resolved.imports) {
29310
+ if (binding.sourceFilePath) visit(binding.sourceFilePath, visited);
29311
+ }
29312
+ };
29313
+ for (const star of entry.imports) {
29314
+ if (star.importKind !== "star" || !star.sourceFilePath) continue;
29315
+ visit(star.sourceFilePath, /* @__PURE__ */ new Set());
29316
+ }
29317
+ return [...entriesByPath.values()];
29318
+ }
29319
+
29320
+ // src/code-nav/symbol-index/imports/expand-star-reexports.ts
29321
+ function expandStarReexportForFile(entry, resolveEntry) {
29322
+ const collected = collectUpstreamEntries(entry, resolveEntry);
29323
+ return expandStarReexportBindings(collected).find((row) => row.relPath === entry.relPath) ?? entry;
29324
+ }
29325
+ function expandStarReexportBindings(collected) {
29326
+ const entriesByPath = new Map(collected.map((entry) => [entry.relPath, entry]));
29327
+ return collected.map((entry) => {
29328
+ const stars = entry.imports.filter((binding) => binding.importKind === "star");
29329
+ if (stars.length === 0) return entry;
29330
+ const localNames = existingLocalNames(entry.imports);
29331
+ const materialized = [];
29332
+ for (const star of stars) {
29333
+ if (!star.sourceFilePath) continue;
29334
+ const exportable = resolveExportableNames(star.sourceFilePath, entriesByPath, /* @__PURE__ */ new Set());
29335
+ for (const [localName, info] of exportable) {
29336
+ if (localName === STAR_LOCAL_NAME || localNames.has(localName)) continue;
29337
+ localNames.add(localName);
29338
+ materialized.push({
29339
+ localName,
29340
+ sourceName: info.sourceName,
29341
+ moduleSpecifier: star.moduleSpecifier,
29342
+ sourceFilePath: info.sourceFilePath,
29343
+ importKind: star.importKind === "type" ? "type" : "reexport",
29344
+ startLine: star.startLine,
29345
+ startColumn: star.startColumn
29346
+ });
29347
+ }
29348
+ }
29349
+ if (materialized.length === 0) return entry;
29350
+ return { ...entry, imports: [...entry.imports, ...materialized] };
29351
+ });
29352
+ }
29353
+
29354
+ // src/code-nav/symbol-index/persistence/persist-single-file.ts
29355
+ async function persistSymbolIndexFileAsync(resolved, relPath, source, tags, imports) {
29356
+ await withCodeNavCacheSqlite(async (db) => {
29357
+ runCodeNavCacheWriteTransaction(db, () => {
29358
+ upsertSymbolIndexParentPath(db, resolved);
29359
+ const ctx = getSymbolIndexParentContext(db, resolved);
29360
+ if (ctx == null) throw new Error(`Failed to resolve symbol index parent: ${resolved}`);
29361
+ persistSymbolIndexFileData(db, ctx, relPath, source, tags, imports);
29362
+ });
29363
+ });
29364
+ }
29365
+ async function removeSymbolIndexFileAsync(resolved, relPath) {
29366
+ await withCodeNavCacheSqlite(async (db) => {
29367
+ runCodeNavCacheWriteTransaction(db, () => {
29368
+ upsertSymbolIndexParentPath(db, resolved);
29369
+ const ctx = getSymbolIndexParentContext(db, resolved);
29370
+ if (ctx == null) throw new Error(`Failed to resolve symbol index parent: ${resolved}`);
29371
+ removeSymbolIndexFileData(db, ctx, relPath);
29372
+ });
29373
+ });
29374
+ }
29375
+
29146
29376
  // src/code-nav/symbol-index/build/extract-file-symbol-data.ts
29147
29377
  import fs20 from "node:fs";
29148
29378
  import path21 from "node:path";
@@ -29829,6 +30059,7 @@ async function parseSourceRoot(filePath, source) {
29829
30059
  const languageKey = getLanguageKeyForFilePath(filePath);
29830
30060
  if (!languageKey) return null;
29831
30061
  return withTreeSitterRuntimeLock(async () => {
30062
+ await yieldForBridgeInteractivePriority();
29832
30063
  let loaded;
29833
30064
  try {
29834
30065
  loaded = await loadLanguage(languageKey);
@@ -29840,7 +30071,11 @@ async function parseSourceRoot(filePath, source) {
29840
30071
  parser4.setLanguage(loaded.language);
29841
30072
  let tree = null;
29842
30073
  try {
30074
+ await yieldForBridgeInteractivePriority();
30075
+ assertBackgroundIndexingAllowed();
29843
30076
  tree = parser4.parse(source);
30077
+ assertBackgroundIndexingAllowed();
30078
+ await yieldForBridgeInteractivePriority();
29844
30079
  if (!tree) return null;
29845
30080
  return {
29846
30081
  root: tree.rootNode,
@@ -29850,9 +30085,10 @@ async function parseSourceRoot(filePath, source) {
29850
30085
  parser4.delete();
29851
30086
  }
29852
30087
  };
29853
- } catch {
30088
+ } catch (err) {
29854
30089
  tree?.delete();
29855
30090
  parser4.delete();
30091
+ if (isSymbolIndexDeferredError(err)) throw err;
29856
30092
  return null;
29857
30093
  }
29858
30094
  });
@@ -29860,9 +30096,11 @@ async function parseSourceRoot(filePath, source) {
29860
30096
 
29861
30097
  // src/code-nav/parser/run-tags-query.ts
29862
30098
  async function runTagsQuery(loaded, root) {
29863
- await yieldToEventLoop();
30099
+ await yieldForBridgeInteractivePriority();
30100
+ assertBackgroundIndexingAllowed();
29864
30101
  const matches = loaded.query.matches(root);
29865
- await yieldToEventLoop();
30102
+ assertBackgroundIndexingAllowed();
30103
+ await yieldForBridgeInteractivePriority();
29866
30104
  return matches;
29867
30105
  }
29868
30106
 
@@ -29943,7 +30181,7 @@ async function tagsFromMatchesAsync(matches, state) {
29943
30181
  // src/code-nav/parser/extract-tags.ts
29944
30182
  async function extractTagsFromSource(filePath, source) {
29945
30183
  const languageKey = getLanguageKeyForFilePath(filePath);
29946
- await yieldToEventLoop();
30184
+ await yieldForBridgeInteractivePriority();
29947
30185
  const parsed = await parseSourceRoot(filePath, source);
29948
30186
  if (!parsed) return [];
29949
30187
  try {
@@ -29959,13 +30197,17 @@ async function extractTagsFromSource(filePath, source) {
29959
30197
  const withReceivers = await augmentMemberReceiverTags(withFunctionTypeParamRefs, nameNodes, parsed.root, languageKey);
29960
30198
  await yieldDuringCodeNavWork(yieldState);
29961
30199
  return await enrichTagsWithEnclosingScope(withReceivers, nameNodes);
29962
- } catch {
30200
+ } catch (err) {
30201
+ if (isSymbolIndexDeferredError(err)) throw err;
29963
30202
  return [];
29964
30203
  } finally {
29965
30204
  parsed.cleanup();
29966
30205
  }
29967
30206
  }
29968
30207
 
30208
+ // src/code-nav/symbol-index/imports/index.ts
30209
+ init_yield_to_event_loop();
30210
+
29969
30211
  // src/code-nav/symbol-index/imports/shared.ts
29970
30212
  function pushBinding(out, filePath, workspaceFiles, moduleSpecifier, localName, sourceName, importKind, nameNode) {
29971
30213
  if (!localName) return;
@@ -30334,6 +30576,7 @@ async function extractImportBindingsFromSource(filePath, source, workspaceFiles)
30334
30576
  var MAX_INDEX_FILE_BYTES = 512 * 1024;
30335
30577
 
30336
30578
  // src/code-nav/symbol-index/build/workspace-files.ts
30579
+ init_normalize_resolved_path();
30337
30580
  function listWorkspaceFiles(db, workspacePath, includePath) {
30338
30581
  const files = /* @__PURE__ */ new Set([includePath.replace(/\\/g, "/")]);
30339
30582
  const normalizedWorkspace = normalizeResolvedPath(workspacePath);
@@ -30355,6 +30598,7 @@ function listWorkspaceFiles(db, workspacePath, includePath) {
30355
30598
 
30356
30599
  // src/code-nav/symbol-index/build/extract-file-symbol-data.ts
30357
30600
  async function extractFileSymbolData(resolved, relPath, workspaceFilesOverride) {
30601
+ await yieldForBridgeInteractivePriority();
30358
30602
  const absPath = path21.join(resolved, relPath);
30359
30603
  let tags = [];
30360
30604
  let source = null;
@@ -30363,15 +30607,16 @@ async function extractFileSymbolData(resolved, relPath, workspaceFilesOverride)
30363
30607
  const stat3 = await fs20.promises.stat(absPath);
30364
30608
  if (stat3.isFile() && stat3.size <= MAX_INDEX_FILE_BYTES) {
30365
30609
  source = await fs20.promises.readFile(absPath, "utf8");
30366
- await yieldToEventLoop();
30610
+ await yieldForBridgeInteractivePriority();
30367
30611
  tags = await extractTagsFromSource(relPath, source);
30368
30612
  }
30369
- } catch {
30613
+ } catch (err) {
30614
+ if (isSymbolIndexDeferredError(err)) throw err;
30370
30615
  tags = [];
30371
30616
  source = null;
30372
30617
  }
30373
30618
  }
30374
- await yieldToEventLoop();
30619
+ await yieldForBridgeInteractivePriority();
30375
30620
  const workspaceFiles = workspaceFilesOverride ?? await withCodeNavCacheSqlite((db) => listWorkspaceFiles(db, resolved, relPath));
30376
30621
  const imports = source != null ? await extractImportBindingsFromSource(relPath, source, workspaceFiles) : [];
30377
30622
  const yieldState = createCodeNavYieldState();
@@ -30382,12 +30627,9 @@ async function extractFileSymbolData(resolved, relPath, workspaceFilesOverride)
30382
30627
  };
30383
30628
  }
30384
30629
 
30385
- // src/code-nav/symbol-index/build/ensure-symbol-index-file.ts
30386
- var MAX_IMPORT_PREFETCH_COUNT = 8;
30387
- function normalizeRelPath3(filePath) {
30388
- return filePath.replace(/\\/g, "/").replace(/^\/+/, "");
30389
- }
30630
+ // src/code-nav/symbol-index/build/index-one-symbol-file-for-build.ts
30390
30631
  async function indexOneSymbolFileForBuild(resolved, relPath, workspaceFiles) {
30632
+ await yieldForBridgeInteractivePriority();
30391
30633
  const data = await extractFileSymbolData(resolved, relPath, workspaceFiles);
30392
30634
  let entry = {
30393
30635
  relPath,
@@ -30396,7 +30638,7 @@ async function indexOneSymbolFileForBuild(resolved, relPath, workspaceFiles) {
30396
30638
  imports: data.imports
30397
30639
  };
30398
30640
  if (data.imports.some((binding) => binding.importKind === "star")) {
30399
- await yieldToEventLoop();
30641
+ await yieldForBridgeInteractivePriority();
30400
30642
  entry = await withCodeNavCacheSqlite((db) => {
30401
30643
  const ctx = getSymbolIndexParentContext(db, resolved);
30402
30644
  if (ctx == null) return entry;
@@ -30406,13 +30648,30 @@ async function indexOneSymbolFileForBuild(resolved, relPath, workspaceFiles) {
30406
30648
  entry.source = data.source;
30407
30649
  }
30408
30650
  await withSymbolIndexSqliteLock(async () => {
30409
- await yieldToEventLoop();
30651
+ await yieldForBridgeInteractivePriority();
30410
30652
  await persistSymbolIndexFileAsync(resolved, relPath, entry.source, entry.tags, entry.imports);
30411
30653
  });
30412
30654
  }
30655
+
30656
+ // src/code-nav/symbol-index/build/normalize-symbol-index-rel-path.ts
30657
+ function normalizeSymbolIndexRelPath(filePath) {
30658
+ return filePath.replace(/\\/g, "/").replace(/^\/+/, "");
30659
+ }
30660
+
30661
+ // src/code-nav/symbol-index/build/register-symbol-index-parent.ts
30662
+ init_normalize_resolved_path();
30663
+ async function registerSymbolIndexParentAsync(parentPath) {
30664
+ const resolved = normalizeResolvedPath(parentPath);
30665
+ await withCodeNavCacheSqlite((db) => {
30666
+ upsertSymbolIndexParentPath(db, resolved);
30667
+ });
30668
+ }
30669
+
30670
+ // src/code-nav/symbol-index/build/ensure-symbol-index-file.ts
30671
+ var MAX_IMPORT_PREFETCH_COUNT = 8;
30413
30672
  async function ensureSymbolIndexFileAsync(parentPath, filePath, opts) {
30414
30673
  const resolved = normalizeResolvedPath(parentPath);
30415
- const relPath = normalizeRelPath3(filePath);
30674
+ const relPath = normalizeSymbolIndexRelPath(filePath);
30416
30675
  if (!relPath) return false;
30417
30676
  const importDepth = opts?.importDepth ?? 0;
30418
30677
  await withCodeNavCacheSqlite((db) => {
@@ -30427,7 +30686,7 @@ async function ensureSymbolIndexFileAsync(parentPath, filePath, opts) {
30427
30686
  MAX_IMPORT_PREFETCH_COUNT
30428
30687
  );
30429
30688
  for (const target of targets) {
30430
- await yieldToEventLoop();
30689
+ await yieldForBridgeInteractivePriority();
30431
30690
  if (!await symbolIndexFileIsReadyAsync(resolved, target)) {
30432
30691
  await ensureSymbolIndexFileAsync(resolved, target, { importDepth: importDepth - 1 });
30433
30692
  }
@@ -30435,18 +30694,12 @@ async function ensureSymbolIndexFileAsync(parentPath, filePath, opts) {
30435
30694
  }
30436
30695
  return await symbolIndexFileIsReadyAsync(resolved, relPath);
30437
30696
  }
30438
- async function registerSymbolIndexParentAsync(parentPath) {
30439
- const resolved = normalizeResolvedPath(parentPath);
30440
- await withCodeNavCacheSqlite((db) => {
30441
- upsertSymbolIndexParentPath(db, resolved);
30442
- });
30443
- }
30444
30697
 
30445
30698
  // src/code-nav/symbol-index/build/build-symbol-index.ts
30446
30699
  var SYMBOL_PARENT_CLEAR_BATCH_SIZE = 256;
30447
30700
  async function buildSymbolIndexAsync(parentPath) {
30448
30701
  const resolved = normalizeResolvedPath(parentPath);
30449
- await yieldToEventLoop();
30702
+ await yieldForBridgeInteractivePriority();
30450
30703
  let clearRemaining = true;
30451
30704
  while (clearRemaining) {
30452
30705
  await withSymbolIndexSqliteLock(async () => {
@@ -30458,7 +30711,7 @@ async function buildSymbolIndexAsync(parentPath) {
30458
30711
  })
30459
30712
  );
30460
30713
  });
30461
- if (clearRemaining) await yieldToEventLoop();
30714
+ if (clearRemaining) await yieldForBridgeInteractivePriority();
30462
30715
  }
30463
30716
  const workspaceFiles = /* @__PURE__ */ new Set();
30464
30717
  const walkState = createWalkYieldState();
@@ -30481,10 +30734,17 @@ async function buildSymbolIndexAsync(parentPath) {
30481
30734
  },
30482
30735
  walkState
30483
30736
  );
30484
- await yieldToEventLoop();
30737
+ await yieldForBridgeInteractivePriority();
30485
30738
  return { fileCount, tagCount: 0 };
30486
30739
  }
30487
30740
 
30741
+ // src/code-nav/symbol-index/build/ensure-symbol-index.ts
30742
+ init_bridge_root();
30743
+ init_normalize_resolved_path();
30744
+
30745
+ // src/code-nav/symbol-index/scheduler/task-queue-enqueue.ts
30746
+ init_normalize_resolved_path();
30747
+
30488
30748
  // src/code-nav/symbol-index/scheduler/task-priority-heap.ts
30489
30749
  function higherPriority(a, b) {
30490
30750
  return a.priority > b.priority;
@@ -30542,122 +30802,185 @@ function symbolIndexTaskKey(parentPath, filePath) {
30542
30802
  return `${parentPath}\0${filePath}`;
30543
30803
  }
30544
30804
 
30545
- // src/code-nav/symbol-index/scheduler/task-queue.ts
30546
- var pending = /* @__PURE__ */ new Map();
30547
- var heap = new SymbolIndexTaskPriorityHeap();
30805
+ // src/code-nav/symbol-index/scheduler/task-queue-store.ts
30806
+ var pendingSymbolIndexTasks = /* @__PURE__ */ new Map();
30807
+ var symbolIndexTaskHeap = new SymbolIndexTaskPriorityHeap();
30548
30808
  var latestActiveSequenceByParent = /* @__PURE__ */ new Map();
30549
- var workerRunning = false;
30809
+ var symbolIndexWorkerRunning = false;
30810
+ function setSymbolIndexWorkerRunning(running) {
30811
+ symbolIndexWorkerRunning = running;
30812
+ }
30813
+ function deferBackgroundSymbolIndexTasks() {
30814
+ if (pendingSymbolIndexTasks.size === 0) return;
30815
+ pendingSymbolIndexTasks.clear();
30816
+ symbolIndexTaskHeap.clear();
30817
+ }
30818
+ registerFileBrowserRequestStartListener(() => {
30819
+ deferBackgroundSymbolIndexTasks();
30820
+ });
30550
30821
  function taskMatchesCurrentPending(task) {
30551
- const current = pending.get(symbolIndexTaskKey(task.parentPath, task.filePath));
30822
+ const current = pendingSymbolIndexTasks.get(symbolIndexTaskKey(task.parentPath, task.filePath));
30552
30823
  return current === task;
30553
30824
  }
30554
- function pickNextTask() {
30555
- while (heap.size > 0) {
30556
- const task = heap.pop();
30825
+ function pickNextSymbolIndexTask() {
30826
+ while (symbolIndexTaskHeap.size > 0) {
30827
+ const task = symbolIndexTaskHeap.pop();
30557
30828
  if (task == null || !taskMatchesCurrentPending(task)) continue;
30558
30829
  return task;
30559
30830
  }
30560
30831
  return void 0;
30561
30832
  }
30833
+ function addPendingSymbolIndexTask(task) {
30834
+ const key = symbolIndexTaskKey(task.parentPath, task.filePath);
30835
+ const existing = pendingSymbolIndexTasks.get(key);
30836
+ if (existing != null && existing.priority >= task.priority) return false;
30837
+ pendingSymbolIndexTasks.set(key, task);
30838
+ symbolIndexTaskHeap.push(task);
30839
+ return true;
30840
+ }
30841
+ function clearSymbolIndexHeapIfEmpty() {
30842
+ if (pendingSymbolIndexTasks.size === 0) symbolIndexTaskHeap.clear();
30843
+ }
30844
+
30845
+ // src/code-nav/symbol-index/scheduler/task-queue-worker.ts
30562
30846
  async function runWorker() {
30563
- if (workerRunning) return;
30564
- workerRunning = true;
30847
+ if (symbolIndexWorkerRunning) return;
30848
+ setSymbolIndexWorkerRunning(true);
30565
30849
  try {
30566
30850
  const yieldState = createCodeNavYieldState();
30567
- while (pending.size > 0) {
30568
- const task = pickNextTask();
30851
+ while (pendingSymbolIndexTasks.size > 0) {
30852
+ await yieldForBridgeInteractivePriority();
30853
+ const task = pickNextSymbolIndexTask();
30569
30854
  if (task == null) break;
30570
- pending.delete(symbolIndexTaskKey(task.parentPath, task.filePath));
30855
+ pendingSymbolIndexTasks.delete(symbolIndexTaskKey(task.parentPath, task.filePath));
30571
30856
  await yieldDuringCodeNavWork(yieldState);
30572
30857
  const latestActiveSequence = latestActiveSequenceByParent.get(task.parentPath);
30573
30858
  if (latestActiveSequence != null && task.sequence != null && task.sequence < latestActiveSequence) {
30574
30859
  continue;
30575
30860
  }
30576
30861
  if (!await symbolIndexFileIsReadyAsync(task.parentPath, task.filePath)) {
30577
- await ensureSymbolIndexFileAsync(task.parentPath, task.filePath);
30862
+ try {
30863
+ await ensureSymbolIndexFileAsync(task.parentPath, task.filePath);
30864
+ } catch (err) {
30865
+ if (isSymbolIndexDeferredError(err)) {
30866
+ if (addPendingSymbolIndexTask(task)) void runWorker();
30867
+ continue;
30868
+ }
30869
+ throw err;
30870
+ }
30578
30871
  }
30579
- await yieldToEventLoop();
30872
+ await yieldForBridgeInteractivePriority();
30580
30873
  }
30581
30874
  } finally {
30582
- if (pending.size === 0) heap.clear();
30583
- workerRunning = false;
30584
- if (pending.size > 0) void runWorker();
30875
+ clearSymbolIndexHeapIfEmpty();
30876
+ setSymbolIndexWorkerRunning(false);
30877
+ if (pendingSymbolIndexTasks.size > 0) void runWorker();
30585
30878
  }
30586
30879
  }
30880
+ function kickSymbolIndexWorker() {
30881
+ void runWorker();
30882
+ }
30883
+
30884
+ // src/code-nav/symbol-index/scheduler/task-queue-enqueue.ts
30587
30885
  function enqueueSymbolIndexTask(parentPath, filePath, priority, sequence) {
30588
30886
  const normalizedParent = normalizeResolvedPath(parentPath);
30589
30887
  const normalizedFile = filePath.replace(/\\/g, "/").replace(/^\/+/, "");
30590
30888
  if (!normalizedFile) return;
30591
- const key = symbolIndexTaskKey(normalizedParent, normalizedFile);
30592
- const existing = pending.get(key);
30593
- if (existing != null && existing.priority >= priority) return;
30594
- const task = { parentPath: normalizedParent, filePath: normalizedFile, priority, sequence };
30595
- pending.set(key, task);
30596
- heap.push(task);
30597
- void runWorker();
30889
+ const added = addPendingSymbolIndexTask({
30890
+ parentPath: normalizedParent,
30891
+ filePath: normalizedFile,
30892
+ priority,
30893
+ sequence
30894
+ });
30895
+ if (added) kickSymbolIndexWorker();
30598
30896
  }
30599
30897
  function markLatestActiveSymbolIndexTask(parentPath, sequence) {
30600
30898
  const normalizedParent = normalizeResolvedPath(parentPath);
30601
30899
  const existing = latestActiveSequenceByParent.get(normalizedParent);
30602
30900
  if (existing != null && existing >= sequence) return;
30603
30901
  latestActiveSequenceByParent.set(normalizedParent, sequence);
30604
- for (const [key, task] of pending) {
30902
+ for (const [key, task] of pendingSymbolIndexTasks) {
30605
30903
  if (task.parentPath === normalizedParent && task.sequence != null && task.sequence < sequence) {
30606
- pending.delete(key);
30904
+ pendingSymbolIndexTasks.delete(key);
30607
30905
  }
30608
30906
  }
30609
- if (pending.size === 0) heap.clear();
30907
+ if (pendingSymbolIndexTasks.size === 0) symbolIndexTaskHeap.clear();
30610
30908
  }
30611
30909
 
30612
- // src/code-nav/symbol-index/scheduler/symbol-index-scheduler.ts
30910
+ // src/code-nav/symbol-index/scheduler/symbol-index-warmup.ts
30911
+ init_normalize_resolved_path();
30613
30912
  var requestSeq = 0;
30614
30913
  var warmupSeq = 0;
30615
- var warmupScheduled = /* @__PURE__ */ new Set();
30616
30914
  var warmupCompleted = /* @__PURE__ */ new Set();
30915
+ var pendingWarmupParents = /* @__PURE__ */ new Set();
30916
+ var warmupWalkInProgress = /* @__PURE__ */ new Set();
30917
+ var WARMUP_IDLE_MS = 3e3;
30918
+ var warmupIdleTimer = null;
30919
+ function scheduleWarmupWhenIdle() {
30920
+ if (warmupIdleTimer != null) clearTimeout(warmupIdleTimer);
30921
+ warmupIdleTimer = setTimeout(() => {
30922
+ warmupIdleTimer = null;
30923
+ if (fileBrowserRequestInFlight()) {
30924
+ scheduleWarmupWhenIdle();
30925
+ return;
30926
+ }
30927
+ for (const parentPath of [...pendingWarmupParents]) {
30928
+ void runWarmupWalk(parentPath);
30929
+ }
30930
+ }, WARMUP_IDLE_MS);
30931
+ }
30932
+ registerFileBrowserActivityListener(() => {
30933
+ if (pendingWarmupParents.size > 0) scheduleWarmupWhenIdle();
30934
+ });
30935
+ async function runWarmupWalk(resolved) {
30936
+ if (warmupCompleted.has(resolved) || warmupWalkInProgress.has(resolved)) {
30937
+ pendingWarmupParents.delete(resolved);
30938
+ return;
30939
+ }
30940
+ warmupWalkInProgress.add(resolved);
30941
+ pendingWarmupParents.delete(resolved);
30942
+ try {
30943
+ const readyFiles = await loadSymbolIndexReadyFileSet(resolved);
30944
+ const walkState = createWalkYieldState();
30945
+ const yieldState = createCodeNavYieldState();
30946
+ await walkCodeNavFilesAsync(
30947
+ resolved,
30948
+ async (relPath) => {
30949
+ await yieldDuringCodeNavWork(yieldState);
30950
+ if (!readyFiles.has(relPath)) {
30951
+ enqueueSymbolIndexTask(resolved, relPath, ++warmupSeq, requestSeq);
30952
+ }
30953
+ },
30954
+ walkState
30955
+ );
30956
+ warmupCompleted.add(resolved);
30957
+ } finally {
30958
+ warmupWalkInProgress.delete(resolved);
30959
+ }
30960
+ }
30961
+
30962
+ // src/code-nav/symbol-index/scheduler/symbol-index-scheduler.ts
30963
+ var requestSeq2 = 0;
30617
30964
  function scheduleSymbolIndexFile(parentPath, filePath) {
30618
- const sequence = ++requestSeq;
30965
+ const sequence = ++requestSeq2;
30619
30966
  markLatestActiveSymbolIndexTask(parentPath, sequence);
30620
30967
  enqueueSymbolIndexTask(parentPath, filePath, 1e6 + sequence, sequence);
30621
30968
  }
30622
30969
  function scheduleSymbolIndexImportNeighbors(parentPath, filePaths) {
30623
- let priority = 5e5 + requestSeq;
30970
+ let priority = 5e5 + requestSeq2;
30624
30971
  for (const filePath of filePaths) {
30625
- enqueueSymbolIndexTask(parentPath, filePath, priority, requestSeq);
30972
+ enqueueSymbolIndexTask(parentPath, filePath, priority, requestSeq2);
30626
30973
  priority -= 1;
30627
30974
  }
30628
30975
  }
30629
- function scheduleSymbolIndexWarmup(parentPath) {
30630
- const resolved = normalizeResolvedPath(parentPath);
30631
- if (warmupCompleted.has(resolved)) return;
30632
- if (warmupScheduled.has(resolved)) return;
30633
- warmupScheduled.add(resolved);
30634
- setImmediate(() => {
30635
- void (async () => {
30636
- try {
30637
- const readyFiles = await loadSymbolIndexReadyFileSet(resolved);
30638
- const walkState = createWalkYieldState();
30639
- const yieldState = createCodeNavYieldState();
30640
- await walkCodeNavFilesAsync(
30641
- resolved,
30642
- async (relPath) => {
30643
- await yieldDuringCodeNavWork(yieldState);
30644
- if (!readyFiles.has(relPath)) {
30645
- enqueueSymbolIndexTask(resolved, relPath, ++warmupSeq, requestSeq);
30646
- }
30647
- },
30648
- walkState
30649
- );
30650
- warmupCompleted.add(resolved);
30651
- } finally {
30652
- warmupScheduled.delete(resolved);
30653
- }
30654
- })();
30655
- });
30656
- }
30976
+
30977
+ // src/code-nav/symbol-index/build/update-symbol-index-file.ts
30978
+ init_normalize_resolved_path();
30979
+ init_yield_to_event_loop();
30657
30980
 
30658
30981
  // src/code-nav/symbol-index/lifecycle/normalize-symbol-index-path.ts
30659
30982
  import path22 from "node:path";
30660
- function normalizeSymbolIndexRelPath(parentPath, changedPath) {
30983
+ function normalizeSymbolIndexRelPath2(parentPath, changedPath) {
30661
30984
  const resolvedParent = path22.resolve(parentPath);
30662
30985
  const abs = path22.isAbsolute(changedPath) ? path22.resolve(changedPath) : path22.resolve(resolvedParent, changedPath);
30663
30986
  const rel = path22.relative(resolvedParent, abs).replace(/\\/g, "/");
@@ -30667,7 +30990,7 @@ function normalizeSymbolIndexRelPath(parentPath, changedPath) {
30667
30990
 
30668
30991
  // src/code-nav/symbol-index/build/update-symbol-index-file.ts
30669
30992
  async function updateSymbolIndexForFile(parentPath, changedPath) {
30670
- const relPath = normalizeSymbolIndexRelPath(parentPath, changedPath);
30993
+ const relPath = normalizeSymbolIndexRelPath2(parentPath, changedPath);
30671
30994
  if (relPath == null) return;
30672
30995
  const resolved = normalizeResolvedPath(parentPath);
30673
30996
  const { source, tags, imports } = await extractFileSymbolData(resolved, relPath);
@@ -30677,7 +31000,7 @@ async function updateSymbolIndexForFile(parentPath, changedPath) {
30677
31000
  });
30678
31001
  }
30679
31002
  async function removeSymbolIndexForFile(parentPath, changedPath) {
30680
- const relPath = normalizeSymbolIndexRelPath(parentPath, changedPath);
31003
+ const relPath = normalizeSymbolIndexRelPath2(parentPath, changedPath);
30681
31004
  if (relPath == null) return;
30682
31005
  const resolved = normalizeResolvedPath(parentPath);
30683
31006
  await withSymbolIndexSqliteLock(async () => {
@@ -30685,6 +31008,10 @@ async function removeSymbolIndexForFile(parentPath, changedPath) {
30685
31008
  });
30686
31009
  }
30687
31010
 
31011
+ // src/code-nav/symbol-index/query/query-definitions.ts
31012
+ init_normalize_resolved_path();
31013
+ init_yield_to_event_loop();
31014
+
30688
31015
  // src/code-nav/symbol-index/sqlite/symbol-index-import-sqlite.ts
30689
31016
  function prefersTypeImport(refKind) {
30690
31017
  return refKind === "type";
@@ -31185,6 +31512,8 @@ async function queryDefinitionAt(parentPath, filePath, line, column) {
31185
31512
  }
31186
31513
 
31187
31514
  // src/code-nav/symbol-index/query/query-references.ts
31515
+ init_normalize_resolved_path();
31516
+ init_yield_to_event_loop();
31188
31517
  async function queryReferencesAt(parentPath, filePath, line, column) {
31189
31518
  await yieldToEventLoop();
31190
31519
  const resolved = normalizeResolvedPath(parentPath);
@@ -31208,6 +31537,8 @@ async function queryReferencesAt(parentPath, filePath, line, column) {
31208
31537
  }
31209
31538
 
31210
31539
  // src/code-nav/symbol-index/query/query-symbols-in-file.ts
31540
+ init_normalize_resolved_path();
31541
+ init_yield_to_event_loop();
31211
31542
  function rowToSymbolSpan(row, clickable) {
31212
31543
  return {
31213
31544
  name: row.name,
@@ -31293,6 +31624,7 @@ function createFileIndexFsWatcher(resolved, schedule) {
31293
31624
  // src/files/index/file-index-incremental-symbol-updates.ts
31294
31625
  import fs21 from "node:fs";
31295
31626
  import path23 from "node:path";
31627
+ init_yield_to_event_loop();
31296
31628
  async function applyIncrementalSymbolIndexUpdates(resolved, relPaths) {
31297
31629
  for (const rel of relPaths) {
31298
31630
  const absPath = path23.join(resolved, rel);
@@ -31316,6 +31648,7 @@ async function applyIncrementalSymbolIndexUpdates(resolved, relPaths) {
31316
31648
 
31317
31649
  // src/files/index/file-index-initial-builds.ts
31318
31650
  import path24 from "node:path";
31651
+ init_cwd();
31319
31652
  async function runInitialIndexBuilds(cwd = getBridgeRoot()) {
31320
31653
  const resolved = path24.resolve(cwd);
31321
31654
  try {
@@ -32371,6 +32704,7 @@ function getAgentModelFromAgentConfig(config2) {
32371
32704
  }
32372
32705
 
32373
32706
  // src/paths/session-layout-paths.ts
32707
+ init_cwd();
32374
32708
  import * as path26 from "node:path";
32375
32709
  function resolveIsolatedSessionParentPathFromCheckouts(worktreePaths) {
32376
32710
  const resolved = worktreePaths.map((p) => path26.resolve(p)).filter(Boolean);
@@ -32441,6 +32775,9 @@ async function execProbeShutdownAware(file2, args, timeoutMs) {
32441
32775
  }
32442
32776
  }
32443
32777
 
32778
+ // src/agents/acp/clients/sdk/sdk-stdio-acp-client.ts
32779
+ init_cwd();
32780
+
32444
32781
  // src/agents/acp/clients/agent-stderr-capture.ts
32445
32782
  var STDERR_CAPTURE_MAX = 48e3;
32446
32783
  function createStderrCapture(child) {
@@ -32829,11 +33166,11 @@ function createSdkStdioExtNotificationHandler(options) {
32829
33166
 
32830
33167
  // src/agents/acp/clients/sdk/sdk-stdio-permission-request-handshake.ts
32831
33168
  function awaitSdkStdioPermissionRequestHandshake(params) {
32832
- const { requestId, paramsRecord, pending: pending2, onRequest } = params;
33169
+ const { requestId, paramsRecord, pending, onRequest } = params;
32833
33170
  return new Promise((resolve37) => {
32834
- pending2.set(requestId, { resolve: resolve37, params: paramsRecord });
33171
+ pending.set(requestId, { resolve: resolve37, params: paramsRecord });
32835
33172
  if (onRequest == null) {
32836
- pending2.delete(requestId);
33173
+ pending.delete(requestId);
32837
33174
  resolve37({ outcome: { outcome: "denied" } });
32838
33175
  return;
32839
33176
  }
@@ -32849,9 +33186,9 @@ function awaitSdkStdioPermissionRequestHandshake(params) {
32849
33186
  }
32850
33187
 
32851
33188
  // src/agents/acp/clients/sdk/sdk-stdio-permission-pending.ts
32852
- function resolvePendingSdkStdioPermissionCancellations(pending2) {
32853
- for (const [id, entry] of [...pending2.entries()]) {
32854
- pending2.delete(id);
33189
+ function resolvePendingSdkStdioPermissionCancellations(pending) {
33190
+ for (const [id, entry] of [...pending.entries()]) {
33191
+ pending.delete(id);
32855
33192
  entry.resolve({ outcome: { outcome: "cancelled" } });
32856
33193
  }
32857
33194
  }
@@ -33523,6 +33860,7 @@ __export(cursor_acp_client_exports, {
33523
33860
  createCursorAcpClient: () => createCursorAcpClient,
33524
33861
  detectLocalAgentPresence: () => detectLocalAgentPresence3
33525
33862
  });
33863
+ init_cwd();
33526
33864
 
33527
33865
  // src/agents/acp/clients/cursor/cursor-spawn-command.ts
33528
33866
  function buildCursorAcpSpawnCommand(base, sessionMode) {
@@ -33554,8 +33892,8 @@ function createCursorAcpSessionContext(options) {
33554
33892
 
33555
33893
  // src/agents/acp/clients/cursor/cancel-pending-cursor-permission-requests.ts
33556
33894
  function cancelPendingCursorPermissionRequests(pendingRequests, respond) {
33557
- for (const [reqId, pending2] of [...pendingRequests.entries()]) {
33558
- if (pending2.method === "session/request_permission") {
33895
+ for (const [reqId, pending] of [...pendingRequests.entries()]) {
33896
+ if (pending.method === "session/request_permission") {
33559
33897
  respond(reqId, { outcome: { outcome: "cancelled" } });
33560
33898
  pendingRequests.delete(reqId);
33561
33899
  }
@@ -33734,8 +34072,8 @@ function handleCursorIncomingPermissionRequest(id, method, msg, deps) {
33734
34072
 
33735
34073
  // src/agents/acp/clients/cursor/cursor-incoming-resolve-request.ts
33736
34074
  function resolveCursorIncomingRequest(pendingRequests, respond, requestId, result) {
33737
- const pending2 = pendingRequests.get(requestId);
33738
- const payload = pending2?.method === "session/request_permission" ? enrichAcpPermissionRpcResultFromRequestParams(result, pending2.params) : result;
34075
+ const pending = pendingRequests.get(requestId);
34076
+ const payload = pending?.method === "session/request_permission" ? enrichAcpPermissionRpcResultFromRequestParams(result, pending.params) : result;
33739
34077
  respond(requestId, payload);
33740
34078
  pendingRequests.delete(requestId);
33741
34079
  }
@@ -33872,25 +34210,25 @@ function createCursorJsonRpcInboundRespond(stdin) {
33872
34210
 
33873
34211
  // src/agents/acp/clients/cursor/cursor-json-rpc-outbound.ts
33874
34212
  function createCursorJsonRpcOutboundPending() {
33875
- const pending2 = /* @__PURE__ */ new Map();
34213
+ const pending = /* @__PURE__ */ new Map();
33876
34214
  let nextId = 1;
33877
34215
  function allocateId() {
33878
34216
  return nextId++;
33879
34217
  }
33880
34218
  function register(id, waiter) {
33881
- pending2.set(id, waiter);
34219
+ pending.set(id, waiter);
33882
34220
  }
33883
34221
  function settleResponse(id, msg) {
33884
- const waiter = pending2.get(id);
34222
+ const waiter = pending.get(id);
33885
34223
  if (!waiter) return false;
33886
- pending2.delete(id);
34224
+ pending.delete(id);
33887
34225
  if (msg.error) waiter.reject(msg.error);
33888
34226
  else waiter.resolve(msg.result);
33889
34227
  return true;
33890
34228
  }
33891
34229
  function rejectOnWriteError(id, err) {
33892
- const waiter = pending2.get(id);
33893
- pending2.delete(id);
34230
+ const waiter = pending.get(id);
34231
+ pending.delete(id);
33894
34232
  waiter?.reject(err);
33895
34233
  }
33896
34234
  return { allocateId, register, settleResponse, rejectOnWriteError };
@@ -35410,8 +35748,8 @@ async function execGitFile(args, options) {
35410
35748
  }
35411
35749
 
35412
35750
  // src/git/changes/parse/normalize-git-diff-path.ts
35413
- function normalizeGitDiffPath(path81) {
35414
- return path81.replace(/\\/g, "/").replace(/\/ +/g, "/").trim();
35751
+ function normalizeGitDiffPath(path84) {
35752
+ return path84.replace(/\\/g, "/").replace(/\/ +/g, "/").trim();
35415
35753
  }
35416
35754
 
35417
35755
  // src/git/changes/parse/parse-name-status-entries.ts
@@ -36856,8 +37194,10 @@ async function createBridgeAccessState(options = {}) {
36856
37194
 
36857
37195
  // src/agents/capabilities/warmup-agent-capabilities-on-connect.ts
36858
37196
  import * as path36 from "node:path";
37197
+ init_cwd();
36859
37198
 
36860
37199
  // src/agents/detect-local-agent-types.ts
37200
+ init_yield_to_event_loop();
36861
37201
  var LOCAL_AGENT_ACP_MODULES = [
36862
37202
  cursor_acp_client_exports,
36863
37203
  codex_acp_client_exports,
@@ -36886,6 +37226,9 @@ async function detectLocalAgentTypes() {
36886
37226
  }
36887
37227
  }
36888
37228
 
37229
+ // src/agents/capabilities/probe-agent-capabilities-for-types.ts
37230
+ init_yield_to_event_loop();
37231
+
36889
37232
  // src/sqlite/hash-json-sha256.ts
36890
37233
  import { createHash as createHash2 } from "node:crypto";
36891
37234
  function hashJsonUtf8Sha256(value) {
@@ -37062,6 +37405,9 @@ async function probeAgentCapabilitiesForDetectedTypes(params) {
37062
37405
  return changedCount;
37063
37406
  }
37064
37407
 
37408
+ // src/agents/capabilities/warmup-agent-capabilities-on-connect.ts
37409
+ init_yield_to_event_loop();
37410
+
37065
37411
  // src/agents/capabilities/agent-capability-warmup-run.ts
37066
37412
  var warmupEpoch = 0;
37067
37413
  function cancelInFlightAgentCapabilityWarmup() {
@@ -37203,6 +37549,7 @@ async function createBridgeAccessAndAcp(options) {
37203
37549
  }
37204
37550
 
37205
37551
  // src/connection/create-bridge-preview-stack.ts
37552
+ init_cwd();
37206
37553
  import * as path39 from "node:path";
37207
37554
 
37208
37555
  // src/preview-environments/manager/firehose-messages.ts
@@ -38727,11 +39074,11 @@ function tryConsumeBinaryProxyBody(raw, deps) {
38727
39074
  if (!PROXY_ID_RE.test(id)) return false;
38728
39075
  const body = raw.slice(PROXY_ID_BYTES);
38729
39076
  const bodyBytes = body.length > 0 ? new Uint8Array(body) : new Uint8Array(0);
38730
- const pending2 = deps.pendingProxyBody.get(id);
38731
- if (pending2) {
39077
+ const pending = deps.pendingProxyBody.get(id);
39078
+ if (pending) {
38732
39079
  deps.pendingProxyBody.delete(id);
38733
39080
  deps.startStreamingProxy({
38734
- ...pending2.pr,
39081
+ ...pending.pr,
38735
39082
  body: bodyBytes.length > 0 ? bodyBytes : void 0
38736
39083
  });
38737
39084
  return true;
@@ -39093,7 +39440,11 @@ function createBridgeMessageDeps(params) {
39093
39440
  };
39094
39441
  }
39095
39442
 
39443
+ // src/connection/create-bridge-local-reports.ts
39444
+ init_cwd();
39445
+
39096
39446
  // src/skills/discovery/skill-discovery-roots.ts
39447
+ init_yield_to_event_loop();
39097
39448
  var SKILL_DISCOVERY_ROOTS = [".agents/skills", ".claude/skills", ".cursor/skills", "skills"];
39098
39449
  async function yieldSkillDiscoveryWork(entryCount) {
39099
39450
  if (entryCount > 0 && entryCount % INDEX_WORK_YIELD_EVERY === 0) {
@@ -39284,9 +39635,9 @@ function createBridgeHeartbeatController(params) {
39284
39635
  if (awaitingSeq === null) return;
39285
39636
  if (!Number.isFinite(seq)) return;
39286
39637
  const ack = Math.trunc(seq);
39287
- const pending2 = awaitingSeq;
39288
- if (ack < pending2) return;
39289
- if (ack === pending2) {
39638
+ const pending = awaitingSeq;
39639
+ if (ack < pending) return;
39640
+ if (ack === pending) {
39290
39641
  const rtt = Date.now() - sentAtMs;
39291
39642
  if (Number.isFinite(rtt) && rtt >= 0 && rtt < 6e5) {
39292
39643
  rttSamples.push(rtt);
@@ -39418,6 +39769,7 @@ function allocateDirNameForLauncherCwd(layout, bridgeRootPath2) {
39418
39769
  }
39419
39770
 
39420
39771
  // src/worktrees/manager/session-worktree-cache.ts
39772
+ init_normalize_resolved_path();
39421
39773
  var SessionWorktreeCache = class {
39422
39774
  sessionRepoCheckoutPaths = /* @__PURE__ */ new Map();
39423
39775
  sessionParentPathBySession = /* @__PURE__ */ new Map();
@@ -39458,6 +39810,9 @@ function createSessionWorktreeManagerContext(options) {
39458
39810
  };
39459
39811
  }
39460
39812
 
39813
+ // src/worktrees/manager/git/commit-session-worktree.ts
39814
+ init_cwd();
39815
+
39461
39816
  // ../../node_modules/.pnpm/simple-git@3.32.3/node_modules/simple-git/dist/esm/index.js
39462
39817
  var import_file_exists = __toESM(require_dist(), 1);
39463
39818
  var import_debug = __toESM(require_src(), 1);
@@ -39495,8 +39850,8 @@ function pathspec(...paths) {
39495
39850
  cache.set(key, paths);
39496
39851
  return key;
39497
39852
  }
39498
- function isPathSpec(path81) {
39499
- return path81 instanceof String && cache.has(path81);
39853
+ function isPathSpec(path84) {
39854
+ return path84 instanceof String && cache.has(path84);
39500
39855
  }
39501
39856
  function toPaths(pathSpec) {
39502
39857
  return cache.get(pathSpec) || [];
@@ -39585,8 +39940,8 @@ function toLinesWithContent(input = "", trimmed2 = true, separator = "\n") {
39585
39940
  function forEachLineWithContent(input, callback) {
39586
39941
  return toLinesWithContent(input, true).map((line) => callback(line));
39587
39942
  }
39588
- function folderExists(path81) {
39589
- return (0, import_file_exists.exists)(path81, import_file_exists.FOLDER);
39943
+ function folderExists(path84) {
39944
+ return (0, import_file_exists.exists)(path84, import_file_exists.FOLDER);
39590
39945
  }
39591
39946
  function append(target, item) {
39592
39947
  if (Array.isArray(target)) {
@@ -39990,8 +40345,8 @@ function checkIsRepoRootTask() {
39990
40345
  commands,
39991
40346
  format: "utf-8",
39992
40347
  onError,
39993
- parser(path81) {
39994
- return /^\.(git)?$/.test(path81.trim());
40348
+ parser(path84) {
40349
+ return /^\.(git)?$/.test(path84.trim());
39995
40350
  }
39996
40351
  };
39997
40352
  }
@@ -40425,11 +40780,11 @@ function parseGrep(grep) {
40425
40780
  const paths = /* @__PURE__ */ new Set();
40426
40781
  const results = {};
40427
40782
  forEachLineWithContent(grep, (input) => {
40428
- const [path81, line, preview] = input.split(NULL);
40429
- paths.add(path81);
40430
- (results[path81] = results[path81] || []).push({
40783
+ const [path84, line, preview] = input.split(NULL);
40784
+ paths.add(path84);
40785
+ (results[path84] = results[path84] || []).push({
40431
40786
  line: asNumber(line),
40432
- path: path81,
40787
+ path: path84,
40433
40788
  preview
40434
40789
  });
40435
40790
  });
@@ -41194,14 +41549,14 @@ var init_hash_object = __esm2({
41194
41549
  init_task();
41195
41550
  }
41196
41551
  });
41197
- function parseInit(bare, path81, text) {
41552
+ function parseInit(bare, path84, text) {
41198
41553
  const response = String(text).trim();
41199
41554
  let result;
41200
41555
  if (result = initResponseRegex.exec(response)) {
41201
- return new InitSummary(bare, path81, false, result[1]);
41556
+ return new InitSummary(bare, path84, false, result[1]);
41202
41557
  }
41203
41558
  if (result = reInitResponseRegex.exec(response)) {
41204
- return new InitSummary(bare, path81, true, result[1]);
41559
+ return new InitSummary(bare, path84, true, result[1]);
41205
41560
  }
41206
41561
  let gitDir = "";
41207
41562
  const tokens = response.split(" ");
@@ -41212,7 +41567,7 @@ function parseInit(bare, path81, text) {
41212
41567
  break;
41213
41568
  }
41214
41569
  }
41215
- return new InitSummary(bare, path81, /^re/i.test(response), gitDir);
41570
+ return new InitSummary(bare, path84, /^re/i.test(response), gitDir);
41216
41571
  }
41217
41572
  var InitSummary;
41218
41573
  var initResponseRegex;
@@ -41221,9 +41576,9 @@ var init_InitSummary = __esm2({
41221
41576
  "src/lib/responses/InitSummary.ts"() {
41222
41577
  "use strict";
41223
41578
  InitSummary = class {
41224
- constructor(bare, path81, existing, gitDir) {
41579
+ constructor(bare, path84, existing, gitDir) {
41225
41580
  this.bare = bare;
41226
- this.path = path81;
41581
+ this.path = path84;
41227
41582
  this.existing = existing;
41228
41583
  this.gitDir = gitDir;
41229
41584
  }
@@ -41235,7 +41590,7 @@ var init_InitSummary = __esm2({
41235
41590
  function hasBareCommand(command) {
41236
41591
  return command.includes(bareCommand);
41237
41592
  }
41238
- function initTask(bare = false, path81, customArgs) {
41593
+ function initTask(bare = false, path84, customArgs) {
41239
41594
  const commands = ["init", ...customArgs];
41240
41595
  if (bare && !hasBareCommand(commands)) {
41241
41596
  commands.splice(1, 0, bareCommand);
@@ -41244,7 +41599,7 @@ function initTask(bare = false, path81, customArgs) {
41244
41599
  commands,
41245
41600
  format: "utf-8",
41246
41601
  parser(text) {
41247
- return parseInit(commands.includes("--bare"), path81, text);
41602
+ return parseInit(commands.includes("--bare"), path84, text);
41248
41603
  }
41249
41604
  };
41250
41605
  }
@@ -42060,12 +42415,12 @@ var init_FileStatusSummary = __esm2({
42060
42415
  "use strict";
42061
42416
  fromPathRegex = /^(.+)\0(.+)$/;
42062
42417
  FileStatusSummary = class {
42063
- constructor(path81, index, working_dir) {
42064
- this.path = path81;
42418
+ constructor(path84, index, working_dir) {
42419
+ this.path = path84;
42065
42420
  this.index = index;
42066
42421
  this.working_dir = working_dir;
42067
42422
  if (index === "R" || working_dir === "R") {
42068
- const detail = fromPathRegex.exec(path81) || [null, path81, path81];
42423
+ const detail = fromPathRegex.exec(path84) || [null, path84, path84];
42069
42424
  this.from = detail[2] || "";
42070
42425
  this.path = detail[1] || "";
42071
42426
  }
@@ -42096,14 +42451,14 @@ function splitLine(result, lineStr) {
42096
42451
  default:
42097
42452
  return;
42098
42453
  }
42099
- function data(index, workingDir, path81) {
42454
+ function data(index, workingDir, path84) {
42100
42455
  const raw = `${index}${workingDir}`;
42101
42456
  const handler = parsers6.get(raw);
42102
42457
  if (handler) {
42103
- handler(result, path81);
42458
+ handler(result, path84);
42104
42459
  }
42105
42460
  if (raw !== "##" && raw !== "!!") {
42106
- result.files.push(new FileStatusSummary(path81, index, workingDir));
42461
+ result.files.push(new FileStatusSummary(path84, index, workingDir));
42107
42462
  }
42108
42463
  }
42109
42464
  }
@@ -42412,9 +42767,9 @@ var init_simple_git_api = __esm2({
42412
42767
  next
42413
42768
  );
42414
42769
  }
42415
- hashObject(path81, write) {
42770
+ hashObject(path84, write) {
42416
42771
  return this._runTask(
42417
- hashObjectTask(path81, write === true),
42772
+ hashObjectTask(path84, write === true),
42418
42773
  trailingFunctionArgument(arguments)
42419
42774
  );
42420
42775
  }
@@ -42767,8 +43122,8 @@ var init_branch = __esm2({
42767
43122
  }
42768
43123
  });
42769
43124
  function toPath(input) {
42770
- const path81 = input.trim().replace(/^["']|["']$/g, "");
42771
- return path81 && normalize3(path81);
43125
+ const path84 = input.trim().replace(/^["']|["']$/g, "");
43126
+ return path84 && normalize3(path84);
42772
43127
  }
42773
43128
  var parseCheckIgnore;
42774
43129
  var init_CheckIgnore = __esm2({
@@ -43082,8 +43437,8 @@ __export2(sub_module_exports, {
43082
43437
  subModuleTask: () => subModuleTask,
43083
43438
  updateSubModuleTask: () => updateSubModuleTask
43084
43439
  });
43085
- function addSubModuleTask(repo, path81) {
43086
- return subModuleTask(["add", repo, path81]);
43440
+ function addSubModuleTask(repo, path84) {
43441
+ return subModuleTask(["add", repo, path84]);
43087
43442
  }
43088
43443
  function initSubModuleTask(customArgs) {
43089
43444
  return subModuleTask(["init", ...customArgs]);
@@ -43416,8 +43771,8 @@ var require_git = __commonJS2({
43416
43771
  }
43417
43772
  return this._runTask(straightThroughStringTask2(command, this._trimmed), next);
43418
43773
  };
43419
- Git2.prototype.submoduleAdd = function(repo, path81, then) {
43420
- return this._runTask(addSubModuleTask2(repo, path81), trailingFunctionArgument2(arguments));
43774
+ Git2.prototype.submoduleAdd = function(repo, path84, then) {
43775
+ return this._runTask(addSubModuleTask2(repo, path84), trailingFunctionArgument2(arguments));
43421
43776
  };
43422
43777
  Git2.prototype.submoduleUpdate = function(args, then) {
43423
43778
  return this._runTask(
@@ -44153,8 +44508,8 @@ function parseNumstatEntries(lines) {
44153
44508
  }
44154
44509
  function parseNumstat(lines) {
44155
44510
  const m = /* @__PURE__ */ new Map();
44156
- for (const [path81, entry] of parseNumstatEntries(lines)) {
44157
- m.set(path81, { additions: entry.additions, deletions: entry.deletions });
44511
+ for (const [path84, entry] of parseNumstatEntries(lines)) {
44512
+ m.set(path84, { additions: entry.additions, deletions: entry.deletions });
44158
44513
  }
44159
44514
  return m;
44160
44515
  }
@@ -44352,6 +44707,7 @@ async function pushAheadOfUpstreamForPaths(paths) {
44352
44707
  }
44353
44708
 
44354
44709
  // src/worktrees/manager/resolve-commit-targets.ts
44710
+ init_cwd();
44355
44711
  function bridgeRootBinding(bridgeRoot) {
44356
44712
  return {
44357
44713
  sessionParentPath: bridgeRoot,
@@ -44437,6 +44793,7 @@ function formatRemoteDisplayLabel(remoteUrl) {
44437
44793
  }
44438
44794
 
44439
44795
  // src/git/changes/repo/get-working-tree-change-repo-details.ts
44796
+ init_cwd();
44440
44797
  import * as path52 from "node:path";
44441
44798
 
44442
44799
  // src/git/changes/repo/build-working-tree-change-repo-detail.ts
@@ -44686,6 +45043,7 @@ function createHydrateSourceLines(options) {
44686
45043
  }
44687
45044
 
44688
45045
  // src/git/changes/patch/hydrate/create-hydrate-yield.ts
45046
+ init_yield_to_event_loop();
44689
45047
  function createHydrateYield() {
44690
45048
  let processedLines = 0;
44691
45049
  return async () => {
@@ -45449,6 +45807,7 @@ function parseWorkingTreeChangeKind(value) {
45449
45807
  }
45450
45808
 
45451
45809
  // src/worktrees/manager/git/get-session-working-tree-change-file-patch.ts
45810
+ init_cwd();
45452
45811
  import * as path54 from "node:path";
45453
45812
  async function getSessionWorkingTreeChangeFilePatch(cache2, sessionId, discover, opts) {
45454
45813
  const targets = await resolveCommitTargetsAsync(sessionId, cache2, discover);
@@ -45499,6 +45858,8 @@ import * as fs36 from "node:fs";
45499
45858
  import * as fs35 from "node:fs";
45500
45859
 
45501
45860
  // src/worktrees/is-removable-session-worktree-checkout-path.ts
45861
+ init_cwd();
45862
+ init_normalize_resolved_path();
45502
45863
  import path55 from "node:path";
45503
45864
  function isBridgeRootCheckoutPath(checkoutPath) {
45504
45865
  return normalizeResolvedPath(checkoutPath) === normalizeResolvedPath(getBridgeRoot());
@@ -45599,9 +45960,13 @@ async function renameSessionWorktreeBranch(cache2, sessionId, newBranch, log2) {
45599
45960
  await renameSessionWorktreeBranches(paths, newBranch, log2);
45600
45961
  }
45601
45962
 
45963
+ // src/worktrees/manager/discover-session-binding.ts
45964
+ init_cwd();
45965
+
45602
45966
  // src/worktrees/discovery/discover-session-worktree-on-disk.ts
45603
45967
  import * as fs40 from "node:fs";
45604
45968
  import * as path61 from "node:path";
45969
+ init_yield_to_event_loop();
45605
45970
 
45606
45971
  // src/worktrees/discovery/collect-worktree-paths.ts
45607
45972
  import * as fs38 from "node:fs";
@@ -45635,6 +46000,7 @@ function shouldSkipDiskWalkEntry(name) {
45635
46000
  // src/worktrees/discovery/disk-walk-utils.ts
45636
46001
  import * as fs37 from "node:fs";
45637
46002
  import * as path57 from "node:path";
46003
+ init_yield_to_event_loop();
45638
46004
  async function yieldDuringDiskWalk(state) {
45639
46005
  state.entries++;
45640
46006
  if (state.entries % DISK_WALK_YIELD_EVERY !== 0) return true;
@@ -45824,6 +46190,7 @@ import * as path63 from "node:path";
45824
46190
 
45825
46191
  // src/worktrees/discovery/discover-legacy-binding-ascending-from-checkout.ts
45826
46192
  import * as path62 from "node:path";
46193
+ init_yield_to_event_loop();
45827
46194
  async function discoverLegacyBindingAscendingFromCheckout(sessionId, checkoutPath) {
45828
46195
  const sid = sessionId.trim();
45829
46196
  if (!sid) return null;
@@ -45941,11 +46308,16 @@ function parseSessionParent(v) {
45941
46308
  return null;
45942
46309
  }
45943
46310
 
46311
+ // src/worktrees/manager/prepare-and-remember-session-worktrees.ts
46312
+ init_cwd();
46313
+
45944
46314
  // src/worktrees/prepare-new-isolated-worktrees.ts
45945
46315
  import * as fs43 from "node:fs";
45946
46316
  import * as path65 from "node:path";
45947
46317
 
45948
46318
  // src/git/discover-repos.ts
46319
+ init_cwd();
46320
+ init_yield_to_event_loop();
45949
46321
  import * as fs42 from "node:fs";
45950
46322
  import * as path64 from "node:path";
45951
46323
  var GIT_DISCOVER_YIELD_EVERY = 32;
@@ -46173,6 +46545,7 @@ async function resolveExistingSessionParentPath(sessionId, cache2, discover) {
46173
46545
 
46174
46546
  // src/worktrees/manager/resolve-explicit-session-parent-path.ts
46175
46547
  import * as path66 from "node:path";
46548
+ init_yield_to_event_loop();
46176
46549
  async function resolveExplicitSessionParentPath(params) {
46177
46550
  const resolved = path66.resolve(params.parentPathRaw);
46178
46551
  if (parseSessionParent(params.sessionParent) !== "worktrees_root") {
@@ -46338,7 +46711,12 @@ var SessionWorktreeManager = class {
46338
46711
  }
46339
46712
  };
46340
46713
 
46714
+ // src/worktrees/manager/preview-worktree-manager.ts
46715
+ init_cwd();
46716
+
46341
46717
  // src/worktrees/discovery/discover-preview-worktree-on-disk.ts
46718
+ init_cwd();
46719
+ init_yield_to_event_loop();
46342
46720
  import * as fs44 from "node:fs";
46343
46721
  import * as path67 from "node:path";
46344
46722
  async function discoverPreviewWorktreeOnDisk(options) {
@@ -46389,6 +46767,7 @@ async function discoverPreviewWorktreeForBridge(options) {
46389
46767
  }
46390
46768
 
46391
46769
  // src/worktrees/manager/preview-worktree-cache.ts
46770
+ init_normalize_resolved_path();
46392
46771
  var PreviewWorktreeCache = class {
46393
46772
  repoCheckoutPaths = /* @__PURE__ */ new Map();
46394
46773
  parentPathByEnvironment = /* @__PURE__ */ new Map();
@@ -46501,6 +46880,7 @@ var PreviewWorktreeManager = class {
46501
46880
  };
46502
46881
 
46503
46882
  // src/worktrees/deploy/deploy-session-to-preview-environment.ts
46883
+ init_cwd();
46504
46884
  import * as path71 from "node:path";
46505
46885
 
46506
46886
  // src/git/worktrees/reset-worktree-to-branch.ts
@@ -47198,6 +47578,7 @@ async function applyPreTurnSnapshot(filePath, log2) {
47198
47578
  }
47199
47579
 
47200
47580
  // src/prompt-turn-queue/runner/run-local-revert-before-queued-prompt.ts
47581
+ init_cwd();
47201
47582
  async function runLocalRevertBeforeQueuedPrompt(next, deps) {
47202
47583
  if (next.bridgeServerState !== "requeued_with_revert") return true;
47203
47584
  const sid = next.sessionId;
@@ -47387,6 +47768,7 @@ function parseWorktreeBaseBranches(msg) {
47387
47768
  }
47388
47769
 
47389
47770
  // src/agents/acp/from-bridge/bridge-prompt-preamble.ts
47771
+ init_cwd();
47390
47772
  import { execFile as execFile8 } from "node:child_process";
47391
47773
  import { promisify as promisify9 } from "node:util";
47392
47774
  var execFileAsync7 = promisify9(execFile8);
@@ -47594,6 +47976,7 @@ var handleSessionRequestResponseMessage = (msg, deps) => {
47594
47976
  };
47595
47977
 
47596
47978
  // src/skills/preview.ts
47979
+ init_cwd();
47597
47980
  import { spawn as spawn10 } from "node:child_process";
47598
47981
  var PREVIEW_API_BASE_PATH = "/__preview";
47599
47982
  var PREVIEW_SECRET_HEADER = "X-Preview-Secret";
@@ -47614,8 +47997,8 @@ function randomSecret() {
47614
47997
  }
47615
47998
  return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
47616
47999
  }
47617
- async function requestPreviewApi(port, secret, method, path81, body) {
47618
- const url2 = `http://127.0.0.1:${port}${path81}`;
48000
+ async function requestPreviewApi(port, secret, method, path84, body) {
48001
+ const url2 = `http://127.0.0.1:${port}${path84}`;
47619
48002
  const headers = {
47620
48003
  [PREVIEW_SECRET_HEADER]: secret,
47621
48004
  "Content-Type": "application/json"
@@ -47627,7 +48010,7 @@ async function requestPreviewApi(port, secret, method, path81, body) {
47627
48010
  });
47628
48011
  const data = await res.json().catch(() => ({}));
47629
48012
  if (!res.ok) {
47630
- throw new Error(data?.error ?? `Preview API ${method} ${path81}: ${res.status}`);
48013
+ throw new Error(data?.error ?? `Preview API ${method} ${path84}: ${res.status}`);
47631
48014
  }
47632
48015
  return data;
47633
48016
  }
@@ -47792,6 +48175,8 @@ var handleSkillCallMessage = (msg, { getWs, log: log2 }) => {
47792
48175
  };
47793
48176
 
47794
48177
  // src/files/resolve-file-browser-session-parent.ts
48178
+ init_normalize_resolved_path();
48179
+ init_cwd();
47795
48180
  async function resolveFileBrowserSessionParent(sessionWorktreeManager, sessionId) {
47796
48181
  const sid = sessionId?.trim();
47797
48182
  if (sid) {
@@ -47802,301 +48187,18 @@ async function resolveFileBrowserSessionParent(sessionWorktreeManager, sessionId
47802
48187
  return getBridgeRoot();
47803
48188
  }
47804
48189
 
47805
- // src/files/list-dir/index.ts
47806
- import fs49 from "node:fs";
47807
-
47808
- // src/files/ensure-under-cwd.ts
47809
- import path74 from "node:path";
47810
- function ensureUnderCwd(relativePath, cwd = getBridgeRoot()) {
47811
- const normalized = path74.normalize(relativePath).replace(/^(\.\/)+/, "");
47812
- const resolved = path74.resolve(cwd, normalized);
47813
- if (!resolved.startsWith(cwd + path74.sep) && resolved !== cwd) {
47814
- return null;
47815
- }
47816
- return resolved;
47817
- }
47818
-
47819
- // src/files/list-dir/types.ts
47820
- var LIST_DIR_YIELD_EVERY = 256;
47821
-
47822
- // src/files/list-dir/map-dir-entry.ts
47823
- import path75 from "node:path";
47824
- import fs48 from "node:fs";
47825
- async function mapDirEntry(d, relativePath, resolved) {
47826
- const entryPath = path75.join(relativePath || ".", d.name).replace(/\\/g, "/");
47827
- const fullPath = path75.join(resolved, d.name);
47828
- let isDir = d.isDirectory();
47829
- if (d.isSymbolicLink()) {
47830
- try {
47831
- const targetStat = await fs48.promises.stat(fullPath);
47832
- isDir = targetStat.isDirectory();
47833
- } catch {
47834
- isDir = false;
47835
- }
47836
- }
47837
- return {
47838
- name: d.name,
47839
- path: entryPath,
47840
- isDir,
47841
- isSymlink: d.isSymbolicLink()
47842
- };
47843
- }
47844
-
47845
- // src/files/list-dir/sort-entries.ts
47846
- function sortListEntries(entries) {
47847
- return entries.sort((a, b) => {
47848
- if (a.isDir !== b.isDir) return a.isDir ? -1 : 1;
47849
- return a.name.localeCompare(b.name, void 0, { sensitivity: "base" });
47850
- });
47851
- }
47852
-
47853
- // src/files/list-dir/index.ts
47854
- async function listDirAsync(relativePath, sessionParentPath = getBridgeRoot()) {
47855
- await yieldToEventLoop();
47856
- const resolved = ensureUnderCwd(relativePath || ".", sessionParentPath);
47857
- if (!resolved) {
47858
- return { error: "Path is outside working directory" };
47859
- }
47860
- try {
47861
- const names = await fs49.promises.readdir(resolved, { withFileTypes: true });
47862
- const entries = [];
47863
- for (let i = 0; i < names.length; i++) {
47864
- if (i > 0 && i % LIST_DIR_YIELD_EVERY === 0) {
47865
- await yieldToEventLoop();
47866
- }
47867
- entries.push(await mapDirEntry(names[i], relativePath, resolved));
47868
- }
47869
- return { entries: sortListEntries(entries) };
47870
- } catch (err) {
47871
- const message = err instanceof Error ? err.message : String(err);
47872
- return { error: message };
47873
- }
47874
- }
47875
-
47876
- // src/files/handle-file-browser-search.ts
47877
- import path76 from "node:path";
47878
- var SEARCH_LIMIT = 100;
47879
- function handleFileBrowserSearch(msg, socket, e2ee, sessionWorktreeManager) {
47880
- void (async () => {
47881
- await yieldToEventLoop();
47882
- const q = typeof msg.q === "string" ? msg.q : "";
47883
- const sessionParentPath = path76.resolve(
47884
- sessionWorktreeManager != null ? await resolveFileBrowserSessionParent(sessionWorktreeManager, msg.sessionId) : getBridgeRoot()
47885
- );
47886
- if (!await bridgeFileIndexIsPopulated(sessionParentPath)) {
47887
- const payload2 = {
47888
- type: "file_browser_search_response",
47889
- id: msg.id,
47890
- paths: [],
47891
- indexReady: false
47892
- };
47893
- sendWsMessage(socket, e2ee ? e2ee.encryptFields(payload2, ["paths"]) : payload2);
47894
- return;
47895
- }
47896
- const results = await searchBridgeFilePathsAsync(sessionParentPath, q, SEARCH_LIMIT);
47897
- const payload = {
47898
- type: "file_browser_search_response",
47899
- id: msg.id,
47900
- paths: results,
47901
- indexReady: true
47902
- };
47903
- sendWsMessage(socket, e2ee ? e2ee.encryptFields(payload, ["paths"]) : payload);
47904
- })();
47905
- }
47906
- function triggerFileIndexBuild(sessionParentPath = getBridgeRoot()) {
47907
- setImmediate(() => {
47908
- void ensureFileIndexAsync(sessionParentPath).catch((e) => {
47909
- console.error("[file-index] Background build failed:", e);
47910
- });
47911
- });
47912
- }
47913
-
47914
- // src/code-nav/handlers/send-code-nav-response.ts
47915
- var ENCRYPTED_FIELDS = ["definition", "definitions", "references", "symbols", "confidentTarget"];
47916
- function sendCodeNavResponse(socket, e2ee, payload) {
47917
- const fieldsToEncrypt = ENCRYPTED_FIELDS.filter((field) => field in payload && payload[field] !== void 0);
47918
- sendWsMessage(
47919
- socket,
47920
- e2ee && fieldsToEncrypt.length > 0 ? e2ee.encryptFields(payload, [...fieldsToEncrypt]) : payload
47921
- );
47922
- }
47923
-
47924
- // src/code-nav/handlers/handle-definition-op.ts
47925
- async function handleDefinitionOp(ctx) {
47926
- const definition = await queryDefinitionAt(ctx.sessionParentPath, ctx.reqPath, ctx.line, ctx.column);
47927
- sendCodeNavResponse(ctx.socket, ctx.e2ee, {
47928
- type: "code_nav_response",
47929
- id: ctx.msg.id,
47930
- indexReady: true,
47931
- definition
47932
- });
47933
- }
47934
-
47935
- // src/code-nav/handlers/handle-definitions-op.ts
47936
- async function handleDefinitionsOp(ctx) {
47937
- const { definitions, confidentTarget } = await queryDefinitionsNavigation(
47938
- ctx.sessionParentPath,
47939
- ctx.reqPath,
47940
- ctx.line,
47941
- ctx.column
47942
- );
47943
- sendCodeNavResponse(ctx.socket, ctx.e2ee, {
47944
- type: "code_nav_response",
47945
- id: ctx.msg.id,
47946
- indexReady: true,
47947
- definitions,
47948
- confidentTarget
47949
- });
47950
- }
47951
-
47952
- // src/code-nav/handlers/handle-references-op.ts
47953
- async function handleReferencesOp(ctx) {
47954
- const references = await queryReferencesAt(ctx.sessionParentPath, ctx.reqPath, ctx.line, ctx.column);
47955
- sendCodeNavResponse(ctx.socket, ctx.e2ee, {
47956
- type: "code_nav_response",
47957
- id: ctx.msg.id,
47958
- indexReady: true,
47959
- references
47960
- });
47961
- }
47962
-
47963
- // src/code-nav/handlers/handle-symbols-op.ts
47964
- async function handleSymbolsOp(ctx) {
47965
- const symbols = await querySymbolsInFile(ctx.sessionParentPath, ctx.reqPath);
47966
- sendCodeNavResponse(ctx.socket, ctx.e2ee, {
47967
- type: "code_nav_response",
47968
- id: ctx.msg.id,
47969
- indexReady: true,
47970
- symbols
47971
- });
47972
- }
47973
-
47974
- // src/code-nav/handlers/code-nav-op-context.ts
47975
- function normalizeCodeNavOp(op) {
47976
- if (op === "references" || op === "symbols" || op === "definitions") return op;
47977
- return "definition";
47978
- }
47979
-
47980
- // src/code-nav/handlers/resolve-code-nav-parent.ts
47981
- async function resolveCodeNavParentPath(sessionWorktreeManager, sessionId) {
47982
- const parent = sessionWorktreeManager != null ? await resolveFileBrowserSessionParent(sessionWorktreeManager, sessionId) : getBridgeRoot();
47983
- return normalizeResolvedPath(parent);
47984
- }
47985
-
47986
- // src/code-nav/handlers/prepare-code-nav-request.ts
47987
- var CODE_NAV_INDEX_READY_WAIT_MS = 75;
47988
- var CODE_NAV_INDEX_READY_POLL_MS = 15;
47989
- function delay2(ms) {
47990
- return new Promise((resolve37) => setTimeout(resolve37, ms));
47991
- }
47992
- async function waitForSymbolIndexReady(sessionParentPath, reqPath) {
47993
- const deadline = Date.now() + CODE_NAV_INDEX_READY_WAIT_MS;
47994
- do {
47995
- if (await symbolIndexFileIsReadyAsync(sessionParentPath, reqPath)) return true;
47996
- await delay2(CODE_NAV_INDEX_READY_POLL_MS);
47997
- } while (Date.now() < deadline);
47998
- return await symbolIndexFileIsReadyAsync(sessionParentPath, reqPath);
47999
- }
48000
- async function prepareCodeNavRequest(msg, socket, e2ee, sessionWorktreeManager) {
48001
- await yieldToEventLoop();
48002
- const reqPath = msg.path.replace(/^\/+/, "") || "";
48003
- if (!reqPath) {
48004
- sendCodeNavResponse(socket, e2ee, {
48005
- type: "code_nav_response",
48006
- id: msg.id,
48007
- error: "Path required"
48008
- });
48009
- return null;
48010
- }
48011
- const sessionParentPath = await resolveCodeNavParentPath(sessionWorktreeManager, msg.sessionId);
48012
- await registerSymbolIndexParentAsync(sessionParentPath);
48013
- scheduleSymbolIndexFile(sessionParentPath, reqPath);
48014
- const indexReady = await waitForSymbolIndexReady(sessionParentPath, reqPath);
48015
- if (indexReady) {
48016
- const importTargets = await listDirectImportTargetsForFileAsync(sessionParentPath, reqPath);
48017
- scheduleSymbolIndexImportNeighbors(sessionParentPath, importTargets);
48018
- }
48019
- scheduleSymbolIndexWarmup(sessionParentPath);
48020
- await yieldToEventLoop();
48021
- return {
48022
- socket,
48023
- e2ee,
48024
- msg,
48025
- reqPath,
48026
- sessionParentPath,
48027
- line: typeof msg.line === "number" ? msg.line : 1,
48028
- column: typeof msg.column === "number" ? msg.column : 0,
48029
- indexReady
48030
- };
48031
- }
48032
- function sendIndexNotReadyResponse(ctx) {
48033
- sendCodeNavResponse(ctx.socket, ctx.e2ee, {
48034
- type: "code_nav_response",
48035
- id: ctx.msg.id,
48036
- indexReady: false,
48037
- definition: null,
48038
- definitions: [],
48039
- references: [],
48040
- symbols: []
48041
- });
48042
- }
48043
- function preparedOpContext(ctx) {
48044
- return {
48045
- socket: ctx.socket,
48046
- e2ee: ctx.e2ee,
48047
- msg: { ...ctx.msg, op: normalizeCodeNavOp(ctx.msg.op) },
48048
- reqPath: ctx.reqPath,
48049
- sessionParentPath: ctx.sessionParentPath,
48050
- line: ctx.line,
48051
- column: ctx.column
48052
- };
48053
- }
48054
-
48055
- // src/code-nav/handlers/handle-code-nav-request.ts
48056
- function handleCodeNavRequest(msg, socket, e2ee, sessionWorktreeManager) {
48057
- void (async () => {
48058
- const prepared = await prepareCodeNavRequest(msg, socket, e2ee, sessionWorktreeManager);
48059
- if (prepared == null) return;
48060
- if (!prepared.indexReady) {
48061
- sendIndexNotReadyResponse(prepared);
48062
- return;
48063
- }
48064
- const ctx = preparedOpContext(prepared);
48065
- switch (ctx.msg.op) {
48066
- case "symbols":
48067
- await handleSymbolsOp(ctx);
48068
- return;
48069
- case "references":
48070
- await handleReferencesOp(ctx);
48071
- return;
48072
- case "definitions":
48073
- await handleDefinitionsOp(ctx);
48074
- return;
48075
- default:
48076
- await handleDefinitionOp(ctx);
48077
- }
48078
- })();
48079
- }
48080
-
48081
- // src/code-nav/handlers/trigger-symbol-index-build.ts
48082
- function triggerSymbolIndexBuild(parentPath) {
48083
- setImmediate(() => {
48084
- void (async () => {
48085
- const resolved = normalizeResolvedPath(parentPath);
48086
- await registerSymbolIndexParentAsync(resolved);
48087
- scheduleSymbolIndexWarmup(resolved);
48088
- })();
48089
- });
48090
- }
48190
+ // src/files/browser/handle-file-browser-list.ts
48191
+ init_list_dir();
48091
48192
 
48092
48193
  // src/git/tree/resolve-repo-abs-path.ts
48093
- import * as path77 from "node:path";
48194
+ init_cwd();
48195
+ import * as path76 from "node:path";
48094
48196
  function resolveRepoAbsPathFromBridge(repoRelPath, bridgeRoot = getBridgeRoot()) {
48095
- const bridgeResolved = path77.resolve(bridgeRoot);
48197
+ const bridgeResolved = path76.resolve(bridgeRoot);
48096
48198
  const rel = repoRelPath.trim() === "." ? "" : repoRelPath.trim().replace(/\\/g, "/");
48097
- const repoPath = rel === "" ? bridgeResolved : path77.join(bridgeResolved, rel);
48098
- const resolved = path77.resolve(repoPath);
48099
- if (!resolved.startsWith(bridgeResolved + path77.sep) && resolved !== bridgeResolved) {
48199
+ const repoPath = rel === "" ? bridgeResolved : path76.join(bridgeResolved, rel);
48200
+ const resolved = path76.resolve(repoPath);
48201
+ if (!resolved.startsWith(bridgeResolved + path76.sep) && resolved !== bridgeResolved) {
48100
48202
  return null;
48101
48203
  }
48102
48204
  return resolved;
@@ -48114,6 +48216,9 @@ async function resolveBranchCommit(repoAbsPath, branch) {
48114
48216
  }
48115
48217
 
48116
48218
  // src/git/tree/list-git-tree-dir.ts
48219
+ init_yield_to_event_loop();
48220
+ init_types2();
48221
+ init_sort_entries();
48117
48222
  function parseLsTreeLine(line) {
48118
48223
  const tab = line.indexOf(" ");
48119
48224
  if (tab < 0) return null;
@@ -48176,6 +48281,9 @@ async function listGitTreeDirAsync(repoAbsPath, branch, relativePath) {
48176
48281
  }
48177
48282
  }
48178
48283
 
48284
+ // src/git/tree/file/index.ts
48285
+ init_yield_to_event_loop();
48286
+
48179
48287
  // src/files/read-file/types.ts
48180
48288
  var LINE_CHUNK_SIZE = 64 * 1024;
48181
48289
  var READ_RANGE_YIELD_EVERY_BYTES = 256 * 1024;
@@ -48212,6 +48320,7 @@ function guessMimeType(filePath) {
48212
48320
  }
48213
48321
 
48214
48322
  // src/git/tree/file/git-blob-ref.ts
48323
+ init_yield_to_event_loop();
48215
48324
  async function gitBlobRef(repoAbsPath, branch, relativePath) {
48216
48325
  const commit = await resolveBranchCommit(repoAbsPath, branch);
48217
48326
  await yieldToEventLoop();
@@ -48231,6 +48340,7 @@ function isBinaryBuffer(buf) {
48231
48340
  }
48232
48341
 
48233
48342
  // src/git/tree/file/read-git-blob-text-async.ts
48343
+ init_yield_to_event_loop();
48234
48344
  import { StringDecoder } from "node:string_decoder";
48235
48345
  async function countGitBlobLinesAsync(buf) {
48236
48346
  if (buf.length === 0) return 1;
@@ -48479,6 +48589,145 @@ function sendFileBrowserMessage(socket, e2ee, payload) {
48479
48589
  sendWsMessage(socket, e2ee ? e2ee.encryptFields(payload, ["entries", "content", "totalLines", "size", "lineOffset"]) : payload);
48480
48590
  }
48481
48591
 
48592
+ // src/files/read-file/resolve-file-cache-warmup.ts
48593
+ init_yield_to_event_loop();
48594
+ import path78 from "node:path";
48595
+
48596
+ // src/files/read-file/resolve-file-cache.ts
48597
+ import fs50 from "node:fs";
48598
+ import path77 from "node:path";
48599
+ var RESOLVE_CACHE_MAX = 4096;
48600
+ var resolveCache = /* @__PURE__ */ new Map();
48601
+ var warmedDirectories = /* @__PURE__ */ new Set();
48602
+ function resolveCacheKey(sessionParentPath, relativePath) {
48603
+ return `${sessionParentPath}\0${relativePath}`;
48604
+ }
48605
+ function warmedDirectoryKey(sessionParentPath, directoryRelativePath) {
48606
+ const dir = directoryRelativePath.replace(/^\/+/, "") || ".";
48607
+ return `${path77.resolve(sessionParentPath)}\0${dir}`;
48608
+ }
48609
+ function pathStaysUnderParent(filePath, sessionParentPath) {
48610
+ const parent = path77.resolve(sessionParentPath);
48611
+ const resolved = path77.resolve(filePath);
48612
+ return resolved === parent || resolved.startsWith(`${parent}${path77.sep}`);
48613
+ }
48614
+ async function statMatchesCache(entry) {
48615
+ try {
48616
+ const stat3 = await fs50.promises.stat(entry.path);
48617
+ return stat3.isFile() && stat3.mtimeMs === entry.mtimeMs && stat3.size === entry.size;
48618
+ } catch {
48619
+ return false;
48620
+ }
48621
+ }
48622
+ function getResolveCacheEntry(cacheKey) {
48623
+ return resolveCache.get(cacheKey);
48624
+ }
48625
+ function deleteResolveCacheEntry(cacheKey) {
48626
+ resolveCache.delete(cacheKey);
48627
+ }
48628
+ function storeResolveCacheEntry(cacheKey, entry) {
48629
+ if (resolveCache.size >= RESOLVE_CACHE_MAX) resolveCache.clear();
48630
+ resolveCache.set(cacheKey, entry);
48631
+ return entry;
48632
+ }
48633
+ function hasResolveCacheEntry(cacheKey) {
48634
+ return resolveCache.has(cacheKey);
48635
+ }
48636
+ function markDirectoryWarmed(dirKey) {
48637
+ if (warmedDirectories.has(dirKey)) return false;
48638
+ warmedDirectories.add(dirKey);
48639
+ return true;
48640
+ }
48641
+ function unmarkDirectoryWarmed(dirKey) {
48642
+ warmedDirectories.delete(dirKey);
48643
+ }
48644
+
48645
+ // src/files/read-file/resolve-file-path.ts
48646
+ init_ensure_under_cwd();
48647
+ init_cwd();
48648
+ import fs51 from "node:fs";
48649
+ async function resolveFileForReadAsync(relativePath, sessionParentPath = getBridgeRoot()) {
48650
+ const cacheKey = resolveCacheKey(sessionParentPath, relativePath);
48651
+ const cached2 = getResolveCacheEntry(cacheKey);
48652
+ if (cached2 != null && await statMatchesCache(cached2)) {
48653
+ return { path: cached2.path, size: cached2.size };
48654
+ }
48655
+ if (cached2 != null) deleteResolveCacheEntry(cacheKey);
48656
+ const resolved = ensureUnderCwd(relativePath, sessionParentPath);
48657
+ if (!resolved) return { error: "Path is outside working directory" };
48658
+ let real;
48659
+ let size;
48660
+ let mtimeMs;
48661
+ try {
48662
+ const lstat = await fs51.promises.lstat(resolved);
48663
+ if (lstat.isSymbolicLink()) {
48664
+ real = await fs51.promises.realpath(resolved);
48665
+ if (!pathStaysUnderParent(real, sessionParentPath)) {
48666
+ return { error: "Path is outside working directory" };
48667
+ }
48668
+ const stat3 = await fs51.promises.stat(real);
48669
+ if (!stat3.isFile()) return { error: "Not a file" };
48670
+ size = stat3.size;
48671
+ mtimeMs = stat3.mtimeMs;
48672
+ } else if (lstat.isFile()) {
48673
+ real = resolved;
48674
+ size = lstat.size;
48675
+ mtimeMs = lstat.mtimeMs;
48676
+ } else {
48677
+ return { error: "Not a file" };
48678
+ }
48679
+ } catch (err) {
48680
+ return { error: err instanceof Error ? err.message : String(err) };
48681
+ }
48682
+ const entry = storeResolveCacheEntry(cacheKey, { path: real, size, mtimeMs });
48683
+ return { path: entry.path, size: entry.size };
48684
+ }
48685
+ async function resolveFilePathAsync(relativePath, sessionParentPath = getBridgeRoot()) {
48686
+ const result = await resolveFileForReadAsync(relativePath, sessionParentPath);
48687
+ if ("error" in result) return result;
48688
+ return result.path;
48689
+ }
48690
+
48691
+ // src/files/read-file/resolve-file-cache-warmup.ts
48692
+ var WARMED_DIRECTORY_TTL_MS = 6e4;
48693
+ async function warmDirectoryResolveCache(sessionParentPath, directoryRelativePath) {
48694
+ const { listDirAsync: listDirAsync2 } = await Promise.resolve().then(() => (init_list_dir(), list_dir_exports));
48695
+ const result = await listDirAsync2(directoryRelativePath, sessionParentPath);
48696
+ if ("error" in result) return;
48697
+ for (const entry of result.entries) {
48698
+ if (entry.isDir) continue;
48699
+ if (fileBrowserRequestInFlight()) return;
48700
+ const cacheKey = resolveCacheKey(sessionParentPath, entry.path);
48701
+ if (hasResolveCacheEntry(cacheKey)) continue;
48702
+ await resolveFileForReadAsync(entry.path, sessionParentPath).catch(() => void 0);
48703
+ await yieldToEventLoop();
48704
+ }
48705
+ }
48706
+ function scheduleDirectoryResolveCacheWarmup(sessionParentPath, directoryRelativePath) {
48707
+ const parent = path78.resolve(sessionParentPath);
48708
+ const dirKey = warmedDirectoryKey(parent, directoryRelativePath);
48709
+ if (!markDirectoryWarmed(dirKey)) return;
48710
+ setTimeout(() => unmarkDirectoryWarmed(dirKey), WARMED_DIRECTORY_TTL_MS);
48711
+ setImmediate(() => {
48712
+ void warmDirectoryResolveCache(parent, directoryRelativePath.replace(/^\/+/, "") || ".");
48713
+ });
48714
+ }
48715
+ function scheduleResolveCacheWarmupForListedEntries(sessionParentPath, listRelativePath, entries) {
48716
+ scheduleDirectoryResolveCacheWarmup(sessionParentPath, listRelativePath);
48717
+ setImmediate(() => {
48718
+ void (async () => {
48719
+ for (const entry of entries) {
48720
+ if (entry.isDir) continue;
48721
+ if (fileBrowserRequestInFlight()) return;
48722
+ const cacheKey = resolveCacheKey(sessionParentPath, entry.path);
48723
+ if (hasResolveCacheEntry(cacheKey)) continue;
48724
+ await resolveFileForReadAsync(entry.path, sessionParentPath).catch(() => void 0);
48725
+ await yieldToEventLoop();
48726
+ }
48727
+ })();
48728
+ });
48729
+ }
48730
+
48482
48731
  // src/files/browser/handle-file-browser-list.ts
48483
48732
  async function handleFileBrowserList(socket, e2ee, id, reqPath, sessionParentPath, gitScope) {
48484
48733
  const result = gitScope ? await listGitTreeDirAsync(gitScope.repoAbsPath, gitScope.branch, reqPath) : await listDirAsync(reqPath, sessionParentPath);
@@ -48487,38 +48736,138 @@ async function handleFileBrowserList(socket, e2ee, id, reqPath, sessionParentPat
48487
48736
  return;
48488
48737
  }
48489
48738
  sendFileBrowserMessage(socket, e2ee, { type: "file_browser_response", id, entries: result.entries });
48490
- if (!gitScope && (reqPath === "." || reqPath === "")) {
48491
- triggerFileIndexBuild(sessionParentPath);
48492
- if (sessionParentPath) triggerSymbolIndexBuild(sessionParentPath);
48739
+ if (!gitScope && sessionParentPath) {
48740
+ scheduleResolveCacheWarmupForListedEntries(sessionParentPath, reqPath, result.entries);
48493
48741
  }
48494
48742
  }
48495
48743
 
48496
- // src/files/read-file/resolve-file-path.ts
48497
- import fs50 from "node:fs";
48498
- async function resolveFilePathAsync(relativePath, sessionParentPath = getBridgeRoot()) {
48499
- const resolved = ensureUnderCwd(relativePath, sessionParentPath);
48500
- if (!resolved) return { error: "Path is outside working directory" };
48501
- let real;
48502
- try {
48503
- real = await fs50.promises.realpath(resolved);
48504
- } catch {
48505
- real = resolved;
48744
+ // src/files/browser/handle-file-browser-read.ts
48745
+ import path79 from "node:path";
48746
+ init_cwd();
48747
+
48748
+ // src/files/read-file/index.ts
48749
+ init_cwd();
48750
+ init_yield_to_event_loop();
48751
+ import fs55 from "node:fs";
48752
+
48753
+ // src/files/read-file/read-file-range-async.ts
48754
+ init_yield_to_event_loop();
48755
+ import fs52 from "node:fs";
48756
+ import { StringDecoder as StringDecoder2 } from "node:string_decoder";
48757
+
48758
+ // src/files/read-file/read-file-range-line-zero.ts
48759
+ function createLineZeroStreamState(lineOffsetIn) {
48760
+ return {
48761
+ line0Accum: "",
48762
+ skipLine0Chars: typeof lineOffsetIn === "number" ? lineOffsetIn : 0,
48763
+ line0CharsReturned: 0
48764
+ };
48765
+ }
48766
+ function shouldTrackLineZero(startLine, lineOffsetIn) {
48767
+ return startLine === 0 || lineOffsetIn !== void 0;
48768
+ }
48769
+ function stripCarriageReturn(lineContent) {
48770
+ return lineContent.endsWith("\r") ? lineContent.slice(0, -1) : lineContent;
48771
+ }
48772
+ function lineContentBeforeNewline(text, lineStart, newlineIndex) {
48773
+ let lineEnd = newlineIndex;
48774
+ if (lineEnd > lineStart && text[lineEnd - 1] === "\r") lineEnd--;
48775
+ return text.slice(lineStart, lineEnd);
48776
+ }
48777
+ function buildLineZeroChunkResult(resultLines, fileSize, lineOffset, totalLines = 1) {
48778
+ return {
48779
+ content: resultLines.join("\n"),
48780
+ size: fileSize,
48781
+ lineOffset,
48782
+ totalLines
48783
+ };
48784
+ }
48785
+ function tryFinishLineZeroOnCompleteLine(state, lineContent, resultLines, fileSize, lineChunkSize, lineOffsetIn, endLine, currentLine) {
48786
+ state.line0Accum += lineContent;
48787
+ const totalLine0 = state.line0Accum.length;
48788
+ if (state.skipLine0Chars > 0) {
48789
+ if (totalLine0 <= state.skipLine0Chars) {
48790
+ state.skipLine0Chars -= totalLine0;
48791
+ state.line0Accum = "";
48792
+ return currentLine + 1 > endLine ? "done" : "continue";
48793
+ }
48794
+ const from = state.skipLine0Chars;
48795
+ const take = Math.min(lineChunkSize, totalLine0 - from);
48796
+ resultLines.push(state.line0Accum.slice(from, from + take));
48797
+ state.line0CharsReturned += take;
48798
+ if (from + take < totalLine0) {
48799
+ return buildLineZeroChunkResult(
48800
+ resultLines,
48801
+ fileSize,
48802
+ (lineOffsetIn ?? 0) + state.line0CharsReturned
48803
+ );
48804
+ }
48805
+ state.line0Accum = "";
48806
+ state.skipLine0Chars = 0;
48807
+ state.line0CharsReturned = 0;
48808
+ return "continue";
48809
+ }
48810
+ if (totalLine0 > lineChunkSize) {
48811
+ resultLines.push(state.line0Accum.slice(0, lineChunkSize));
48812
+ return buildLineZeroChunkResult(resultLines, fileSize, lineChunkSize);
48813
+ }
48814
+ resultLines.push(state.line0Accum);
48815
+ state.line0Accum = "";
48816
+ return "continue";
48817
+ }
48818
+ function tryFinishLineZeroPartial(state, partialLine, resultLines, fileSize, lineChunkSize, lineOffsetIn) {
48819
+ state.line0Accum += partialLine;
48820
+ const totalLine0 = state.line0Accum.length;
48821
+ if (state.skipLine0Chars > 0) {
48822
+ if (totalLine0 <= state.skipLine0Chars) {
48823
+ state.skipLine0Chars -= totalLine0;
48824
+ state.line0Accum = "";
48825
+ return null;
48826
+ }
48827
+ const from = state.skipLine0Chars;
48828
+ const take = Math.min(lineChunkSize, totalLine0 - from);
48829
+ resultLines.push(state.line0Accum.slice(from, from + take));
48830
+ return buildLineZeroChunkResult(resultLines, fileSize, (lineOffsetIn ?? 0) + take);
48506
48831
  }
48507
- try {
48508
- const stat3 = await fs50.promises.stat(real);
48509
- if (!stat3.isFile()) return { error: "Not a file" };
48510
- return real;
48511
- } catch (err) {
48512
- return { error: err instanceof Error ? err.message : String(err) };
48832
+ if (totalLine0 > lineChunkSize) {
48833
+ resultLines.push(state.line0Accum.slice(0, lineChunkSize));
48834
+ return buildLineZeroChunkResult(resultLines, fileSize, lineChunkSize);
48513
48835
  }
48836
+ return null;
48837
+ }
48838
+ function finishLineZeroTail(state, tail, resultLines, fileSize, lineChunkSize, lineOffsetIn) {
48839
+ if (tail.length === 0) return null;
48840
+ state.line0Accum += stripCarriageReturn(tail);
48841
+ const totalLine0 = state.line0Accum.length;
48842
+ if (state.skipLine0Chars > 0) {
48843
+ if (totalLine0 <= state.skipLine0Chars) {
48844
+ return { content: resultLines.join("\n"), size: fileSize };
48845
+ }
48846
+ const from = state.skipLine0Chars;
48847
+ const take = Math.min(lineChunkSize, totalLine0 - from);
48848
+ resultLines.push(state.line0Accum.slice(from, from + take));
48849
+ state.line0CharsReturned += take;
48850
+ if (from + take < totalLine0) {
48851
+ return buildLineZeroChunkResult(
48852
+ resultLines,
48853
+ fileSize,
48854
+ (lineOffsetIn ?? 0) + state.line0CharsReturned
48855
+ );
48856
+ }
48857
+ return null;
48858
+ }
48859
+ if (totalLine0 > lineChunkSize) {
48860
+ resultLines.push(state.line0Accum.slice(0, lineChunkSize));
48861
+ return buildLineZeroChunkResult(resultLines, fileSize, lineChunkSize);
48862
+ }
48863
+ resultLines.push(state.line0Accum);
48864
+ return null;
48514
48865
  }
48515
48866
 
48516
48867
  // src/files/read-file/read-file-range-async.ts
48517
- import fs51 from "node:fs";
48518
- import { StringDecoder as StringDecoder2 } from "node:string_decoder";
48519
- async function readFileRangeAsync(filePath, startLine, endLine, lineOffsetIn, lineChunkSize = LINE_CHUNK_SIZE) {
48520
- const fileSize = (await fs51.promises.stat(filePath)).size;
48521
- const fd = await fs51.promises.open(filePath, "r");
48868
+ async function readFileRangeAsync(filePath, startLine, endLine, lineOffsetIn, lineChunkSize = LINE_CHUNK_SIZE, fileSizeIn) {
48869
+ const fileSize = fileSizeIn ?? (await fs52.promises.stat(filePath)).size;
48870
+ const fd = await fs52.promises.open(filePath, "r");
48522
48871
  const bufSize = 64 * 1024;
48523
48872
  const buf = Buffer.alloc(bufSize);
48524
48873
  const decoder = new StringDecoder2("utf8");
@@ -48526,9 +48875,8 @@ async function readFileRangeAsync(filePath, startLine, endLine, lineOffsetIn, li
48526
48875
  const resultLines = [];
48527
48876
  let partial2 = "";
48528
48877
  let done = false;
48529
- let skipLine0Chars = typeof lineOffsetIn === "number" ? lineOffsetIn : 0;
48530
- let line0CharsReturned = 0;
48531
- let line0Accum = "";
48878
+ const trackLineZero = shouldTrackLineZero(startLine, lineOffsetIn);
48879
+ const lineZeroState = createLineZeroStreamState(lineOffsetIn);
48532
48880
  let bytesSinceYield = 0;
48533
48881
  try {
48534
48882
  let position = 0;
@@ -48545,130 +48893,70 @@ async function readFileRangeAsync(filePath, startLine, endLine, lineOffsetIn, li
48545
48893
  partial2 = "";
48546
48894
  let lineStart = 0;
48547
48895
  for (let i = 0; i < text.length; i++) {
48548
- if (text[i] === "\n") {
48549
- const lineContent = (() => {
48550
- let lineEnd = i;
48551
- if (lineEnd > lineStart && text[lineEnd - 1] === "\r") lineEnd--;
48552
- return text.slice(lineStart, lineEnd);
48553
- })();
48554
- if (currentLine === 0 && (startLine === 0 || lineOffsetIn !== void 0)) {
48555
- line0Accum += lineContent;
48556
- const totalLine0 = line0Accum.length;
48557
- if (skipLine0Chars > 0) {
48558
- if (totalLine0 <= skipLine0Chars) {
48559
- skipLine0Chars -= totalLine0;
48560
- line0Accum = "";
48561
- currentLine++;
48562
- lineStart = i + 1;
48563
- if (currentLine > endLine) {
48564
- done = true;
48565
- break;
48566
- }
48567
- continue;
48568
- }
48569
- const from = skipLine0Chars;
48570
- const take = Math.min(lineChunkSize, totalLine0 - from);
48571
- resultLines.push(line0Accum.slice(from, from + take));
48572
- line0CharsReturned += take;
48573
- if (from + take < totalLine0) {
48574
- return {
48575
- content: resultLines.join("\n"),
48576
- size: fileSize,
48577
- lineOffset: lineOffsetIn + line0CharsReturned,
48578
- totalLines: 1
48579
- };
48580
- }
48581
- line0Accum = "";
48582
- skipLine0Chars = 0;
48583
- line0CharsReturned = 0;
48584
- } else if (totalLine0 > lineChunkSize) {
48585
- resultLines.push(line0Accum.slice(0, lineChunkSize));
48586
- return {
48587
- content: resultLines.join("\n"),
48588
- size: fileSize,
48589
- lineOffset: lineChunkSize,
48590
- totalLines: 1
48591
- };
48592
- } else {
48593
- resultLines.push(line0Accum);
48594
- line0Accum = "";
48595
- }
48596
- } else if (currentLine >= startLine && currentLine <= endLine) {
48597
- resultLines.push(lineContent);
48896
+ if (text[i] !== "\n") continue;
48897
+ const lineContent2 = lineContentBeforeNewline(text, lineStart, i);
48898
+ if (currentLine === 0 && trackLineZero) {
48899
+ const lineZeroResult = tryFinishLineZeroOnCompleteLine(
48900
+ lineZeroState,
48901
+ lineContent2,
48902
+ resultLines,
48903
+ fileSize,
48904
+ lineChunkSize,
48905
+ lineOffsetIn,
48906
+ endLine,
48907
+ currentLine
48908
+ );
48909
+ if (lineZeroResult === "done") {
48910
+ done = true;
48911
+ break;
48598
48912
  }
48913
+ if (lineZeroResult !== "continue") return lineZeroResult;
48599
48914
  currentLine++;
48600
48915
  lineStart = i + 1;
48601
48916
  if (currentLine > endLine) {
48602
48917
  done = true;
48603
48918
  break;
48604
48919
  }
48920
+ continue;
48605
48921
  }
48606
- }
48607
- if (!done) {
48608
- const lineContent = text.slice(lineStart);
48609
- if (currentLine === 0 && (startLine === 0 || lineOffsetIn !== void 0)) {
48610
- line0Accum += lineContent;
48611
- const totalLine0 = line0Accum.length;
48612
- if (skipLine0Chars > 0) {
48613
- if (totalLine0 <= skipLine0Chars) {
48614
- skipLine0Chars -= totalLine0;
48615
- line0Accum = "";
48616
- } else {
48617
- const from = skipLine0Chars;
48618
- const take = Math.min(lineChunkSize, totalLine0 - from);
48619
- resultLines.push(line0Accum.slice(from, from + take));
48620
- return {
48621
- content: resultLines.join("\n"),
48622
- size: fileSize,
48623
- lineOffset: (lineOffsetIn ?? 0) + take,
48624
- totalLines: 1
48625
- };
48626
- }
48627
- } else if (totalLine0 > lineChunkSize) {
48628
- resultLines.push(line0Accum.slice(0, lineChunkSize));
48629
- return {
48630
- content: resultLines.join("\n"),
48631
- size: fileSize,
48632
- lineOffset: lineChunkSize,
48633
- totalLines: 1
48634
- };
48635
- }
48922
+ if (currentLine >= startLine && currentLine <= endLine) {
48923
+ resultLines.push(lineContent2);
48924
+ }
48925
+ currentLine++;
48926
+ lineStart = i + 1;
48927
+ if (currentLine > endLine) {
48928
+ done = true;
48929
+ break;
48636
48930
  }
48637
- partial2 = text.slice(lineStart);
48931
+ }
48932
+ if (done) continue;
48933
+ const lineContent = text.slice(lineStart);
48934
+ if (currentLine === 0 && trackLineZero) {
48935
+ const partialResult = tryFinishLineZeroPartial(
48936
+ lineZeroState,
48937
+ lineContent,
48938
+ resultLines,
48939
+ fileSize,
48940
+ lineChunkSize,
48941
+ lineOffsetIn
48942
+ );
48943
+ if (partialResult != null) return partialResult;
48944
+ } else {
48945
+ partial2 = lineContent;
48638
48946
  }
48639
48947
  }
48640
48948
  if (!done) {
48641
48949
  const tail = partial2 + decoder.end();
48642
- if (currentLine === 0 && (startLine === 0 || lineOffsetIn !== void 0) && tail.length > 0) {
48643
- line0Accum += tail.endsWith("\r") ? tail.slice(0, -1) : tail;
48644
- const totalLine0 = line0Accum.length;
48645
- if (skipLine0Chars > 0) {
48646
- if (totalLine0 <= skipLine0Chars) {
48647
- return { content: resultLines.join("\n"), size: fileSize };
48648
- }
48649
- const from = skipLine0Chars;
48650
- const take = Math.min(lineChunkSize, totalLine0 - from);
48651
- resultLines.push(line0Accum.slice(from, from + take));
48652
- line0CharsReturned += take;
48653
- if (from + take < totalLine0) {
48654
- return {
48655
- content: resultLines.join("\n"),
48656
- size: fileSize,
48657
- lineOffset: (lineOffsetIn ?? 0) + line0CharsReturned,
48658
- totalLines: 1
48659
- };
48660
- }
48661
- } else if (totalLine0 > lineChunkSize) {
48662
- resultLines.push(line0Accum.slice(0, lineChunkSize));
48663
- return {
48664
- content: resultLines.join("\n"),
48665
- size: fileSize,
48666
- lineOffset: lineChunkSize,
48667
- totalLines: 1
48668
- };
48669
- } else {
48670
- resultLines.push(line0Accum);
48671
- }
48950
+ if (currentLine === 0 && trackLineZero) {
48951
+ const tailResult = finishLineZeroTail(
48952
+ lineZeroState,
48953
+ tail,
48954
+ resultLines,
48955
+ fileSize,
48956
+ lineChunkSize,
48957
+ lineOffsetIn
48958
+ );
48959
+ if (tailResult != null) return tailResult;
48672
48960
  } else if (tail.length > 0 && currentLine >= startLine && currentLine <= endLine) {
48673
48961
  resultLines.push(tail.endsWith("\r") ? tail.slice(0, -1) : tail);
48674
48962
  }
@@ -48679,12 +48967,48 @@ async function readFileRangeAsync(filePath, startLine, endLine, lineOffsetIn, li
48679
48967
  }
48680
48968
  }
48681
48969
 
48970
+ // src/files/read-file/read-small-file-range-async.ts
48971
+ import fs53 from "node:fs";
48972
+ var SMALL_FILE_RANGE_MAX_BYTES = 512 * 1024;
48973
+ function sliceLineRange(lines, startLine, endLine, lineOffsetIn, lineChunkSize, fileSize) {
48974
+ if (startLine === 0 && lineOffsetIn == null && lines[0] != null && lines[0].length > lineChunkSize) {
48975
+ return {
48976
+ content: lines[0].slice(0, lineChunkSize),
48977
+ size: fileSize,
48978
+ lineOffset: lineChunkSize,
48979
+ totalLines: lines.length
48980
+ };
48981
+ }
48982
+ if (startLine === 0 && typeof lineOffsetIn === "number") {
48983
+ const line0 = lines[0] ?? "";
48984
+ const from = lineOffsetIn;
48985
+ const take = Math.min(lineChunkSize, Math.max(0, line0.length - from));
48986
+ return {
48987
+ content: line0.slice(from, from + take),
48988
+ size: fileSize,
48989
+ ...from + take < line0.length ? { lineOffset: from + take, totalLines: lines.length } : { totalLines: lines.length }
48990
+ };
48991
+ }
48992
+ const slice = lines.slice(startLine, endLine + 1);
48993
+ return {
48994
+ content: slice.join("\n"),
48995
+ size: fileSize,
48996
+ totalLines: lines.length
48997
+ };
48998
+ }
48999
+ async function readSmallFileRangeAsync(filePath, fileSize, startLine, endLine, lineOffsetIn, lineChunkSize = LINE_CHUNK_SIZE) {
49000
+ const raw = await fs53.promises.readFile(filePath, "utf8");
49001
+ const lines = raw.split(/\r?\n/);
49002
+ return sliceLineRange(lines, startLine, endLine, lineOffsetIn, lineChunkSize, fileSize);
49003
+ }
49004
+
48682
49005
  // src/files/read-file/read-file-buffer-full-async.ts
48683
- import fs52 from "node:fs";
49006
+ init_yield_to_event_loop();
49007
+ import fs54 from "node:fs";
48684
49008
  var READ_CHUNK_BYTES = 256 * 1024;
48685
49009
  async function readFileBufferFullAsync(filePath) {
48686
- const stat3 = await fs52.promises.stat(filePath);
48687
- const fd = await fs52.promises.open(filePath, "r");
49010
+ const stat3 = await fs54.promises.stat(filePath);
49011
+ const fd = await fs54.promises.open(filePath, "r");
48688
49012
  const chunks = [];
48689
49013
  let position = 0;
48690
49014
  let bytesSinceYield = 0;
@@ -48726,12 +49050,23 @@ async function readFileBinaryFullAsync(filePath) {
48726
49050
  }
48727
49051
 
48728
49052
  // src/files/read-file/index.ts
48729
- async function readFileAsync(relativePath, startLine, endLine, lineOffset, lineChunkSize = LINE_CHUNK_SIZE, sessionParentPath = getBridgeRoot(), encoding = "utf8") {
48730
- await yieldToEventLoop();
49053
+ async function readFileAsync(relativePath, startLine, endLine, lineOffset, lineChunkSize = LINE_CHUNK_SIZE, sessionParentPath = getBridgeRoot(), encoding = "utf8", options) {
49054
+ if (!options?.skipInitialYield) {
49055
+ await yieldToEventLoop();
49056
+ }
48731
49057
  try {
48732
- const result = await resolveFilePathAsync(relativePath, sessionParentPath);
48733
- if (typeof result === "object") return result;
48734
- const resolvedPath = result;
49058
+ let resolvedPath;
49059
+ let fileSize;
49060
+ if (options?.useResolvedSize) {
49061
+ const resolved = await resolveFileForReadAsync(relativePath, sessionParentPath);
49062
+ if ("error" in resolved) return resolved;
49063
+ resolvedPath = resolved.path;
49064
+ fileSize = resolved.size;
49065
+ } else {
49066
+ const result = await resolveFilePathAsync(relativePath, sessionParentPath);
49067
+ if (typeof result === "object") return result;
49068
+ resolvedPath = result;
49069
+ }
48735
49070
  const hasRange = typeof startLine === "number" && typeof endLine === "number";
48736
49071
  if (encoding === "base64") {
48737
49072
  if (hasRange) return { error: "base64 encoding requires a full file read (no line range)" };
@@ -48739,7 +49074,26 @@ async function readFileAsync(relativePath, startLine, endLine, lineOffset, lineC
48739
49074
  return { ...read2, resolvedPath };
48740
49075
  }
48741
49076
  if (hasRange) {
48742
- return readFileRangeAsync(resolvedPath, startLine, endLine, lineOffset, lineChunkSize);
49077
+ if (fileSize == null) {
49078
+ const stat3 = await fs55.promises.stat(resolvedPath);
49079
+ fileSize = stat3.size;
49080
+ }
49081
+ const read2 = fileSize <= SMALL_FILE_RANGE_MAX_BYTES ? await readSmallFileRangeAsync(
49082
+ resolvedPath,
49083
+ fileSize,
49084
+ startLine,
49085
+ endLine,
49086
+ lineOffset,
49087
+ lineChunkSize
49088
+ ) : await readFileRangeAsync(
49089
+ resolvedPath,
49090
+ startLine,
49091
+ endLine,
49092
+ lineOffset,
49093
+ lineChunkSize,
49094
+ fileSize
49095
+ );
49096
+ return read2;
48743
49097
  }
48744
49098
  const read = await readFileFullAsync(resolvedPath);
48745
49099
  return { ...read, resolvedPath };
@@ -48748,6 +49102,17 @@ async function readFileAsync(relativePath, startLine, endLine, lineOffset, lineC
48748
49102
  }
48749
49103
  }
48750
49104
 
49105
+ // src/files/browser/file-browser-read-queue.ts
49106
+ var readChain = Promise.resolve();
49107
+ function withFileBrowserReadQueue(fn) {
49108
+ const next = readChain.then(() => fn());
49109
+ readChain = next.then(
49110
+ () => void 0,
49111
+ () => void 0
49112
+ );
49113
+ return next;
49114
+ }
49115
+
48751
49116
  // src/files/browser/handle-file-browser-read.ts
48752
49117
  async function handleFileBrowserRead(socket, e2ee, msg, reqPath, sessionParentPath, gitScope) {
48753
49118
  const startLine = typeof msg.startLine === "number" ? msg.startLine : void 0;
@@ -48764,14 +49129,17 @@ async function handleFileBrowserRead(socket, e2ee, msg, reqPath, sessionParentPa
48764
49129
  lineOffset,
48765
49130
  lineChunkSize,
48766
49131
  encoding
48767
- ) : await readFileAsync(
48768
- reqPath,
48769
- startLine,
48770
- endLine,
48771
- lineOffset,
48772
- lineChunkSize,
48773
- sessionParentPath,
48774
- encoding
49132
+ ) : await withFileBrowserReadQueue(
49133
+ () => readFileAsync(
49134
+ reqPath,
49135
+ startLine,
49136
+ endLine,
49137
+ lineOffset,
49138
+ lineChunkSize,
49139
+ sessionParentPath,
49140
+ encoding,
49141
+ { skipInitialYield: true, useResolvedSize: true }
49142
+ )
48775
49143
  );
48776
49144
  if ("error" in result) {
48777
49145
  sendWsMessage(socket, { type: "file_browser_response", id: msg.id, error: result.error });
@@ -48788,6 +49156,10 @@ async function handleFileBrowserRead(socket, e2ee, msg, reqPath, sessionParentPa
48788
49156
  if (result.mimeType != null) payload.mimeType = result.mimeType;
48789
49157
  if (result.resolvedPath != null) payload.resolvedPath = result.resolvedPath;
48790
49158
  sendFileBrowserMessage(socket, e2ee, payload);
49159
+ if (!gitScope) {
49160
+ const parentDir = path79.dirname(reqPath.replace(/^\/+/, "") || ".");
49161
+ scheduleDirectoryResolveCacheWarmup(sessionParentPath ?? getBridgeRoot(), parentDir === "" ? "." : parentDir);
49162
+ }
48791
49163
  }
48792
49164
 
48793
49165
  // src/files/browser/resolve-git-branch-scope.ts
@@ -48801,22 +49173,67 @@ function resolveGitBranchScope(msg) {
48801
49173
 
48802
49174
  // src/files/browser/index.ts
48803
49175
  function handleFileBrowserRequest(msg, socket, e2ee, sessionWorktreeManager) {
49176
+ beginFileBrowserRequest();
48804
49177
  void (async () => {
48805
- const reqPath = msg.path.replace(/^\/+/, "") || ".";
48806
- const op = msg.op === "read" ? "read" : "list";
48807
- const sessionParentPath = sessionWorktreeManager != null ? await resolveFileBrowserSessionParent(sessionWorktreeManager, msg.sessionId) : void 0;
48808
- const gitScope = resolveGitBranchScope(msg);
48809
- if (msg.source === "git_branch" && typeof msg.repoRelPath === "string" && typeof msg.branch === "string" && msg.branch.trim().length > 0 && !gitScope) {
48810
- sendWsMessage(socket, { type: "file_browser_response", id: msg.id, error: "Invalid repository path" });
48811
- return;
49178
+ try {
49179
+ const reqPath = msg.path.replace(/^\/+/, "") || ".";
49180
+ const sessionParentPath = sessionWorktreeManager != null ? await resolveFileBrowserSessionParent(sessionWorktreeManager, msg.sessionId) : void 0;
49181
+ const gitScope = resolveGitBranchScope(msg);
49182
+ if (msg.source === "git_branch" && typeof msg.repoRelPath === "string" && typeof msg.branch === "string" && msg.branch.trim().length > 0 && !gitScope) {
49183
+ sendWsMessage(socket, { type: "file_browser_response", id: msg.id, error: "Invalid repository path" });
49184
+ return;
49185
+ }
49186
+ if (msg.op === "read") {
49187
+ await handleFileBrowserRead(socket, e2ee, msg, reqPath, sessionParentPath, gitScope);
49188
+ } else {
49189
+ await handleFileBrowserList(socket, e2ee, msg.id, reqPath, sessionParentPath, gitScope);
49190
+ }
49191
+ } finally {
49192
+ endFileBrowserRequest();
48812
49193
  }
48813
- if (op === "list") {
48814
- await handleFileBrowserList(socket, e2ee, msg.id, reqPath, sessionParentPath, gitScope);
48815
- } else {
48816
- await handleFileBrowserRead(socket, e2ee, msg, reqPath, sessionParentPath, gitScope);
49194
+ })();
49195
+ }
49196
+
49197
+ // src/files/handle-file-browser-search.ts
49198
+ init_cwd();
49199
+ init_yield_to_event_loop();
49200
+ import path80 from "node:path";
49201
+ var SEARCH_LIMIT = 100;
49202
+ function handleFileBrowserSearch(msg, socket, e2ee, sessionWorktreeManager) {
49203
+ void (async () => {
49204
+ await yieldToEventLoop();
49205
+ const q = typeof msg.q === "string" ? msg.q : "";
49206
+ const sessionParentPath = path80.resolve(
49207
+ sessionWorktreeManager != null ? await resolveFileBrowserSessionParent(sessionWorktreeManager, msg.sessionId) : getBridgeRoot()
49208
+ );
49209
+ if (!await bridgeFileIndexIsPopulated(sessionParentPath)) {
49210
+ triggerFileIndexBuild(sessionParentPath);
49211
+ const payload2 = {
49212
+ type: "file_browser_search_response",
49213
+ id: msg.id,
49214
+ paths: [],
49215
+ indexReady: false
49216
+ };
49217
+ sendWsMessage(socket, e2ee ? e2ee.encryptFields(payload2, ["paths"]) : payload2);
49218
+ return;
48817
49219
  }
49220
+ const results = await searchBridgeFilePathsAsync(sessionParentPath, q, SEARCH_LIMIT);
49221
+ const payload = {
49222
+ type: "file_browser_search_response",
49223
+ id: msg.id,
49224
+ paths: results,
49225
+ indexReady: true
49226
+ };
49227
+ sendWsMessage(socket, e2ee ? e2ee.encryptFields(payload, ["paths"]) : payload);
48818
49228
  })();
48819
49229
  }
49230
+ function triggerFileIndexBuild(sessionParentPath = getBridgeRoot()) {
49231
+ setImmediate(() => {
49232
+ void ensureFileIndexAsync(sessionParentPath).catch((e) => {
49233
+ console.error("[file-index] Background build failed:", e);
49234
+ });
49235
+ });
49236
+ }
48820
49237
 
48821
49238
  // src/routing/handlers/file-browser-messages.ts
48822
49239
  function handleFileBrowserRequestMessage(msg, { getWs, e2ee, sessionWorktreeManager }) {
@@ -48837,6 +49254,235 @@ function handleFileBrowserSearchMessage(msg, { getWs, e2ee, sessionWorktreeManag
48837
49254
  );
48838
49255
  }
48839
49256
 
49257
+ // src/code-nav/handlers/send-code-nav-response.ts
49258
+ var ENCRYPTED_FIELDS = ["definition", "definitions", "references", "symbols", "confidentTarget"];
49259
+ function sendCodeNavResponse(socket, e2ee, payload) {
49260
+ const fieldsToEncrypt = ENCRYPTED_FIELDS.filter((field) => field in payload && payload[field] !== void 0);
49261
+ sendWsMessage(
49262
+ socket,
49263
+ e2ee && fieldsToEncrypt.length > 0 ? e2ee.encryptFields(payload, [...fieldsToEncrypt]) : payload
49264
+ );
49265
+ }
49266
+
49267
+ // src/code-nav/handlers/handle-definition-op.ts
49268
+ async function handleDefinitionOp(ctx) {
49269
+ const definition = await queryDefinitionAt(ctx.sessionParentPath, ctx.reqPath, ctx.line, ctx.column);
49270
+ sendCodeNavResponse(ctx.socket, ctx.e2ee, {
49271
+ type: "code_nav_response",
49272
+ id: ctx.msg.id,
49273
+ indexReady: true,
49274
+ definition
49275
+ });
49276
+ }
49277
+
49278
+ // src/code-nav/handlers/handle-definitions-op.ts
49279
+ async function handleDefinitionsOp(ctx) {
49280
+ const { definitions, confidentTarget } = await queryDefinitionsNavigation(
49281
+ ctx.sessionParentPath,
49282
+ ctx.reqPath,
49283
+ ctx.line,
49284
+ ctx.column
49285
+ );
49286
+ sendCodeNavResponse(ctx.socket, ctx.e2ee, {
49287
+ type: "code_nav_response",
49288
+ id: ctx.msg.id,
49289
+ indexReady: true,
49290
+ definitions,
49291
+ confidentTarget
49292
+ });
49293
+ }
49294
+
49295
+ // src/code-nav/handlers/handle-references-op.ts
49296
+ async function handleReferencesOp(ctx) {
49297
+ const references = await queryReferencesAt(ctx.sessionParentPath, ctx.reqPath, ctx.line, ctx.column);
49298
+ sendCodeNavResponse(ctx.socket, ctx.e2ee, {
49299
+ type: "code_nav_response",
49300
+ id: ctx.msg.id,
49301
+ indexReady: true,
49302
+ references
49303
+ });
49304
+ }
49305
+
49306
+ // src/code-nav/handlers/handle-symbols-op.ts
49307
+ async function handleSymbolsOp(ctx) {
49308
+ const symbols = await querySymbolsInFile(ctx.sessionParentPath, ctx.reqPath);
49309
+ sendCodeNavResponse(ctx.socket, ctx.e2ee, {
49310
+ type: "code_nav_response",
49311
+ id: ctx.msg.id,
49312
+ indexReady: true,
49313
+ symbols
49314
+ });
49315
+ }
49316
+
49317
+ // src/code-nav/handlers/prepare-code-nav-request.ts
49318
+ init_yield_to_event_loop();
49319
+
49320
+ // src/code-nav/handlers/deferred-code-nav-index.ts
49321
+ var latestSeqBySession = /* @__PURE__ */ new Map();
49322
+ var pendingBySession = /* @__PURE__ */ new Map();
49323
+ var flushPromise = null;
49324
+ function scheduleDeferredCodeNavIndex(sessionKey, sessionParentPath, reqPath) {
49325
+ const seq = (latestSeqBySession.get(sessionKey) ?? 0) + 1;
49326
+ latestSeqBySession.set(sessionKey, seq);
49327
+ pendingBySession.set(sessionKey, { sessionParentPath, reqPath, seq });
49328
+ scheduleFlushWhenIdle();
49329
+ }
49330
+ function scheduleFlushWhenIdle() {
49331
+ if (flushPromise != null) return;
49332
+ flushPromise = runFlushWhenIdle().finally(() => {
49333
+ flushPromise = null;
49334
+ if (pendingBySession.size > 0) scheduleFlushWhenIdle();
49335
+ });
49336
+ }
49337
+ async function runFlushWhenIdle() {
49338
+ await yieldUntilFileBrowserIdle();
49339
+ const entries = [];
49340
+ for (const [sessionKey, entry] of pendingBySession) {
49341
+ pendingBySession.delete(sessionKey);
49342
+ if (entry.seq === latestSeqBySession.get(sessionKey)) entries.push(entry);
49343
+ }
49344
+ for (const entry of entries) {
49345
+ scheduleSymbolIndexFile(entry.sessionParentPath, entry.reqPath);
49346
+ }
49347
+ }
49348
+ registerFileBrowserActivityListener(() => {
49349
+ if (pendingBySession.size > 0 && !isBridgeBrowseInteractiveActive()) {
49350
+ scheduleFlushWhenIdle();
49351
+ }
49352
+ });
49353
+
49354
+ // src/code-nav/handlers/code-nav-session-key.ts
49355
+ function codeNavSessionKey(sessionId, sessionParentPath) {
49356
+ const trimmed2 = sessionId?.trim();
49357
+ return trimmed2 ? trimmed2 : sessionParentPath;
49358
+ }
49359
+
49360
+ // src/code-nav/handlers/wait-for-symbol-index-ready.ts
49361
+ var CODE_NAV_INDEX_READY_WAIT_MS = 75;
49362
+ var CODE_NAV_INDEX_READY_POLL_MS = 15;
49363
+ function delay2(ms) {
49364
+ return new Promise((resolve37) => setTimeout(resolve37, ms));
49365
+ }
49366
+ async function waitForSymbolIndexReady(sessionParentPath, reqPath, maxWaitMs = CODE_NAV_INDEX_READY_WAIT_MS) {
49367
+ const deadline = Date.now() + maxWaitMs;
49368
+ do {
49369
+ if (await symbolIndexFileIsReadyAsync(sessionParentPath, reqPath)) return true;
49370
+ await delay2(CODE_NAV_INDEX_READY_POLL_MS);
49371
+ } while (Date.now() < deadline);
49372
+ return await symbolIndexFileIsReadyAsync(sessionParentPath, reqPath);
49373
+ }
49374
+
49375
+ // src/code-nav/handlers/prepare-code-nav-base-context.ts
49376
+ function buildPreparedCodeNavBaseContext(msg, socket, e2ee, reqPath, sessionParentPath) {
49377
+ return {
49378
+ socket,
49379
+ e2ee,
49380
+ msg,
49381
+ reqPath,
49382
+ sessionParentPath,
49383
+ line: typeof msg.line === "number" ? msg.line : 1,
49384
+ column: typeof msg.column === "number" ? msg.column : 0
49385
+ };
49386
+ }
49387
+
49388
+ // src/code-nav/handlers/code-nav-op-context.ts
49389
+ function normalizeCodeNavOp(op) {
49390
+ if (op === "references" || op === "symbols" || op === "definitions") return op;
49391
+ return "definition";
49392
+ }
49393
+
49394
+ // src/code-nav/handlers/resolve-code-nav-parent.ts
49395
+ init_cwd();
49396
+ init_normalize_resolved_path();
49397
+ async function resolveCodeNavParentPath(sessionWorktreeManager, sessionId) {
49398
+ const parent = sessionWorktreeManager != null ? await resolveFileBrowserSessionParent(sessionWorktreeManager, sessionId) : getBridgeRoot();
49399
+ return normalizeResolvedPath(parent);
49400
+ }
49401
+
49402
+ // src/code-nav/handlers/prepare-code-nav-request.ts
49403
+ async function prepareCodeNavRequest(msg, socket, e2ee, sessionWorktreeManager) {
49404
+ await yieldToEventLoop();
49405
+ const reqPath = msg.path.replace(/^\/+/, "") || "";
49406
+ if (!reqPath) {
49407
+ sendCodeNavResponse(socket, e2ee, {
49408
+ type: "code_nav_response",
49409
+ id: msg.id,
49410
+ error: "Path required"
49411
+ });
49412
+ return null;
49413
+ }
49414
+ const sessionParentPath = await resolveCodeNavParentPath(sessionWorktreeManager, msg.sessionId);
49415
+ await registerSymbolIndexParentAsync(sessionParentPath);
49416
+ const sessionKey = codeNavSessionKey(msg.sessionId, sessionParentPath);
49417
+ const baseContext = buildPreparedCodeNavBaseContext(msg, socket, e2ee, reqPath, sessionParentPath);
49418
+ if (isBridgeBrowseInteractiveActive()) {
49419
+ scheduleDeferredCodeNavIndex(sessionKey, sessionParentPath, reqPath);
49420
+ return { ...baseContext, indexReady: false };
49421
+ }
49422
+ scheduleSymbolIndexFile(sessionParentPath, reqPath);
49423
+ const indexReady = await waitForSymbolIndexReady(sessionParentPath, reqPath);
49424
+ if (indexReady) {
49425
+ const importTargets = await listDirectImportTargetsForFileAsync(sessionParentPath, reqPath);
49426
+ scheduleSymbolIndexImportNeighbors(sessionParentPath, importTargets);
49427
+ }
49428
+ await yieldToEventLoop();
49429
+ return {
49430
+ ...baseContext,
49431
+ indexReady
49432
+ };
49433
+ }
49434
+ function sendIndexNotReadyResponse(ctx) {
49435
+ sendCodeNavResponse(ctx.socket, ctx.e2ee, {
49436
+ type: "code_nav_response",
49437
+ id: ctx.msg.id,
49438
+ indexReady: false,
49439
+ definition: null,
49440
+ definitions: [],
49441
+ references: [],
49442
+ symbols: []
49443
+ });
49444
+ }
49445
+ function preparedOpContext(ctx) {
49446
+ return {
49447
+ socket: ctx.socket,
49448
+ e2ee: ctx.e2ee,
49449
+ msg: { ...ctx.msg, op: normalizeCodeNavOp(ctx.msg.op) },
49450
+ reqPath: ctx.reqPath,
49451
+ sessionParentPath: ctx.sessionParentPath,
49452
+ line: ctx.line,
49453
+ column: ctx.column
49454
+ };
49455
+ }
49456
+
49457
+ // src/code-nav/handlers/handle-code-nav-request.ts
49458
+ function handleCodeNavRequest(msg, socket, e2ee, sessionWorktreeManager) {
49459
+ void (async () => {
49460
+ const prepared = await prepareCodeNavRequest(msg, socket, e2ee, sessionWorktreeManager);
49461
+ if (prepared == null) return;
49462
+ if (!prepared.indexReady) {
49463
+ sendIndexNotReadyResponse(prepared);
49464
+ return;
49465
+ }
49466
+ const ctx = preparedOpContext(prepared);
49467
+ switch (ctx.msg.op) {
49468
+ case "symbols":
49469
+ await handleSymbolsOp(ctx);
49470
+ return;
49471
+ case "references":
49472
+ await handleReferencesOp(ctx);
49473
+ return;
49474
+ case "definitions":
49475
+ await handleDefinitionsOp(ctx);
49476
+ return;
49477
+ default:
49478
+ await handleDefinitionOp(ctx);
49479
+ }
49480
+ })();
49481
+ }
49482
+
49483
+ // src/code-nav/handlers/trigger-symbol-index-build.ts
49484
+ init_normalize_resolved_path();
49485
+
48840
49486
  // src/routing/handlers/code-nav-messages.ts
48841
49487
  function handleFileBrowserCodeNavMessage(msg, { getWs, e2ee, sessionWorktreeManager }) {
48842
49488
  if (typeof msg.id !== "string" || typeof msg.path !== "string") return;
@@ -48859,6 +49505,7 @@ function handleFileBrowserCodeNavMessage(msg, { getWs, e2ee, sessionWorktreeMana
48859
49505
  }
48860
49506
 
48861
49507
  // src/routing/handlers/skill-layout-request.ts
49508
+ init_cwd();
48862
49509
  function handleSkillLayoutRequest(msg, deps) {
48863
49510
  const id = typeof msg.id === "string" ? msg.id : "";
48864
49511
  void (async () => {
@@ -48870,6 +49517,9 @@ function handleSkillLayoutRequest(msg, deps) {
48870
49517
  })();
48871
49518
  }
48872
49519
 
49520
+ // src/routing/handlers/install-skills.ts
49521
+ init_cwd();
49522
+
48873
49523
  // src/skills/install/is-valid-install-item.ts
48874
49524
  function isValidRemoteSkillInstallItem(item) {
48875
49525
  if (item === null || typeof item !== "object") return false;
@@ -48878,8 +49528,9 @@ function isValidRemoteSkillInstallItem(item) {
48878
49528
  }
48879
49529
 
48880
49530
  // src/skills/install/install-remote-skills-async.ts
48881
- import fs53 from "node:fs";
48882
- import path78 from "node:path";
49531
+ init_yield_to_event_loop();
49532
+ import fs56 from "node:fs";
49533
+ import path81 from "node:path";
48883
49534
 
48884
49535
  // src/skills/install/constants.ts
48885
49536
  var INSTALL_SKILLS_YIELD_EVERY = 16;
@@ -48890,12 +49541,12 @@ async function writeInstallFileAsync(skillDir, f, filesWritten) {
48890
49541
  if (++filesWritten.count % INSTALL_SKILLS_YIELD_EVERY === 0) {
48891
49542
  await yieldToEventLoop();
48892
49543
  }
48893
- const dest = path78.join(skillDir, f.path);
48894
- await fs53.promises.mkdir(path78.dirname(dest), { recursive: true });
49544
+ const dest = path81.join(skillDir, f.path);
49545
+ await fs56.promises.mkdir(path81.dirname(dest), { recursive: true });
48895
49546
  if (f.text !== void 0) {
48896
- await fs53.promises.writeFile(dest, f.text, "utf8");
49547
+ await fs56.promises.writeFile(dest, f.text, "utf8");
48897
49548
  } else if (f.base64) {
48898
- await fs53.promises.writeFile(dest, Buffer.from(f.base64, "base64"));
49549
+ await fs56.promises.writeFile(dest, Buffer.from(f.base64, "base64"));
48899
49550
  }
48900
49551
  }
48901
49552
  async function installRemoteSkillsAsync(cwd, targetDir, items) {
@@ -48907,7 +49558,7 @@ async function installRemoteSkillsAsync(cwd, targetDir, items) {
48907
49558
  try {
48908
49559
  for (const item of items) {
48909
49560
  if (!isValidRemoteSkillInstallItem(item)) continue;
48910
- const skillDir = path78.join(cwd, targetDir, item.skillName);
49561
+ const skillDir = path81.join(cwd, targetDir, item.skillName);
48911
49562
  for (const f of item.files) {
48912
49563
  await writeInstallFileAsync(skillDir, f, filesWritten);
48913
49564
  }
@@ -49189,7 +49840,8 @@ var handleSessionDiscardedMessage = (msg, deps) => {
49189
49840
  };
49190
49841
 
49191
49842
  // src/routing/handlers/revert-turn-snapshot.ts
49192
- import * as fs54 from "node:fs";
49843
+ init_cwd();
49844
+ import * as fs57 from "node:fs";
49193
49845
  var handleRevertTurnSnapshotMessage = (msg, deps) => {
49194
49846
  const id = typeof msg.id === "string" ? msg.id : "";
49195
49847
  const sessionId = typeof msg.sessionId === "string" ? msg.sessionId : "";
@@ -49202,7 +49854,7 @@ var handleRevertTurnSnapshotMessage = (msg, deps) => {
49202
49854
  const agentBase = sessionWorktreeManager.getSessionWorktreeRootForSession(sessionId) ?? getBridgeRoot();
49203
49855
  const file2 = snapshotFilePath(agentBase, turnId);
49204
49856
  try {
49205
- await fs54.promises.access(file2, fs54.constants.F_OK);
49857
+ await fs57.promises.access(file2, fs57.constants.F_OK);
49206
49858
  } catch {
49207
49859
  sendWsMessage(s, {
49208
49860
  type: "revert_turn_snapshot_result",
@@ -49287,7 +49939,9 @@ var handleDeploySessionToPreviewMessage = (msg, deps) => {
49287
49939
  };
49288
49940
 
49289
49941
  // src/git/bridge-git-context.ts
49290
- import * as path79 from "node:path";
49942
+ init_cwd();
49943
+ init_yield_to_event_loop();
49944
+ import * as path82 from "node:path";
49291
49945
 
49292
49946
  // src/git/branches/get-current-branch.ts
49293
49947
  async function getCurrentBranch(repoPath) {
@@ -49337,12 +49991,12 @@ async function listRepoBranchRefs(repoPath) {
49337
49991
  // src/git/bridge-git-context.ts
49338
49992
  function folderNameForRelPath(relPath, bridgeRoot) {
49339
49993
  if (relPath === "." || relPath === "") {
49340
- return path79.basename(path79.resolve(bridgeRoot)) || "repo";
49994
+ return path82.basename(path82.resolve(bridgeRoot)) || "repo";
49341
49995
  }
49342
- return path79.basename(relPath) || relPath;
49996
+ return path82.basename(relPath) || relPath;
49343
49997
  }
49344
49998
  async function discoverGitReposForBridgeContext(bridgeRoot) {
49345
- const root = path79.resolve(bridgeRoot);
49999
+ const root = path82.resolve(bridgeRoot);
49346
50000
  if (await isGitRepoDirectory(root)) {
49347
50001
  const remoteUrl = await getRemoteOriginUrl(root);
49348
50002
  return [{ absolutePath: root, remoteUrl }];
@@ -49350,19 +50004,19 @@ async function discoverGitReposForBridgeContext(bridgeRoot) {
49350
50004
  const [deep, shallow] = await Promise.all([discoverGitReposUnderRoot(root), discoverGitRepos(root)]);
49351
50005
  const byPath = /* @__PURE__ */ new Map();
49352
50006
  for (const repo of [...deep, ...shallow]) {
49353
- byPath.set(path79.resolve(repo.absolutePath), repo);
50007
+ byPath.set(path82.resolve(repo.absolutePath), repo);
49354
50008
  }
49355
50009
  return [...byPath.values()];
49356
50010
  }
49357
50011
  async function getBridgeGitContext(bridgeRoot = getBridgeRoot()) {
49358
- const bridgeResolved = path79.resolve(bridgeRoot);
50012
+ const bridgeResolved = path82.resolve(bridgeRoot);
49359
50013
  const repos = await discoverGitReposForBridgeContext(bridgeResolved);
49360
50014
  const rows = [];
49361
50015
  for (let i = 0; i < repos.length; i++) {
49362
50016
  if (i > 0) await yieldToEventLoop();
49363
50017
  const repo = repos[i];
49364
- let rel = path79.relative(bridgeResolved, repo.absolutePath);
49365
- if (rel.startsWith("..") || path79.isAbsolute(rel)) continue;
50018
+ let rel = path82.relative(bridgeResolved, repo.absolutePath);
50019
+ if (rel.startsWith("..") || path82.isAbsolute(rel)) continue;
49366
50020
  const relPath = rel === "" ? "." : rel.replace(/\\/g, "/");
49367
50021
  const currentBranch = await getCurrentBranch(repo.absolutePath);
49368
50022
  const remoteUrl = repo.remoteUrl.trim() || null;
@@ -49377,11 +50031,11 @@ async function getBridgeGitContext(bridgeRoot = getBridgeRoot()) {
49377
50031
  return rows;
49378
50032
  }
49379
50033
  async function listRepoBranchesForBridge(repoRelPath, bridgeRoot = getBridgeRoot()) {
49380
- const bridgeResolved = path79.resolve(bridgeRoot);
50034
+ const bridgeResolved = path82.resolve(bridgeRoot);
49381
50035
  const rel = repoRelPath.trim() === "." ? "" : repoRelPath.trim().replace(/\\/g, "/");
49382
- const repoPath = rel === "" ? bridgeResolved : path79.join(bridgeResolved, rel);
49383
- const resolved = path79.resolve(repoPath);
49384
- if (!resolved.startsWith(bridgeResolved + path79.sep) && resolved !== bridgeResolved) {
50036
+ const repoPath = rel === "" ? bridgeResolved : path82.join(bridgeResolved, rel);
50037
+ const resolved = path82.resolve(repoPath);
50038
+ if (!resolved.startsWith(bridgeResolved + path82.sep) && resolved !== bridgeResolved) {
49385
50039
  return [];
49386
50040
  }
49387
50041
  return listRepoBranchRefs(resolved);
@@ -50057,9 +50711,9 @@ async function runCliAction(program2, opts) {
50057
50711
  const firehoseServerUrl = opts.firehoseUrl ?? opts.proxyUrl ?? process.env.BUILDAUTOMATON_FIREHOSE_URL ?? process.env.BUILDAUTOMATON_PROXY_URL ?? DEFAULT_FIREHOSE_URL;
50058
50712
  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);
50059
50713
  if (bridgeRootOpt) {
50060
- const resolvedBridgeRoot = path80.resolve(process.cwd(), bridgeRootOpt);
50714
+ const resolvedBridgeRoot = path83.resolve(process.cwd(), bridgeRootOpt);
50061
50715
  try {
50062
- const st = fs55.statSync(resolvedBridgeRoot);
50716
+ const st = fs58.statSync(resolvedBridgeRoot);
50063
50717
  if (!st.isDirectory()) {
50064
50718
  console.error(`Bridge root is not a directory: ${resolvedBridgeRoot}`);
50065
50719
  process.exit(1);
@@ -50079,7 +50733,7 @@ async function runCliAction(program2, opts) {
50079
50733
  );
50080
50734
  let worktreesRootPath;
50081
50735
  if (opts.worktreesRoot && opts.worktreesRoot.trim()) {
50082
- worktreesRootPath = path80.resolve(opts.worktreesRoot.trim());
50736
+ worktreesRootPath = path83.resolve(opts.worktreesRoot.trim());
50083
50737
  }
50084
50738
  const e2eCertificates = opts.e2eeCertificatesDir?.trim() ? await loadOrCreateE2eCertificates(opts.e2eeCertificatesDir.trim()) : void 0;
50085
50739
  if (e2eCertificates) {