@buildautomaton/cli 0.1.62 → 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.62".length > 0 ? "0.1.62" : "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 {
@@ -31955,7 +32288,6 @@ var StoryCheckpointSummarySchema = CheckpointSummarySchema.extend({
31955
32288
 
31956
32289
  // ../types/src/sessions.ts
31957
32290
  init_zod();
31958
- var BUILTIN_SESSION_CHANGE_SUMMARY_FOLLOW_UP_CATALOG_PROMPT_ID = "__builtin_change_summary__";
31959
32291
  var SessionMetaSchema = external_exports.object({
31960
32292
  sessionId: external_exports.string(),
31961
32293
  workspaceId: external_exports.string(),
@@ -32088,146 +32420,6 @@ function buildPlanningSessionFollowUpAgentPrompt(userPrompt, existingTodos) {
32088
32420
  ].join("\n");
32089
32421
  }
32090
32422
 
32091
- // ../types/src/change-summary-path.ts
32092
- function normalizeRepoRelativePath(p) {
32093
- let t = p.trim().replace(/\\/g, "/");
32094
- while (t.startsWith("./")) t = t.slice(2);
32095
- return t.replace(/\/+/g, "/");
32096
- }
32097
- function resolveChangeSummaryPathAgainstAllowed(rawPath, allowed) {
32098
- const trimmed2 = rawPath.trim();
32099
- if (!trimmed2) return null;
32100
- if (allowed.has(trimmed2)) return trimmed2;
32101
- const n = normalizeRepoRelativePath(trimmed2);
32102
- if (allowed.has(n)) return n;
32103
- for (const a of allowed) {
32104
- if (normalizeRepoRelativePath(a) === n) return a;
32105
- }
32106
- return null;
32107
- }
32108
-
32109
- // ../types/src/parse-change-summary-json.ts
32110
- function clampSummaryToAtMostTwoLines(summary) {
32111
- const lines = summary.split(/\r?\n/).map((l) => l.trim()).filter((l) => l.length > 0);
32112
- return lines.slice(0, 2).join("\n");
32113
- }
32114
- function parseChangeSummaryJson(raw, allowedPaths, options) {
32115
- if (raw == null || raw.trim() === "") return [];
32116
- let text = raw.trim();
32117
- const fence = text.match(/```(?:json)?\s*([\s\S]*?)```/i);
32118
- if (fence?.[1]) text = fence[1].trim();
32119
- let parsed;
32120
- try {
32121
- parsed = JSON.parse(text);
32122
- } catch {
32123
- const start = text.indexOf("[");
32124
- const end = text.lastIndexOf("]");
32125
- if (start < 0 || end <= start) return [];
32126
- try {
32127
- parsed = JSON.parse(text.slice(start, end + 1));
32128
- } catch {
32129
- return [];
32130
- }
32131
- }
32132
- const rows = [];
32133
- let arr = [];
32134
- if (Array.isArray(parsed)) {
32135
- arr = parsed;
32136
- } else if (parsed && typeof parsed === "object" && Array.isArray(parsed.files)) {
32137
- arr = parsed.files;
32138
- }
32139
- const skip = options?.skipPathAllowlist === true;
32140
- for (const item of arr) {
32141
- if (!item || typeof item !== "object") continue;
32142
- const o = item;
32143
- const rawPath = typeof o.path === "string" ? o.path.trim() : "";
32144
- const summary = typeof o.summary === "string" ? o.summary.trim() : "";
32145
- if (!rawPath || !summary) continue;
32146
- const path81 = skip ? normalizeRepoRelativePath(rawPath) || rawPath : resolveChangeSummaryPathAgainstAllowed(rawPath, allowedPaths);
32147
- if (!path81) continue;
32148
- rows.push({ path: path81, summary: clampSummaryToAtMostTwoLines(summary) });
32149
- }
32150
- return rows;
32151
- }
32152
-
32153
- // ../types/src/build-change-summary-prompt.ts
32154
- var PATCH_PREVIEW_MAX = 12e3;
32155
- function clip(s, max) {
32156
- if (s.length <= max) return s;
32157
- return `${s.slice(0, max)}
32158
-
32159
- \u2026(truncated, ${s.length - max} more characters)`;
32160
- }
32161
- function buildSessionChangeSummaryPrompt(files) {
32162
- const lines = [
32163
- "You are the same agent that produced the changes below. Summarize **your own** edits so a reader can scan them quickly.",
32164
- "",
32165
- "Write in second person (you / your): what you changed in each path and why it matters.",
32166
- "",
32167
- "Each summary must be **very concise**: **one line** of plain text, or **at most two short lines** (use a single line break between the two if needed). No bullets, no paragraphs.",
32168
- "",
32169
- "## How to format your reply (machine parsing)",
32170
- "",
32171
- "- Put the machine-readable part **only** inside a **markdown fenced code block** whose opening fence is exactly ```json on its own line. Close the block with ``` on its own line after the JSON.",
32172
- "- Inside that fence: **nothing except** one valid JSON value \u2014 the array described below. No trailing commentary inside the fence.",
32173
- "- **Do not** attach prose to the JSON on the same line (wrong: `Only one file\u2026page.tsx.[{\u2026}]`). Wrong: any sentence that ends with `.` immediately before `[`. Put a blank line before the ```json line.",
32174
- "- If you add optional plain English before the fence (e.g. one short sentence), keep it **separate**: end that sentence, blank line, then ```json.",
32175
- '- In each `"summary"` string, avoid raw double-quote characters, or escape them as `\\"` so the JSON parses.',
32176
- "",
32177
- "JSON shape **inside the fence** (array only):",
32178
- '[{"path":"<file path exactly as given>","summary":"<one line, or two short lines separated by \\n>"}]',
32179
- "",
32180
- "Rules:",
32181
- "- Include **exactly one** object per file path listed below (same path strings).",
32182
- "- If a path is a removed directory, state briefly what you removed.",
32183
- "- Do not invent paths; use only the paths provided.",
32184
- "",
32185
- "## Files you changed",
32186
- ""
32187
- ];
32188
- for (const f of files) {
32189
- lines.push(`### ${f.path}`);
32190
- if (f.directoryRemoved) {
32191
- lines.push("(directory removed)");
32192
- lines.push("");
32193
- continue;
32194
- }
32195
- if (f.patchContent && f.patchContent.trim() !== "") {
32196
- lines.push("```diff");
32197
- lines.push(clip(f.patchContent.trim(), PATCH_PREVIEW_MAX));
32198
- lines.push("```");
32199
- } else if (f.oldText != null || f.newText != null) {
32200
- const oldT = (f.oldText ?? "").trim();
32201
- const newT = (f.newText ?? "").trim();
32202
- lines.push("Previous snippet:", clip(oldT, 6e3));
32203
- lines.push("New snippet:", clip(newT, 6e3));
32204
- } else {
32205
- lines.push("(no diff body stored for this path)");
32206
- }
32207
- lines.push("");
32208
- }
32209
- return lines.join("\n");
32210
- }
32211
-
32212
- // ../types/src/dedupe-session-file-changes-by-path.ts
32213
- function defaultRichness(c) {
32214
- const patch = typeof c.patchContent === "string" ? c.patchContent.length : 0;
32215
- const nt = typeof c.newText === "string" ? c.newText.length : 0;
32216
- const ot = typeof c.oldText === "string" ? c.oldText.length : 0;
32217
- const dir = c.directoryRemoved === true ? 8 : 0;
32218
- return (patch > 0 ? 4 : 0) + (nt > 0 ? 2 : 0) + (ot > 0 ? 1 : 0) + dir;
32219
- }
32220
- function dedupeSessionFileChangesByPath(items, richness = (item) => defaultRichness(item)) {
32221
- const byPath = /* @__PURE__ */ new Map();
32222
- for (const item of items) {
32223
- const p = typeof item.path === "string" ? item.path.trim() : "";
32224
- if (!p) continue;
32225
- const prev = byPath.get(p);
32226
- if (!prev || richness(item) >= richness(prev)) byPath.set(p, item);
32227
- }
32228
- return Array.from(byPath.entries()).sort(([a], [b]) => a.localeCompare(b)).map(([, v]) => v);
32229
- }
32230
-
32231
32423
  // ../types/src/diff/line-diff.ts
32232
32424
  function normalizeDiffLineText(line) {
32233
32425
  return line.replace(/\r$/, "").replace(/\s*\\s*$/, "");
@@ -32512,6 +32704,7 @@ function getAgentModelFromAgentConfig(config2) {
32512
32704
  }
32513
32705
 
32514
32706
  // src/paths/session-layout-paths.ts
32707
+ init_cwd();
32515
32708
  import * as path26 from "node:path";
32516
32709
  function resolveIsolatedSessionParentPathFromCheckouts(worktreePaths) {
32517
32710
  const resolved = worktreePaths.map((p) => path26.resolve(p)).filter(Boolean);
@@ -32582,6 +32775,9 @@ async function execProbeShutdownAware(file2, args, timeoutMs) {
32582
32775
  }
32583
32776
  }
32584
32777
 
32778
+ // src/agents/acp/clients/sdk/sdk-stdio-acp-client.ts
32779
+ init_cwd();
32780
+
32585
32781
  // src/agents/acp/clients/agent-stderr-capture.ts
32586
32782
  var STDERR_CAPTURE_MAX = 48e3;
32587
32783
  function createStderrCapture(child) {
@@ -32970,11 +33166,11 @@ function createSdkStdioExtNotificationHandler(options) {
32970
33166
 
32971
33167
  // src/agents/acp/clients/sdk/sdk-stdio-permission-request-handshake.ts
32972
33168
  function awaitSdkStdioPermissionRequestHandshake(params) {
32973
- const { requestId, paramsRecord, pending: pending2, onRequest } = params;
33169
+ const { requestId, paramsRecord, pending, onRequest } = params;
32974
33170
  return new Promise((resolve37) => {
32975
- pending2.set(requestId, { resolve: resolve37, params: paramsRecord });
33171
+ pending.set(requestId, { resolve: resolve37, params: paramsRecord });
32976
33172
  if (onRequest == null) {
32977
- pending2.delete(requestId);
33173
+ pending.delete(requestId);
32978
33174
  resolve37({ outcome: { outcome: "denied" } });
32979
33175
  return;
32980
33176
  }
@@ -32990,9 +33186,9 @@ function awaitSdkStdioPermissionRequestHandshake(params) {
32990
33186
  }
32991
33187
 
32992
33188
  // src/agents/acp/clients/sdk/sdk-stdio-permission-pending.ts
32993
- function resolvePendingSdkStdioPermissionCancellations(pending2) {
32994
- for (const [id, entry] of [...pending2.entries()]) {
32995
- pending2.delete(id);
33189
+ function resolvePendingSdkStdioPermissionCancellations(pending) {
33190
+ for (const [id, entry] of [...pending.entries()]) {
33191
+ pending.delete(id);
32996
33192
  entry.resolve({ outcome: { outcome: "cancelled" } });
32997
33193
  }
32998
33194
  }
@@ -33664,6 +33860,7 @@ __export(cursor_acp_client_exports, {
33664
33860
  createCursorAcpClient: () => createCursorAcpClient,
33665
33861
  detectLocalAgentPresence: () => detectLocalAgentPresence3
33666
33862
  });
33863
+ init_cwd();
33667
33864
 
33668
33865
  // src/agents/acp/clients/cursor/cursor-spawn-command.ts
33669
33866
  function buildCursorAcpSpawnCommand(base, sessionMode) {
@@ -33695,8 +33892,8 @@ function createCursorAcpSessionContext(options) {
33695
33892
 
33696
33893
  // src/agents/acp/clients/cursor/cancel-pending-cursor-permission-requests.ts
33697
33894
  function cancelPendingCursorPermissionRequests(pendingRequests, respond) {
33698
- for (const [reqId, pending2] of [...pendingRequests.entries()]) {
33699
- if (pending2.method === "session/request_permission") {
33895
+ for (const [reqId, pending] of [...pendingRequests.entries()]) {
33896
+ if (pending.method === "session/request_permission") {
33700
33897
  respond(reqId, { outcome: { outcome: "cancelled" } });
33701
33898
  pendingRequests.delete(reqId);
33702
33899
  }
@@ -33875,8 +34072,8 @@ function handleCursorIncomingPermissionRequest(id, method, msg, deps) {
33875
34072
 
33876
34073
  // src/agents/acp/clients/cursor/cursor-incoming-resolve-request.ts
33877
34074
  function resolveCursorIncomingRequest(pendingRequests, respond, requestId, result) {
33878
- const pending2 = pendingRequests.get(requestId);
33879
- 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;
33880
34077
  respond(requestId, payload);
33881
34078
  pendingRequests.delete(requestId);
33882
34079
  }
@@ -34013,25 +34210,25 @@ function createCursorJsonRpcInboundRespond(stdin) {
34013
34210
 
34014
34211
  // src/agents/acp/clients/cursor/cursor-json-rpc-outbound.ts
34015
34212
  function createCursorJsonRpcOutboundPending() {
34016
- const pending2 = /* @__PURE__ */ new Map();
34213
+ const pending = /* @__PURE__ */ new Map();
34017
34214
  let nextId = 1;
34018
34215
  function allocateId() {
34019
34216
  return nextId++;
34020
34217
  }
34021
34218
  function register(id, waiter) {
34022
- pending2.set(id, waiter);
34219
+ pending.set(id, waiter);
34023
34220
  }
34024
34221
  function settleResponse(id, msg) {
34025
- const waiter = pending2.get(id);
34222
+ const waiter = pending.get(id);
34026
34223
  if (!waiter) return false;
34027
- pending2.delete(id);
34224
+ pending.delete(id);
34028
34225
  if (msg.error) waiter.reject(msg.error);
34029
34226
  else waiter.resolve(msg.result);
34030
34227
  return true;
34031
34228
  }
34032
34229
  function rejectOnWriteError(id, err) {
34033
- const waiter = pending2.get(id);
34034
- pending2.delete(id);
34230
+ const waiter = pending.get(id);
34231
+ pending.delete(id);
34035
34232
  waiter?.reject(err);
34036
34233
  }
34037
34234
  return { allocateId, register, settleResponse, rejectOnWriteError };
@@ -35551,8 +35748,8 @@ async function execGitFile(args, options) {
35551
35748
  }
35552
35749
 
35553
35750
  // src/git/changes/parse/normalize-git-diff-path.ts
35554
- function normalizeGitDiffPath(path81) {
35555
- return path81.replace(/\\/g, "/").replace(/\/ +/g, "/").trim();
35751
+ function normalizeGitDiffPath(path84) {
35752
+ return path84.replace(/\\/g, "/").replace(/\/ +/g, "/").trim();
35556
35753
  }
35557
35754
 
35558
35755
  // src/git/changes/parse/parse-name-status-entries.ts
@@ -35836,102 +36033,6 @@ async function collectTurnGitDiffFromPreTurnSnapshot(options) {
35836
36033
  });
35837
36034
  }
35838
36035
 
35839
- // src/agents/acp/put-summarize-change-summaries.ts
35840
- async function putEncryptedChangeSummaryRows(params) {
35841
- const base = params.apiBaseUrl.replace(/\/+$/, "");
35842
- const entries = params.rows.map(({ path: path81, summary }) => {
35843
- const enc = params.e2ee.encryptFields({ summary }, ["summary"]);
35844
- return { path: path81, summary: JSON.stringify(enc) };
35845
- });
35846
- const res = await fetch(
35847
- `${base}/internal/sessions/${encodeURIComponent(params.sessionId)}/follow-ups/summarize-changes`,
35848
- {
35849
- method: "PUT",
35850
- headers: {
35851
- Authorization: `Bearer ${params.authToken}`,
35852
- "Content-Type": "application/json"
35853
- },
35854
- body: JSON.stringify({ entries })
35855
- }
35856
- );
35857
- if (!res.ok) {
35858
- const t = await res.text();
35859
- throw new Error(`PUT summarize-changes summaries failed ${res.status}: ${t.slice(0, 500)}`);
35860
- }
35861
- }
35862
-
35863
- // src/agents/acp/maybe-upload-e2ee-session-change-summaries.ts
35864
- async function maybeUploadE2eeSessionChangeSummariesAfterAgentSuccess(params) {
35865
- const {
35866
- sessionId,
35867
- runId,
35868
- resultSuccess,
35869
- output,
35870
- e2ee,
35871
- cloudApiBaseUrl,
35872
- getCloudAccessToken,
35873
- followUpCatalogPromptId,
35874
- sessionChangeSummaryFilePaths,
35875
- log: log2
35876
- } = params;
35877
- const outputStr = typeof output === "string" ? output : "";
35878
- if (!sessionId) {
35879
- return;
35880
- }
35881
- if (!runId) {
35882
- return;
35883
- }
35884
- if (!resultSuccess) {
35885
- return;
35886
- }
35887
- if (!e2ee) {
35888
- return;
35889
- }
35890
- if (!cloudApiBaseUrl) {
35891
- return;
35892
- }
35893
- if (!getCloudAccessToken) {
35894
- return;
35895
- }
35896
- if (followUpCatalogPromptId !== BUILTIN_SESSION_CHANGE_SUMMARY_FOLLOW_UP_CATALOG_PROMPT_ID) {
35897
- return;
35898
- }
35899
- if (!sessionChangeSummaryFilePaths || sessionChangeSummaryFilePaths.length === 0) {
35900
- return;
35901
- }
35902
- if (outputStr.trim() === "") {
35903
- return;
35904
- }
35905
- const allowed = /* @__PURE__ */ new Set();
35906
- for (const p of sessionChangeSummaryFilePaths) {
35907
- const t = p.trim();
35908
- if (!t) continue;
35909
- allowed.add(t);
35910
- allowed.add(normalizeRepoRelativePath(t));
35911
- }
35912
- const rows = parseChangeSummaryJson(outputStr, allowed);
35913
- if (rows.length === 0) {
35914
- return;
35915
- }
35916
- const token = getCloudAccessToken();
35917
- if (!token) {
35918
- return;
35919
- }
35920
- try {
35921
- await putEncryptedChangeSummaryRows({
35922
- apiBaseUrl: cloudApiBaseUrl,
35923
- authToken: token,
35924
- sessionId,
35925
- e2ee,
35926
- rows
35927
- });
35928
- } catch (uploadErr) {
35929
- log2(
35930
- `[Agent] Encrypted change summary upload failed: ${uploadErr instanceof Error ? uploadErr.message : String(uploadErr)}`
35931
- );
35932
- }
35933
- }
35934
-
35935
36036
  // src/agents/planning/submit-planning-todos-for-turn.ts
35936
36037
  async function submitPlanningTodosForTurn(params) {
35937
36038
  const token = params.getCloudAccessToken();
@@ -36000,10 +36101,8 @@ async function finalizeAndSendPromptResult(params) {
36000
36101
  agentCwd,
36001
36102
  isPlanningSession,
36002
36103
  followUpCatalogPromptId,
36003
- sessionChangeSummaryFilePaths,
36004
36104
  cloudApiBaseUrl,
36005
36105
  getCloudAccessToken,
36006
- e2ee,
36007
36106
  sendResult,
36008
36107
  sendSessionUpdate,
36009
36108
  log: log2
@@ -36017,18 +36116,6 @@ async function finalizeAndSendPromptResult(params) {
36017
36116
  log: log2
36018
36117
  });
36019
36118
  }
36020
- await maybeUploadE2eeSessionChangeSummariesAfterAgentSuccess({
36021
- sessionId,
36022
- runId,
36023
- resultSuccess: result.success === true,
36024
- output: result.output,
36025
- e2ee,
36026
- cloudApiBaseUrl,
36027
- getCloudAccessToken,
36028
- followUpCatalogPromptId,
36029
- sessionChangeSummaryFilePaths,
36030
- log: log2
36031
- });
36032
36119
  const planningTodosSubmit = await maybeSubmitPlanningTodosAfterAgentSuccess({
36033
36120
  sessionId,
36034
36121
  runId,
@@ -36472,7 +36559,6 @@ async function sendPromptToAgent(options) {
36472
36559
  sendSessionUpdate,
36473
36560
  log: log2,
36474
36561
  followUpCatalogPromptId,
36475
- sessionChangeSummaryFilePaths,
36476
36562
  cloudApiBaseUrl,
36477
36563
  getCloudAccessToken,
36478
36564
  e2ee,
@@ -36516,7 +36602,6 @@ async function sendPromptToAgent(options) {
36516
36602
  agentCwd,
36517
36603
  isPlanningSession,
36518
36604
  followUpCatalogPromptId,
36519
- sessionChangeSummaryFilePaths,
36520
36605
  cloudApiBaseUrl,
36521
36606
  getCloudAccessToken,
36522
36607
  e2ee,
@@ -36587,7 +36672,6 @@ async function runAcpPrompt(ctx, runCtx, opts) {
36587
36672
  sendResult,
36588
36673
  sendSessionUpdate,
36589
36674
  followUpCatalogPromptId,
36590
- sessionChangeSummaryFilePaths,
36591
36675
  cloudApiBaseUrl,
36592
36676
  getCloudAccessToken,
36593
36677
  e2ee,
@@ -36653,7 +36737,6 @@ async function runAcpPrompt(ctx, runCtx, opts) {
36653
36737
  sendSessionUpdate,
36654
36738
  log: ctx.log,
36655
36739
  followUpCatalogPromptId,
36656
- sessionChangeSummaryFilePaths,
36657
36740
  cloudApiBaseUrl,
36658
36741
  getCloudAccessToken,
36659
36742
  e2ee,
@@ -37111,8 +37194,10 @@ async function createBridgeAccessState(options = {}) {
37111
37194
 
37112
37195
  // src/agents/capabilities/warmup-agent-capabilities-on-connect.ts
37113
37196
  import * as path36 from "node:path";
37197
+ init_cwd();
37114
37198
 
37115
37199
  // src/agents/detect-local-agent-types.ts
37200
+ init_yield_to_event_loop();
37116
37201
  var LOCAL_AGENT_ACP_MODULES = [
37117
37202
  cursor_acp_client_exports,
37118
37203
  codex_acp_client_exports,
@@ -37141,6 +37226,9 @@ async function detectLocalAgentTypes() {
37141
37226
  }
37142
37227
  }
37143
37228
 
37229
+ // src/agents/capabilities/probe-agent-capabilities-for-types.ts
37230
+ init_yield_to_event_loop();
37231
+
37144
37232
  // src/sqlite/hash-json-sha256.ts
37145
37233
  import { createHash as createHash2 } from "node:crypto";
37146
37234
  function hashJsonUtf8Sha256(value) {
@@ -37317,6 +37405,9 @@ async function probeAgentCapabilitiesForDetectedTypes(params) {
37317
37405
  return changedCount;
37318
37406
  }
37319
37407
 
37408
+ // src/agents/capabilities/warmup-agent-capabilities-on-connect.ts
37409
+ init_yield_to_event_loop();
37410
+
37320
37411
  // src/agents/capabilities/agent-capability-warmup-run.ts
37321
37412
  var warmupEpoch = 0;
37322
37413
  function cancelInFlightAgentCapabilityWarmup() {
@@ -37458,6 +37549,7 @@ async function createBridgeAccessAndAcp(options) {
37458
37549
  }
37459
37550
 
37460
37551
  // src/connection/create-bridge-preview-stack.ts
37552
+ init_cwd();
37461
37553
  import * as path39 from "node:path";
37462
37554
 
37463
37555
  // src/preview-environments/manager/firehose-messages.ts
@@ -38982,11 +39074,11 @@ function tryConsumeBinaryProxyBody(raw, deps) {
38982
39074
  if (!PROXY_ID_RE.test(id)) return false;
38983
39075
  const body = raw.slice(PROXY_ID_BYTES);
38984
39076
  const bodyBytes = body.length > 0 ? new Uint8Array(body) : new Uint8Array(0);
38985
- const pending2 = deps.pendingProxyBody.get(id);
38986
- if (pending2) {
39077
+ const pending = deps.pendingProxyBody.get(id);
39078
+ if (pending) {
38987
39079
  deps.pendingProxyBody.delete(id);
38988
39080
  deps.startStreamingProxy({
38989
- ...pending2.pr,
39081
+ ...pending.pr,
38990
39082
  body: bodyBytes.length > 0 ? bodyBytes : void 0
38991
39083
  });
38992
39084
  return true;
@@ -39348,7 +39440,11 @@ function createBridgeMessageDeps(params) {
39348
39440
  };
39349
39441
  }
39350
39442
 
39443
+ // src/connection/create-bridge-local-reports.ts
39444
+ init_cwd();
39445
+
39351
39446
  // src/skills/discovery/skill-discovery-roots.ts
39447
+ init_yield_to_event_loop();
39352
39448
  var SKILL_DISCOVERY_ROOTS = [".agents/skills", ".claude/skills", ".cursor/skills", "skills"];
39353
39449
  async function yieldSkillDiscoveryWork(entryCount) {
39354
39450
  if (entryCount > 0 && entryCount % INDEX_WORK_YIELD_EVERY === 0) {
@@ -39539,9 +39635,9 @@ function createBridgeHeartbeatController(params) {
39539
39635
  if (awaitingSeq === null) return;
39540
39636
  if (!Number.isFinite(seq)) return;
39541
39637
  const ack = Math.trunc(seq);
39542
- const pending2 = awaitingSeq;
39543
- if (ack < pending2) return;
39544
- if (ack === pending2) {
39638
+ const pending = awaitingSeq;
39639
+ if (ack < pending) return;
39640
+ if (ack === pending) {
39545
39641
  const rtt = Date.now() - sentAtMs;
39546
39642
  if (Number.isFinite(rtt) && rtt >= 0 && rtt < 6e5) {
39547
39643
  rttSamples.push(rtt);
@@ -39673,6 +39769,7 @@ function allocateDirNameForLauncherCwd(layout, bridgeRootPath2) {
39673
39769
  }
39674
39770
 
39675
39771
  // src/worktrees/manager/session-worktree-cache.ts
39772
+ init_normalize_resolved_path();
39676
39773
  var SessionWorktreeCache = class {
39677
39774
  sessionRepoCheckoutPaths = /* @__PURE__ */ new Map();
39678
39775
  sessionParentPathBySession = /* @__PURE__ */ new Map();
@@ -39713,6 +39810,9 @@ function createSessionWorktreeManagerContext(options) {
39713
39810
  };
39714
39811
  }
39715
39812
 
39813
+ // src/worktrees/manager/git/commit-session-worktree.ts
39814
+ init_cwd();
39815
+
39716
39816
  // ../../node_modules/.pnpm/simple-git@3.32.3/node_modules/simple-git/dist/esm/index.js
39717
39817
  var import_file_exists = __toESM(require_dist(), 1);
39718
39818
  var import_debug = __toESM(require_src(), 1);
@@ -39750,8 +39850,8 @@ function pathspec(...paths) {
39750
39850
  cache.set(key, paths);
39751
39851
  return key;
39752
39852
  }
39753
- function isPathSpec(path81) {
39754
- return path81 instanceof String && cache.has(path81);
39853
+ function isPathSpec(path84) {
39854
+ return path84 instanceof String && cache.has(path84);
39755
39855
  }
39756
39856
  function toPaths(pathSpec) {
39757
39857
  return cache.get(pathSpec) || [];
@@ -39840,8 +39940,8 @@ function toLinesWithContent(input = "", trimmed2 = true, separator = "\n") {
39840
39940
  function forEachLineWithContent(input, callback) {
39841
39941
  return toLinesWithContent(input, true).map((line) => callback(line));
39842
39942
  }
39843
- function folderExists(path81) {
39844
- 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);
39845
39945
  }
39846
39946
  function append(target, item) {
39847
39947
  if (Array.isArray(target)) {
@@ -40245,8 +40345,8 @@ function checkIsRepoRootTask() {
40245
40345
  commands,
40246
40346
  format: "utf-8",
40247
40347
  onError,
40248
- parser(path81) {
40249
- return /^\.(git)?$/.test(path81.trim());
40348
+ parser(path84) {
40349
+ return /^\.(git)?$/.test(path84.trim());
40250
40350
  }
40251
40351
  };
40252
40352
  }
@@ -40680,11 +40780,11 @@ function parseGrep(grep) {
40680
40780
  const paths = /* @__PURE__ */ new Set();
40681
40781
  const results = {};
40682
40782
  forEachLineWithContent(grep, (input) => {
40683
- const [path81, line, preview] = input.split(NULL);
40684
- paths.add(path81);
40685
- (results[path81] = results[path81] || []).push({
40783
+ const [path84, line, preview] = input.split(NULL);
40784
+ paths.add(path84);
40785
+ (results[path84] = results[path84] || []).push({
40686
40786
  line: asNumber(line),
40687
- path: path81,
40787
+ path: path84,
40688
40788
  preview
40689
40789
  });
40690
40790
  });
@@ -41449,14 +41549,14 @@ var init_hash_object = __esm2({
41449
41549
  init_task();
41450
41550
  }
41451
41551
  });
41452
- function parseInit(bare, path81, text) {
41552
+ function parseInit(bare, path84, text) {
41453
41553
  const response = String(text).trim();
41454
41554
  let result;
41455
41555
  if (result = initResponseRegex.exec(response)) {
41456
- return new InitSummary(bare, path81, false, result[1]);
41556
+ return new InitSummary(bare, path84, false, result[1]);
41457
41557
  }
41458
41558
  if (result = reInitResponseRegex.exec(response)) {
41459
- return new InitSummary(bare, path81, true, result[1]);
41559
+ return new InitSummary(bare, path84, true, result[1]);
41460
41560
  }
41461
41561
  let gitDir = "";
41462
41562
  const tokens = response.split(" ");
@@ -41467,7 +41567,7 @@ function parseInit(bare, path81, text) {
41467
41567
  break;
41468
41568
  }
41469
41569
  }
41470
- return new InitSummary(bare, path81, /^re/i.test(response), gitDir);
41570
+ return new InitSummary(bare, path84, /^re/i.test(response), gitDir);
41471
41571
  }
41472
41572
  var InitSummary;
41473
41573
  var initResponseRegex;
@@ -41476,9 +41576,9 @@ var init_InitSummary = __esm2({
41476
41576
  "src/lib/responses/InitSummary.ts"() {
41477
41577
  "use strict";
41478
41578
  InitSummary = class {
41479
- constructor(bare, path81, existing, gitDir) {
41579
+ constructor(bare, path84, existing, gitDir) {
41480
41580
  this.bare = bare;
41481
- this.path = path81;
41581
+ this.path = path84;
41482
41582
  this.existing = existing;
41483
41583
  this.gitDir = gitDir;
41484
41584
  }
@@ -41490,7 +41590,7 @@ var init_InitSummary = __esm2({
41490
41590
  function hasBareCommand(command) {
41491
41591
  return command.includes(bareCommand);
41492
41592
  }
41493
- function initTask(bare = false, path81, customArgs) {
41593
+ function initTask(bare = false, path84, customArgs) {
41494
41594
  const commands = ["init", ...customArgs];
41495
41595
  if (bare && !hasBareCommand(commands)) {
41496
41596
  commands.splice(1, 0, bareCommand);
@@ -41499,7 +41599,7 @@ function initTask(bare = false, path81, customArgs) {
41499
41599
  commands,
41500
41600
  format: "utf-8",
41501
41601
  parser(text) {
41502
- return parseInit(commands.includes("--bare"), path81, text);
41602
+ return parseInit(commands.includes("--bare"), path84, text);
41503
41603
  }
41504
41604
  };
41505
41605
  }
@@ -42315,12 +42415,12 @@ var init_FileStatusSummary = __esm2({
42315
42415
  "use strict";
42316
42416
  fromPathRegex = /^(.+)\0(.+)$/;
42317
42417
  FileStatusSummary = class {
42318
- constructor(path81, index, working_dir) {
42319
- this.path = path81;
42418
+ constructor(path84, index, working_dir) {
42419
+ this.path = path84;
42320
42420
  this.index = index;
42321
42421
  this.working_dir = working_dir;
42322
42422
  if (index === "R" || working_dir === "R") {
42323
- const detail = fromPathRegex.exec(path81) || [null, path81, path81];
42423
+ const detail = fromPathRegex.exec(path84) || [null, path84, path84];
42324
42424
  this.from = detail[2] || "";
42325
42425
  this.path = detail[1] || "";
42326
42426
  }
@@ -42351,14 +42451,14 @@ function splitLine(result, lineStr) {
42351
42451
  default:
42352
42452
  return;
42353
42453
  }
42354
- function data(index, workingDir, path81) {
42454
+ function data(index, workingDir, path84) {
42355
42455
  const raw = `${index}${workingDir}`;
42356
42456
  const handler = parsers6.get(raw);
42357
42457
  if (handler) {
42358
- handler(result, path81);
42458
+ handler(result, path84);
42359
42459
  }
42360
42460
  if (raw !== "##" && raw !== "!!") {
42361
- result.files.push(new FileStatusSummary(path81, index, workingDir));
42461
+ result.files.push(new FileStatusSummary(path84, index, workingDir));
42362
42462
  }
42363
42463
  }
42364
42464
  }
@@ -42667,9 +42767,9 @@ var init_simple_git_api = __esm2({
42667
42767
  next
42668
42768
  );
42669
42769
  }
42670
- hashObject(path81, write) {
42770
+ hashObject(path84, write) {
42671
42771
  return this._runTask(
42672
- hashObjectTask(path81, write === true),
42772
+ hashObjectTask(path84, write === true),
42673
42773
  trailingFunctionArgument(arguments)
42674
42774
  );
42675
42775
  }
@@ -43022,8 +43122,8 @@ var init_branch = __esm2({
43022
43122
  }
43023
43123
  });
43024
43124
  function toPath(input) {
43025
- const path81 = input.trim().replace(/^["']|["']$/g, "");
43026
- return path81 && normalize3(path81);
43125
+ const path84 = input.trim().replace(/^["']|["']$/g, "");
43126
+ return path84 && normalize3(path84);
43027
43127
  }
43028
43128
  var parseCheckIgnore;
43029
43129
  var init_CheckIgnore = __esm2({
@@ -43337,8 +43437,8 @@ __export2(sub_module_exports, {
43337
43437
  subModuleTask: () => subModuleTask,
43338
43438
  updateSubModuleTask: () => updateSubModuleTask
43339
43439
  });
43340
- function addSubModuleTask(repo, path81) {
43341
- return subModuleTask(["add", repo, path81]);
43440
+ function addSubModuleTask(repo, path84) {
43441
+ return subModuleTask(["add", repo, path84]);
43342
43442
  }
43343
43443
  function initSubModuleTask(customArgs) {
43344
43444
  return subModuleTask(["init", ...customArgs]);
@@ -43671,8 +43771,8 @@ var require_git = __commonJS2({
43671
43771
  }
43672
43772
  return this._runTask(straightThroughStringTask2(command, this._trimmed), next);
43673
43773
  };
43674
- Git2.prototype.submoduleAdd = function(repo, path81, then) {
43675
- 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));
43676
43776
  };
43677
43777
  Git2.prototype.submoduleUpdate = function(args, then) {
43678
43778
  return this._runTask(
@@ -44408,8 +44508,8 @@ function parseNumstatEntries(lines) {
44408
44508
  }
44409
44509
  function parseNumstat(lines) {
44410
44510
  const m = /* @__PURE__ */ new Map();
44411
- for (const [path81, entry] of parseNumstatEntries(lines)) {
44412
- 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 });
44413
44513
  }
44414
44514
  return m;
44415
44515
  }
@@ -44607,6 +44707,7 @@ async function pushAheadOfUpstreamForPaths(paths) {
44607
44707
  }
44608
44708
 
44609
44709
  // src/worktrees/manager/resolve-commit-targets.ts
44710
+ init_cwd();
44610
44711
  function bridgeRootBinding(bridgeRoot) {
44611
44712
  return {
44612
44713
  sessionParentPath: bridgeRoot,
@@ -44692,6 +44793,7 @@ function formatRemoteDisplayLabel(remoteUrl) {
44692
44793
  }
44693
44794
 
44694
44795
  // src/git/changes/repo/get-working-tree-change-repo-details.ts
44796
+ init_cwd();
44695
44797
  import * as path52 from "node:path";
44696
44798
 
44697
44799
  // src/git/changes/repo/build-working-tree-change-repo-detail.ts
@@ -44941,6 +45043,7 @@ function createHydrateSourceLines(options) {
44941
45043
  }
44942
45044
 
44943
45045
  // src/git/changes/patch/hydrate/create-hydrate-yield.ts
45046
+ init_yield_to_event_loop();
44944
45047
  function createHydrateYield() {
44945
45048
  let processedLines = 0;
44946
45049
  return async () => {
@@ -45704,6 +45807,7 @@ function parseWorkingTreeChangeKind(value) {
45704
45807
  }
45705
45808
 
45706
45809
  // src/worktrees/manager/git/get-session-working-tree-change-file-patch.ts
45810
+ init_cwd();
45707
45811
  import * as path54 from "node:path";
45708
45812
  async function getSessionWorkingTreeChangeFilePatch(cache2, sessionId, discover, opts) {
45709
45813
  const targets = await resolveCommitTargetsAsync(sessionId, cache2, discover);
@@ -45754,6 +45858,8 @@ import * as fs36 from "node:fs";
45754
45858
  import * as fs35 from "node:fs";
45755
45859
 
45756
45860
  // src/worktrees/is-removable-session-worktree-checkout-path.ts
45861
+ init_cwd();
45862
+ init_normalize_resolved_path();
45757
45863
  import path55 from "node:path";
45758
45864
  function isBridgeRootCheckoutPath(checkoutPath) {
45759
45865
  return normalizeResolvedPath(checkoutPath) === normalizeResolvedPath(getBridgeRoot());
@@ -45854,9 +45960,13 @@ async function renameSessionWorktreeBranch(cache2, sessionId, newBranch, log2) {
45854
45960
  await renameSessionWorktreeBranches(paths, newBranch, log2);
45855
45961
  }
45856
45962
 
45963
+ // src/worktrees/manager/discover-session-binding.ts
45964
+ init_cwd();
45965
+
45857
45966
  // src/worktrees/discovery/discover-session-worktree-on-disk.ts
45858
45967
  import * as fs40 from "node:fs";
45859
45968
  import * as path61 from "node:path";
45969
+ init_yield_to_event_loop();
45860
45970
 
45861
45971
  // src/worktrees/discovery/collect-worktree-paths.ts
45862
45972
  import * as fs38 from "node:fs";
@@ -45890,6 +46000,7 @@ function shouldSkipDiskWalkEntry(name) {
45890
46000
  // src/worktrees/discovery/disk-walk-utils.ts
45891
46001
  import * as fs37 from "node:fs";
45892
46002
  import * as path57 from "node:path";
46003
+ init_yield_to_event_loop();
45893
46004
  async function yieldDuringDiskWalk(state) {
45894
46005
  state.entries++;
45895
46006
  if (state.entries % DISK_WALK_YIELD_EVERY !== 0) return true;
@@ -46079,6 +46190,7 @@ import * as path63 from "node:path";
46079
46190
 
46080
46191
  // src/worktrees/discovery/discover-legacy-binding-ascending-from-checkout.ts
46081
46192
  import * as path62 from "node:path";
46193
+ init_yield_to_event_loop();
46082
46194
  async function discoverLegacyBindingAscendingFromCheckout(sessionId, checkoutPath) {
46083
46195
  const sid = sessionId.trim();
46084
46196
  if (!sid) return null;
@@ -46196,11 +46308,16 @@ function parseSessionParent(v) {
46196
46308
  return null;
46197
46309
  }
46198
46310
 
46311
+ // src/worktrees/manager/prepare-and-remember-session-worktrees.ts
46312
+ init_cwd();
46313
+
46199
46314
  // src/worktrees/prepare-new-isolated-worktrees.ts
46200
46315
  import * as fs43 from "node:fs";
46201
46316
  import * as path65 from "node:path";
46202
46317
 
46203
46318
  // src/git/discover-repos.ts
46319
+ init_cwd();
46320
+ init_yield_to_event_loop();
46204
46321
  import * as fs42 from "node:fs";
46205
46322
  import * as path64 from "node:path";
46206
46323
  var GIT_DISCOVER_YIELD_EVERY = 32;
@@ -46428,6 +46545,7 @@ async function resolveExistingSessionParentPath(sessionId, cache2, discover) {
46428
46545
 
46429
46546
  // src/worktrees/manager/resolve-explicit-session-parent-path.ts
46430
46547
  import * as path66 from "node:path";
46548
+ init_yield_to_event_loop();
46431
46549
  async function resolveExplicitSessionParentPath(params) {
46432
46550
  const resolved = path66.resolve(params.parentPathRaw);
46433
46551
  if (parseSessionParent(params.sessionParent) !== "worktrees_root") {
@@ -46593,7 +46711,12 @@ var SessionWorktreeManager = class {
46593
46711
  }
46594
46712
  };
46595
46713
 
46714
+ // src/worktrees/manager/preview-worktree-manager.ts
46715
+ init_cwd();
46716
+
46596
46717
  // src/worktrees/discovery/discover-preview-worktree-on-disk.ts
46718
+ init_cwd();
46719
+ init_yield_to_event_loop();
46597
46720
  import * as fs44 from "node:fs";
46598
46721
  import * as path67 from "node:path";
46599
46722
  async function discoverPreviewWorktreeOnDisk(options) {
@@ -46644,6 +46767,7 @@ async function discoverPreviewWorktreeForBridge(options) {
46644
46767
  }
46645
46768
 
46646
46769
  // src/worktrees/manager/preview-worktree-cache.ts
46770
+ init_normalize_resolved_path();
46647
46771
  var PreviewWorktreeCache = class {
46648
46772
  repoCheckoutPaths = /* @__PURE__ */ new Map();
46649
46773
  parentPathByEnvironment = /* @__PURE__ */ new Map();
@@ -46756,6 +46880,7 @@ var PreviewWorktreeManager = class {
46756
46880
  };
46757
46881
 
46758
46882
  // src/worktrees/deploy/deploy-session-to-preview-environment.ts
46883
+ init_cwd();
46759
46884
  import * as path71 from "node:path";
46760
46885
 
46761
46886
  // src/git/worktrees/reset-worktree-to-branch.ts
@@ -47315,8 +47440,6 @@ function dispatchLocalPrompt(next, deps) {
47315
47440
  ...sessionParentPath ? { sessionParentPath } : {},
47316
47441
  ...worktreeBaseBranches && Object.keys(worktreeBaseBranches).length > 0 ? { worktreeBaseBranches } : {},
47317
47442
  ...typeof pl.followUpCatalogPromptId === "string" ? { followUpCatalogPromptId: pl.followUpCatalogPromptId } : {},
47318
- ...Array.isArray(pl.sessionChangeSummaryFilePaths) ? { sessionChangeSummaryFilePaths: pl.sessionChangeSummaryFilePaths } : {},
47319
- ...Array.isArray(pl.sessionChangeSummaryFileSnapshots) ? { sessionChangeSummaryFileSnapshots: pl.sessionChangeSummaryFileSnapshots } : {},
47320
47443
  ...typeof pl.agentType === "string" && pl.agentType.trim() ? { agentType: pl.agentType.trim() } : {},
47321
47444
  ...pl.agentConfig != null && typeof pl.agentConfig === "object" && !Array.isArray(pl.agentConfig) && Object.keys(pl.agentConfig).length > 0 ? { agentConfig: pl.agentConfig } : {},
47322
47445
  ...Array.isArray(pl.attachments) && pl.attachments.length > 0 ? { attachments: pl.attachments } : {}
@@ -47455,6 +47578,7 @@ async function applyPreTurnSnapshot(filePath, log2) {
47455
47578
  }
47456
47579
 
47457
47580
  // src/prompt-turn-queue/runner/run-local-revert-before-queued-prompt.ts
47581
+ init_cwd();
47458
47582
  async function runLocalRevertBeforeQueuedPrompt(next, deps) {
47459
47583
  if (next.bridgeServerState !== "requeued_with_revert") return true;
47460
47584
  const sid = next.sessionId;
@@ -47579,8 +47703,7 @@ function createBridgePromptSenders(deps, getWs) {
47579
47703
  return true;
47580
47704
  };
47581
47705
  const sendResult = (result) => {
47582
- const skipEncryptForChangeSummaryFollowUp = result.type === "prompt_result" && result.followUpCatalogPromptId === BUILTIN_SESSION_CHANGE_SUMMARY_FOLLOW_UP_CATALOG_PROMPT_ID;
47583
- const encryptedFields = result.type === "prompt_result" && !skipEncryptForChangeSummaryFollowUp ? ["output", "error"] : [];
47706
+ const encryptedFields = result.type === "prompt_result" ? ["output", "error"] : [];
47584
47707
  sendBridgeMessage(result, encryptedFields);
47585
47708
  if (result.type === "prompt_result") {
47586
47709
  const pr = result;
@@ -47644,62 +47767,8 @@ function parseWorktreeBaseBranches(msg) {
47644
47767
  return Object.keys(out).length > 0 ? out : void 0;
47645
47768
  }
47646
47769
 
47647
- // src/agents/acp/change-summary/decrypt-change-summary-file-input.ts
47648
- function decryptChangeSummaryFileInput(row, e2ee) {
47649
- if (!e2ee) return row;
47650
- for (const field of ["path", "patchContent", "oldText", "newText"]) {
47651
- const raw = row[field];
47652
- if (typeof raw !== "string" || raw.trim() === "") continue;
47653
- let o;
47654
- try {
47655
- o = JSON.parse(raw);
47656
- } catch {
47657
- continue;
47658
- }
47659
- if (!isE2eeEnvelope(o.ee)) continue;
47660
- try {
47661
- const d = e2ee.decryptMessage(o);
47662
- const out = {
47663
- path: typeof d.path === "string" ? d.path : row.path
47664
- };
47665
- if (d.directoryRemoved === true) out.directoryRemoved = true;
47666
- else if (row.directoryRemoved === true) out.directoryRemoved = true;
47667
- if (typeof d.patchContent === "string") out.patchContent = d.patchContent;
47668
- else if (typeof row.patchContent === "string" && row.patchContent !== raw) out.patchContent = row.patchContent;
47669
- if (typeof d.oldText === "string") out.oldText = d.oldText;
47670
- else if (typeof row.oldText === "string") out.oldText = row.oldText;
47671
- if (typeof d.newText === "string") out.newText = d.newText;
47672
- else if (typeof row.newText === "string") out.newText = row.newText;
47673
- return out;
47674
- } catch {
47675
- return row;
47676
- }
47677
- }
47678
- return row;
47679
- }
47680
-
47681
- // src/agents/acp/change-summary/resolve-change-summary-prompt-for-agent.ts
47682
- function hasSummarizePayload(f) {
47683
- return f.directoryRemoved === true || f.patchContent != null && f.patchContent.trim() !== "" || f.oldText != null && f.oldText.trim() !== "" || f.newText != null && f.newText.trim() !== "";
47684
- }
47685
- function resolveChangeSummaryPromptForAgent(params) {
47686
- const isBuiltin = params.followUpCatalogPromptId === BUILTIN_SESSION_CHANGE_SUMMARY_FOLLOW_UP_CATALOG_PROMPT_ID;
47687
- const snaps = params.sessionChangeSummaryFileSnapshots;
47688
- if (!isBuiltin || !snaps || snaps.length === 0) {
47689
- return { promptText: params.bridgePromptText, sessionChangeSummaryFilePaths: void 0 };
47690
- }
47691
- const decrypted = dedupeSessionFileChangesByPath(snaps.map((row) => decryptChangeSummaryFileInput(row, params.e2ee)));
47692
- const withPayload = decrypted.filter(hasSummarizePayload);
47693
- if (withPayload.length === 0) {
47694
- return { promptText: params.bridgePromptText, sessionChangeSummaryFilePaths: void 0 };
47695
- }
47696
- return {
47697
- promptText: buildSessionChangeSummaryPrompt(withPayload),
47698
- sessionChangeSummaryFilePaths: withPayload.map((f) => f.path)
47699
- };
47700
- }
47701
-
47702
47770
  // src/agents/acp/from-bridge/bridge-prompt-preamble.ts
47771
+ init_cwd();
47703
47772
  import { execFile as execFile8 } from "node:child_process";
47704
47773
  import { promisify as promisify9 } from "node:util";
47705
47774
  var execFileAsync7 = promisify9(execFile8);
@@ -47745,29 +47814,9 @@ async function runBridgePromptPreamble(params) {
47745
47814
  });
47746
47815
  }
47747
47816
  }
47748
- function parseChangeSummarySnapshots(raw) {
47749
- if (!Array.isArray(raw) || raw.length === 0) return void 0;
47750
- const out = [];
47751
- for (const item of raw) {
47752
- if (!item || typeof item !== "object") continue;
47753
- const o = item;
47754
- const path81 = typeof o.path === "string" && o.path.trim() !== "" ? o.path.trim() : "";
47755
- if (!path81) continue;
47756
- const row = { path: path81 };
47757
- if (typeof o.patchContent === "string") row.patchContent = o.patchContent;
47758
- if (typeof o.oldText === "string") row.oldText = o.oldText;
47759
- if (typeof o.newText === "string") row.newText = o.newText;
47760
- if (o.directoryRemoved === true) row.directoryRemoved = true;
47761
- out.push(row);
47762
- }
47763
- return out.length > 0 ? out : void 0;
47764
- }
47765
47817
  function parseFollowUpFieldsFromPromptMessage(msg) {
47766
47818
  const followUpCatalogPromptId = typeof msg.followUpCatalogPromptId === "string" && msg.followUpCatalogPromptId.trim() !== "" ? msg.followUpCatalogPromptId.trim() : null;
47767
- const rawPaths = msg.sessionChangeSummaryFilePaths;
47768
- const sessionChangeSummaryFilePaths = Array.isArray(rawPaths) ? rawPaths.filter((p) => typeof p === "string" && p.trim() !== "").map((p) => p.trim()) : void 0;
47769
- const sessionChangeSummaryFileSnapshots = parseChangeSummarySnapshots(msg.sessionChangeSummaryFileSnapshots);
47770
- return { followUpCatalogPromptId, sessionChangeSummaryFilePaths, sessionChangeSummaryFileSnapshots };
47819
+ return { followUpCatalogPromptId };
47771
47820
  }
47772
47821
 
47773
47822
  // src/agents/acp/from-bridge/handle-bridge-prompt/run-preamble-and-prompt.ts
@@ -47798,25 +47847,9 @@ async function runPreambleAndPrompt(params) {
47798
47847
  runId,
47799
47848
  effectiveCwd
47800
47849
  });
47801
- const {
47802
- followUpCatalogPromptId,
47803
- sessionChangeSummaryFilePaths: pathsFromBridge,
47804
- sessionChangeSummaryFileSnapshots
47805
- } = parseFollowUpFieldsFromPromptMessage(msg);
47806
- const { promptText: resolvedPromptText, sessionChangeSummaryFilePaths } = resolveChangeSummaryPromptForAgent({
47807
- followUpCatalogPromptId,
47808
- sessionChangeSummaryFileSnapshots,
47809
- bridgePromptText: promptText,
47810
- e2ee: deps.e2ee
47811
- });
47812
- if (sessionChangeSummaryFileSnapshots && sessionChangeSummaryFileSnapshots.length > 0 && resolvedPromptText === promptText) {
47813
- deps.log(
47814
- "[Agent] Change-summary snapshots were present but the prompt was not rebuilt (decrypt failed or empty payloads); sending the bridge prompt as-is."
47815
- );
47816
- }
47817
- const pathsForUpload = sessionChangeSummaryFilePaths ?? pathsFromBridge;
47850
+ const { followUpCatalogPromptId } = parseFollowUpFieldsFromPromptMessage(msg);
47818
47851
  deps.acpManager.handlePrompt({
47819
- promptText: resolvedPromptText,
47852
+ promptText,
47820
47853
  promptId: msg.id,
47821
47854
  sessionId,
47822
47855
  runId,
@@ -47828,7 +47861,6 @@ async function runPreambleAndPrompt(params) {
47828
47861
  sendResult,
47829
47862
  sendSessionUpdate,
47830
47863
  followUpCatalogPromptId,
47831
- sessionChangeSummaryFilePaths: pathsForUpload,
47832
47864
  cloudApiBaseUrl: deps.cloudApiBaseUrl,
47833
47865
  getCloudAccessToken: deps.getCloudAccessToken,
47834
47866
  e2ee: deps.e2ee,
@@ -47944,6 +47976,7 @@ var handleSessionRequestResponseMessage = (msg, deps) => {
47944
47976
  };
47945
47977
 
47946
47978
  // src/skills/preview.ts
47979
+ init_cwd();
47947
47980
  import { spawn as spawn10 } from "node:child_process";
47948
47981
  var PREVIEW_API_BASE_PATH = "/__preview";
47949
47982
  var PREVIEW_SECRET_HEADER = "X-Preview-Secret";
@@ -47964,8 +47997,8 @@ function randomSecret() {
47964
47997
  }
47965
47998
  return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
47966
47999
  }
47967
- async function requestPreviewApi(port, secret, method, path81, body) {
47968
- 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}`;
47969
48002
  const headers = {
47970
48003
  [PREVIEW_SECRET_HEADER]: secret,
47971
48004
  "Content-Type": "application/json"
@@ -47977,7 +48010,7 @@ async function requestPreviewApi(port, secret, method, path81, body) {
47977
48010
  });
47978
48011
  const data = await res.json().catch(() => ({}));
47979
48012
  if (!res.ok) {
47980
- throw new Error(data?.error ?? `Preview API ${method} ${path81}: ${res.status}`);
48013
+ throw new Error(data?.error ?? `Preview API ${method} ${path84}: ${res.status}`);
47981
48014
  }
47982
48015
  return data;
47983
48016
  }
@@ -48142,6 +48175,8 @@ var handleSkillCallMessage = (msg, { getWs, log: log2 }) => {
48142
48175
  };
48143
48176
 
48144
48177
  // src/files/resolve-file-browser-session-parent.ts
48178
+ init_normalize_resolved_path();
48179
+ init_cwd();
48145
48180
  async function resolveFileBrowserSessionParent(sessionWorktreeManager, sessionId) {
48146
48181
  const sid = sessionId?.trim();
48147
48182
  if (sid) {
@@ -48152,301 +48187,18 @@ async function resolveFileBrowserSessionParent(sessionWorktreeManager, sessionId
48152
48187
  return getBridgeRoot();
48153
48188
  }
48154
48189
 
48155
- // src/files/list-dir/index.ts
48156
- import fs49 from "node:fs";
48157
-
48158
- // src/files/ensure-under-cwd.ts
48159
- import path74 from "node:path";
48160
- function ensureUnderCwd(relativePath, cwd = getBridgeRoot()) {
48161
- const normalized = path74.normalize(relativePath).replace(/^(\.\/)+/, "");
48162
- const resolved = path74.resolve(cwd, normalized);
48163
- if (!resolved.startsWith(cwd + path74.sep) && resolved !== cwd) {
48164
- return null;
48165
- }
48166
- return resolved;
48167
- }
48168
-
48169
- // src/files/list-dir/types.ts
48170
- var LIST_DIR_YIELD_EVERY = 256;
48171
-
48172
- // src/files/list-dir/map-dir-entry.ts
48173
- import path75 from "node:path";
48174
- import fs48 from "node:fs";
48175
- async function mapDirEntry(d, relativePath, resolved) {
48176
- const entryPath = path75.join(relativePath || ".", d.name).replace(/\\/g, "/");
48177
- const fullPath = path75.join(resolved, d.name);
48178
- let isDir = d.isDirectory();
48179
- if (d.isSymbolicLink()) {
48180
- try {
48181
- const targetStat = await fs48.promises.stat(fullPath);
48182
- isDir = targetStat.isDirectory();
48183
- } catch {
48184
- isDir = false;
48185
- }
48186
- }
48187
- return {
48188
- name: d.name,
48189
- path: entryPath,
48190
- isDir,
48191
- isSymlink: d.isSymbolicLink()
48192
- };
48193
- }
48194
-
48195
- // src/files/list-dir/sort-entries.ts
48196
- function sortListEntries(entries) {
48197
- return entries.sort((a, b) => {
48198
- if (a.isDir !== b.isDir) return a.isDir ? -1 : 1;
48199
- return a.name.localeCompare(b.name, void 0, { sensitivity: "base" });
48200
- });
48201
- }
48202
-
48203
- // src/files/list-dir/index.ts
48204
- async function listDirAsync(relativePath, sessionParentPath = getBridgeRoot()) {
48205
- await yieldToEventLoop();
48206
- const resolved = ensureUnderCwd(relativePath || ".", sessionParentPath);
48207
- if (!resolved) {
48208
- return { error: "Path is outside working directory" };
48209
- }
48210
- try {
48211
- const names = await fs49.promises.readdir(resolved, { withFileTypes: true });
48212
- const entries = [];
48213
- for (let i = 0; i < names.length; i++) {
48214
- if (i > 0 && i % LIST_DIR_YIELD_EVERY === 0) {
48215
- await yieldToEventLoop();
48216
- }
48217
- entries.push(await mapDirEntry(names[i], relativePath, resolved));
48218
- }
48219
- return { entries: sortListEntries(entries) };
48220
- } catch (err) {
48221
- const message = err instanceof Error ? err.message : String(err);
48222
- return { error: message };
48223
- }
48224
- }
48225
-
48226
- // src/files/handle-file-browser-search.ts
48227
- import path76 from "node:path";
48228
- var SEARCH_LIMIT = 100;
48229
- function handleFileBrowserSearch(msg, socket, e2ee, sessionWorktreeManager) {
48230
- void (async () => {
48231
- await yieldToEventLoop();
48232
- const q = typeof msg.q === "string" ? msg.q : "";
48233
- const sessionParentPath = path76.resolve(
48234
- sessionWorktreeManager != null ? await resolveFileBrowserSessionParent(sessionWorktreeManager, msg.sessionId) : getBridgeRoot()
48235
- );
48236
- if (!await bridgeFileIndexIsPopulated(sessionParentPath)) {
48237
- const payload2 = {
48238
- type: "file_browser_search_response",
48239
- id: msg.id,
48240
- paths: [],
48241
- indexReady: false
48242
- };
48243
- sendWsMessage(socket, e2ee ? e2ee.encryptFields(payload2, ["paths"]) : payload2);
48244
- return;
48245
- }
48246
- const results = await searchBridgeFilePathsAsync(sessionParentPath, q, SEARCH_LIMIT);
48247
- const payload = {
48248
- type: "file_browser_search_response",
48249
- id: msg.id,
48250
- paths: results,
48251
- indexReady: true
48252
- };
48253
- sendWsMessage(socket, e2ee ? e2ee.encryptFields(payload, ["paths"]) : payload);
48254
- })();
48255
- }
48256
- function triggerFileIndexBuild(sessionParentPath = getBridgeRoot()) {
48257
- setImmediate(() => {
48258
- void ensureFileIndexAsync(sessionParentPath).catch((e) => {
48259
- console.error("[file-index] Background build failed:", e);
48260
- });
48261
- });
48262
- }
48263
-
48264
- // src/code-nav/handlers/send-code-nav-response.ts
48265
- var ENCRYPTED_FIELDS = ["definition", "definitions", "references", "symbols", "confidentTarget"];
48266
- function sendCodeNavResponse(socket, e2ee, payload) {
48267
- const fieldsToEncrypt = ENCRYPTED_FIELDS.filter((field) => field in payload && payload[field] !== void 0);
48268
- sendWsMessage(
48269
- socket,
48270
- e2ee && fieldsToEncrypt.length > 0 ? e2ee.encryptFields(payload, [...fieldsToEncrypt]) : payload
48271
- );
48272
- }
48273
-
48274
- // src/code-nav/handlers/handle-definition-op.ts
48275
- async function handleDefinitionOp(ctx) {
48276
- const definition = await queryDefinitionAt(ctx.sessionParentPath, ctx.reqPath, ctx.line, ctx.column);
48277
- sendCodeNavResponse(ctx.socket, ctx.e2ee, {
48278
- type: "code_nav_response",
48279
- id: ctx.msg.id,
48280
- indexReady: true,
48281
- definition
48282
- });
48283
- }
48284
-
48285
- // src/code-nav/handlers/handle-definitions-op.ts
48286
- async function handleDefinitionsOp(ctx) {
48287
- const { definitions, confidentTarget } = await queryDefinitionsNavigation(
48288
- ctx.sessionParentPath,
48289
- ctx.reqPath,
48290
- ctx.line,
48291
- ctx.column
48292
- );
48293
- sendCodeNavResponse(ctx.socket, ctx.e2ee, {
48294
- type: "code_nav_response",
48295
- id: ctx.msg.id,
48296
- indexReady: true,
48297
- definitions,
48298
- confidentTarget
48299
- });
48300
- }
48301
-
48302
- // src/code-nav/handlers/handle-references-op.ts
48303
- async function handleReferencesOp(ctx) {
48304
- const references = await queryReferencesAt(ctx.sessionParentPath, ctx.reqPath, ctx.line, ctx.column);
48305
- sendCodeNavResponse(ctx.socket, ctx.e2ee, {
48306
- type: "code_nav_response",
48307
- id: ctx.msg.id,
48308
- indexReady: true,
48309
- references
48310
- });
48311
- }
48312
-
48313
- // src/code-nav/handlers/handle-symbols-op.ts
48314
- async function handleSymbolsOp(ctx) {
48315
- const symbols = await querySymbolsInFile(ctx.sessionParentPath, ctx.reqPath);
48316
- sendCodeNavResponse(ctx.socket, ctx.e2ee, {
48317
- type: "code_nav_response",
48318
- id: ctx.msg.id,
48319
- indexReady: true,
48320
- symbols
48321
- });
48322
- }
48323
-
48324
- // src/code-nav/handlers/code-nav-op-context.ts
48325
- function normalizeCodeNavOp(op) {
48326
- if (op === "references" || op === "symbols" || op === "definitions") return op;
48327
- return "definition";
48328
- }
48329
-
48330
- // src/code-nav/handlers/resolve-code-nav-parent.ts
48331
- async function resolveCodeNavParentPath(sessionWorktreeManager, sessionId) {
48332
- const parent = sessionWorktreeManager != null ? await resolveFileBrowserSessionParent(sessionWorktreeManager, sessionId) : getBridgeRoot();
48333
- return normalizeResolvedPath(parent);
48334
- }
48335
-
48336
- // src/code-nav/handlers/prepare-code-nav-request.ts
48337
- var CODE_NAV_INDEX_READY_WAIT_MS = 75;
48338
- var CODE_NAV_INDEX_READY_POLL_MS = 15;
48339
- function delay2(ms) {
48340
- return new Promise((resolve37) => setTimeout(resolve37, ms));
48341
- }
48342
- async function waitForSymbolIndexReady(sessionParentPath, reqPath) {
48343
- const deadline = Date.now() + CODE_NAV_INDEX_READY_WAIT_MS;
48344
- do {
48345
- if (await symbolIndexFileIsReadyAsync(sessionParentPath, reqPath)) return true;
48346
- await delay2(CODE_NAV_INDEX_READY_POLL_MS);
48347
- } while (Date.now() < deadline);
48348
- return await symbolIndexFileIsReadyAsync(sessionParentPath, reqPath);
48349
- }
48350
- async function prepareCodeNavRequest(msg, socket, e2ee, sessionWorktreeManager) {
48351
- await yieldToEventLoop();
48352
- const reqPath = msg.path.replace(/^\/+/, "") || "";
48353
- if (!reqPath) {
48354
- sendCodeNavResponse(socket, e2ee, {
48355
- type: "code_nav_response",
48356
- id: msg.id,
48357
- error: "Path required"
48358
- });
48359
- return null;
48360
- }
48361
- const sessionParentPath = await resolveCodeNavParentPath(sessionWorktreeManager, msg.sessionId);
48362
- await registerSymbolIndexParentAsync(sessionParentPath);
48363
- scheduleSymbolIndexFile(sessionParentPath, reqPath);
48364
- const indexReady = await waitForSymbolIndexReady(sessionParentPath, reqPath);
48365
- if (indexReady) {
48366
- const importTargets = await listDirectImportTargetsForFileAsync(sessionParentPath, reqPath);
48367
- scheduleSymbolIndexImportNeighbors(sessionParentPath, importTargets);
48368
- }
48369
- scheduleSymbolIndexWarmup(sessionParentPath);
48370
- await yieldToEventLoop();
48371
- return {
48372
- socket,
48373
- e2ee,
48374
- msg,
48375
- reqPath,
48376
- sessionParentPath,
48377
- line: typeof msg.line === "number" ? msg.line : 1,
48378
- column: typeof msg.column === "number" ? msg.column : 0,
48379
- indexReady
48380
- };
48381
- }
48382
- function sendIndexNotReadyResponse(ctx) {
48383
- sendCodeNavResponse(ctx.socket, ctx.e2ee, {
48384
- type: "code_nav_response",
48385
- id: ctx.msg.id,
48386
- indexReady: false,
48387
- definition: null,
48388
- definitions: [],
48389
- references: [],
48390
- symbols: []
48391
- });
48392
- }
48393
- function preparedOpContext(ctx) {
48394
- return {
48395
- socket: ctx.socket,
48396
- e2ee: ctx.e2ee,
48397
- msg: { ...ctx.msg, op: normalizeCodeNavOp(ctx.msg.op) },
48398
- reqPath: ctx.reqPath,
48399
- sessionParentPath: ctx.sessionParentPath,
48400
- line: ctx.line,
48401
- column: ctx.column
48402
- };
48403
- }
48404
-
48405
- // src/code-nav/handlers/handle-code-nav-request.ts
48406
- function handleCodeNavRequest(msg, socket, e2ee, sessionWorktreeManager) {
48407
- void (async () => {
48408
- const prepared = await prepareCodeNavRequest(msg, socket, e2ee, sessionWorktreeManager);
48409
- if (prepared == null) return;
48410
- if (!prepared.indexReady) {
48411
- sendIndexNotReadyResponse(prepared);
48412
- return;
48413
- }
48414
- const ctx = preparedOpContext(prepared);
48415
- switch (ctx.msg.op) {
48416
- case "symbols":
48417
- await handleSymbolsOp(ctx);
48418
- return;
48419
- case "references":
48420
- await handleReferencesOp(ctx);
48421
- return;
48422
- case "definitions":
48423
- await handleDefinitionsOp(ctx);
48424
- return;
48425
- default:
48426
- await handleDefinitionOp(ctx);
48427
- }
48428
- })();
48429
- }
48430
-
48431
- // src/code-nav/handlers/trigger-symbol-index-build.ts
48432
- function triggerSymbolIndexBuild(parentPath) {
48433
- setImmediate(() => {
48434
- void (async () => {
48435
- const resolved = normalizeResolvedPath(parentPath);
48436
- await registerSymbolIndexParentAsync(resolved);
48437
- scheduleSymbolIndexWarmup(resolved);
48438
- })();
48439
- });
48440
- }
48190
+ // src/files/browser/handle-file-browser-list.ts
48191
+ init_list_dir();
48441
48192
 
48442
48193
  // src/git/tree/resolve-repo-abs-path.ts
48443
- import * as path77 from "node:path";
48194
+ init_cwd();
48195
+ import * as path76 from "node:path";
48444
48196
  function resolveRepoAbsPathFromBridge(repoRelPath, bridgeRoot = getBridgeRoot()) {
48445
- const bridgeResolved = path77.resolve(bridgeRoot);
48197
+ const bridgeResolved = path76.resolve(bridgeRoot);
48446
48198
  const rel = repoRelPath.trim() === "." ? "" : repoRelPath.trim().replace(/\\/g, "/");
48447
- const repoPath = rel === "" ? bridgeResolved : path77.join(bridgeResolved, rel);
48448
- const resolved = path77.resolve(repoPath);
48449
- 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) {
48450
48202
  return null;
48451
48203
  }
48452
48204
  return resolved;
@@ -48464,6 +48216,9 @@ async function resolveBranchCommit(repoAbsPath, branch) {
48464
48216
  }
48465
48217
 
48466
48218
  // src/git/tree/list-git-tree-dir.ts
48219
+ init_yield_to_event_loop();
48220
+ init_types2();
48221
+ init_sort_entries();
48467
48222
  function parseLsTreeLine(line) {
48468
48223
  const tab = line.indexOf(" ");
48469
48224
  if (tab < 0) return null;
@@ -48526,6 +48281,9 @@ async function listGitTreeDirAsync(repoAbsPath, branch, relativePath) {
48526
48281
  }
48527
48282
  }
48528
48283
 
48284
+ // src/git/tree/file/index.ts
48285
+ init_yield_to_event_loop();
48286
+
48529
48287
  // src/files/read-file/types.ts
48530
48288
  var LINE_CHUNK_SIZE = 64 * 1024;
48531
48289
  var READ_RANGE_YIELD_EVERY_BYTES = 256 * 1024;
@@ -48562,6 +48320,7 @@ function guessMimeType(filePath) {
48562
48320
  }
48563
48321
 
48564
48322
  // src/git/tree/file/git-blob-ref.ts
48323
+ init_yield_to_event_loop();
48565
48324
  async function gitBlobRef(repoAbsPath, branch, relativePath) {
48566
48325
  const commit = await resolveBranchCommit(repoAbsPath, branch);
48567
48326
  await yieldToEventLoop();
@@ -48581,6 +48340,7 @@ function isBinaryBuffer(buf) {
48581
48340
  }
48582
48341
 
48583
48342
  // src/git/tree/file/read-git-blob-text-async.ts
48343
+ init_yield_to_event_loop();
48584
48344
  import { StringDecoder } from "node:string_decoder";
48585
48345
  async function countGitBlobLinesAsync(buf) {
48586
48346
  if (buf.length === 0) return 1;
@@ -48829,6 +48589,145 @@ function sendFileBrowserMessage(socket, e2ee, payload) {
48829
48589
  sendWsMessage(socket, e2ee ? e2ee.encryptFields(payload, ["entries", "content", "totalLines", "size", "lineOffset"]) : payload);
48830
48590
  }
48831
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
+
48832
48731
  // src/files/browser/handle-file-browser-list.ts
48833
48732
  async function handleFileBrowserList(socket, e2ee, id, reqPath, sessionParentPath, gitScope) {
48834
48733
  const result = gitScope ? await listGitTreeDirAsync(gitScope.repoAbsPath, gitScope.branch, reqPath) : await listDirAsync(reqPath, sessionParentPath);
@@ -48837,38 +48736,138 @@ async function handleFileBrowserList(socket, e2ee, id, reqPath, sessionParentPat
48837
48736
  return;
48838
48737
  }
48839
48738
  sendFileBrowserMessage(socket, e2ee, { type: "file_browser_response", id, entries: result.entries });
48840
- if (!gitScope && (reqPath === "." || reqPath === "")) {
48841
- triggerFileIndexBuild(sessionParentPath);
48842
- if (sessionParentPath) triggerSymbolIndexBuild(sessionParentPath);
48739
+ if (!gitScope && sessionParentPath) {
48740
+ scheduleResolveCacheWarmupForListedEntries(sessionParentPath, reqPath, result.entries);
48843
48741
  }
48844
48742
  }
48845
48743
 
48846
- // src/files/read-file/resolve-file-path.ts
48847
- import fs50 from "node:fs";
48848
- async function resolveFilePathAsync(relativePath, sessionParentPath = getBridgeRoot()) {
48849
- const resolved = ensureUnderCwd(relativePath, sessionParentPath);
48850
- if (!resolved) return { error: "Path is outside working directory" };
48851
- let real;
48852
- try {
48853
- real = await fs50.promises.realpath(resolved);
48854
- } catch {
48855
- 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);
48856
48831
  }
48857
- try {
48858
- const stat3 = await fs50.promises.stat(real);
48859
- if (!stat3.isFile()) return { error: "Not a file" };
48860
- return real;
48861
- } catch (err) {
48862
- 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);
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;
48863
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;
48864
48865
  }
48865
48866
 
48866
48867
  // src/files/read-file/read-file-range-async.ts
48867
- import fs51 from "node:fs";
48868
- import { StringDecoder as StringDecoder2 } from "node:string_decoder";
48869
- async function readFileRangeAsync(filePath, startLine, endLine, lineOffsetIn, lineChunkSize = LINE_CHUNK_SIZE) {
48870
- const fileSize = (await fs51.promises.stat(filePath)).size;
48871
- 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");
48872
48871
  const bufSize = 64 * 1024;
48873
48872
  const buf = Buffer.alloc(bufSize);
48874
48873
  const decoder = new StringDecoder2("utf8");
@@ -48876,9 +48875,8 @@ async function readFileRangeAsync(filePath, startLine, endLine, lineOffsetIn, li
48876
48875
  const resultLines = [];
48877
48876
  let partial2 = "";
48878
48877
  let done = false;
48879
- let skipLine0Chars = typeof lineOffsetIn === "number" ? lineOffsetIn : 0;
48880
- let line0CharsReturned = 0;
48881
- let line0Accum = "";
48878
+ const trackLineZero = shouldTrackLineZero(startLine, lineOffsetIn);
48879
+ const lineZeroState = createLineZeroStreamState(lineOffsetIn);
48882
48880
  let bytesSinceYield = 0;
48883
48881
  try {
48884
48882
  let position = 0;
@@ -48895,130 +48893,70 @@ async function readFileRangeAsync(filePath, startLine, endLine, lineOffsetIn, li
48895
48893
  partial2 = "";
48896
48894
  let lineStart = 0;
48897
48895
  for (let i = 0; i < text.length; i++) {
48898
- if (text[i] === "\n") {
48899
- const lineContent = (() => {
48900
- let lineEnd = i;
48901
- if (lineEnd > lineStart && text[lineEnd - 1] === "\r") lineEnd--;
48902
- return text.slice(lineStart, lineEnd);
48903
- })();
48904
- if (currentLine === 0 && (startLine === 0 || lineOffsetIn !== void 0)) {
48905
- line0Accum += lineContent;
48906
- const totalLine0 = line0Accum.length;
48907
- if (skipLine0Chars > 0) {
48908
- if (totalLine0 <= skipLine0Chars) {
48909
- skipLine0Chars -= totalLine0;
48910
- line0Accum = "";
48911
- currentLine++;
48912
- lineStart = i + 1;
48913
- if (currentLine > endLine) {
48914
- done = true;
48915
- break;
48916
- }
48917
- continue;
48918
- }
48919
- const from = skipLine0Chars;
48920
- const take = Math.min(lineChunkSize, totalLine0 - from);
48921
- resultLines.push(line0Accum.slice(from, from + take));
48922
- line0CharsReturned += take;
48923
- if (from + take < totalLine0) {
48924
- return {
48925
- content: resultLines.join("\n"),
48926
- size: fileSize,
48927
- lineOffset: lineOffsetIn + line0CharsReturned,
48928
- totalLines: 1
48929
- };
48930
- }
48931
- line0Accum = "";
48932
- skipLine0Chars = 0;
48933
- line0CharsReturned = 0;
48934
- } else if (totalLine0 > lineChunkSize) {
48935
- resultLines.push(line0Accum.slice(0, lineChunkSize));
48936
- return {
48937
- content: resultLines.join("\n"),
48938
- size: fileSize,
48939
- lineOffset: lineChunkSize,
48940
- totalLines: 1
48941
- };
48942
- } else {
48943
- resultLines.push(line0Accum);
48944
- line0Accum = "";
48945
- }
48946
- } else if (currentLine >= startLine && currentLine <= endLine) {
48947
- 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;
48948
48912
  }
48913
+ if (lineZeroResult !== "continue") return lineZeroResult;
48949
48914
  currentLine++;
48950
48915
  lineStart = i + 1;
48951
48916
  if (currentLine > endLine) {
48952
48917
  done = true;
48953
48918
  break;
48954
48919
  }
48920
+ continue;
48955
48921
  }
48956
- }
48957
- if (!done) {
48958
- const lineContent = text.slice(lineStart);
48959
- if (currentLine === 0 && (startLine === 0 || lineOffsetIn !== void 0)) {
48960
- line0Accum += lineContent;
48961
- const totalLine0 = line0Accum.length;
48962
- if (skipLine0Chars > 0) {
48963
- if (totalLine0 <= skipLine0Chars) {
48964
- skipLine0Chars -= totalLine0;
48965
- line0Accum = "";
48966
- } else {
48967
- const from = skipLine0Chars;
48968
- const take = Math.min(lineChunkSize, totalLine0 - from);
48969
- resultLines.push(line0Accum.slice(from, from + take));
48970
- return {
48971
- content: resultLines.join("\n"),
48972
- size: fileSize,
48973
- lineOffset: (lineOffsetIn ?? 0) + take,
48974
- totalLines: 1
48975
- };
48976
- }
48977
- } else if (totalLine0 > lineChunkSize) {
48978
- resultLines.push(line0Accum.slice(0, lineChunkSize));
48979
- return {
48980
- content: resultLines.join("\n"),
48981
- size: fileSize,
48982
- lineOffset: lineChunkSize,
48983
- totalLines: 1
48984
- };
48985
- }
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;
48986
48930
  }
48987
- 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;
48988
48946
  }
48989
48947
  }
48990
48948
  if (!done) {
48991
48949
  const tail = partial2 + decoder.end();
48992
- if (currentLine === 0 && (startLine === 0 || lineOffsetIn !== void 0) && tail.length > 0) {
48993
- line0Accum += tail.endsWith("\r") ? tail.slice(0, -1) : tail;
48994
- const totalLine0 = line0Accum.length;
48995
- if (skipLine0Chars > 0) {
48996
- if (totalLine0 <= skipLine0Chars) {
48997
- return { content: resultLines.join("\n"), size: fileSize };
48998
- }
48999
- const from = skipLine0Chars;
49000
- const take = Math.min(lineChunkSize, totalLine0 - from);
49001
- resultLines.push(line0Accum.slice(from, from + take));
49002
- line0CharsReturned += take;
49003
- if (from + take < totalLine0) {
49004
- return {
49005
- content: resultLines.join("\n"),
49006
- size: fileSize,
49007
- lineOffset: (lineOffsetIn ?? 0) + line0CharsReturned,
49008
- totalLines: 1
49009
- };
49010
- }
49011
- } else if (totalLine0 > lineChunkSize) {
49012
- resultLines.push(line0Accum.slice(0, lineChunkSize));
49013
- return {
49014
- content: resultLines.join("\n"),
49015
- size: fileSize,
49016
- lineOffset: lineChunkSize,
49017
- totalLines: 1
49018
- };
49019
- } else {
49020
- resultLines.push(line0Accum);
49021
- }
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;
49022
48960
  } else if (tail.length > 0 && currentLine >= startLine && currentLine <= endLine) {
49023
48961
  resultLines.push(tail.endsWith("\r") ? tail.slice(0, -1) : tail);
49024
48962
  }
@@ -49029,12 +48967,48 @@ async function readFileRangeAsync(filePath, startLine, endLine, lineOffsetIn, li
49029
48967
  }
49030
48968
  }
49031
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
+
49032
49005
  // src/files/read-file/read-file-buffer-full-async.ts
49033
- import fs52 from "node:fs";
49006
+ init_yield_to_event_loop();
49007
+ import fs54 from "node:fs";
49034
49008
  var READ_CHUNK_BYTES = 256 * 1024;
49035
49009
  async function readFileBufferFullAsync(filePath) {
49036
- const stat3 = await fs52.promises.stat(filePath);
49037
- 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");
49038
49012
  const chunks = [];
49039
49013
  let position = 0;
49040
49014
  let bytesSinceYield = 0;
@@ -49076,12 +49050,23 @@ async function readFileBinaryFullAsync(filePath) {
49076
49050
  }
49077
49051
 
49078
49052
  // src/files/read-file/index.ts
49079
- async function readFileAsync(relativePath, startLine, endLine, lineOffset, lineChunkSize = LINE_CHUNK_SIZE, sessionParentPath = getBridgeRoot(), encoding = "utf8") {
49080
- 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
+ }
49081
49057
  try {
49082
- const result = await resolveFilePathAsync(relativePath, sessionParentPath);
49083
- if (typeof result === "object") return result;
49084
- 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
+ }
49085
49070
  const hasRange = typeof startLine === "number" && typeof endLine === "number";
49086
49071
  if (encoding === "base64") {
49087
49072
  if (hasRange) return { error: "base64 encoding requires a full file read (no line range)" };
@@ -49089,7 +49074,26 @@ async function readFileAsync(relativePath, startLine, endLine, lineOffset, lineC
49089
49074
  return { ...read2, resolvedPath };
49090
49075
  }
49091
49076
  if (hasRange) {
49092
- 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;
49093
49097
  }
49094
49098
  const read = await readFileFullAsync(resolvedPath);
49095
49099
  return { ...read, resolvedPath };
@@ -49098,6 +49102,17 @@ async function readFileAsync(relativePath, startLine, endLine, lineOffset, lineC
49098
49102
  }
49099
49103
  }
49100
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
+
49101
49116
  // src/files/browser/handle-file-browser-read.ts
49102
49117
  async function handleFileBrowserRead(socket, e2ee, msg, reqPath, sessionParentPath, gitScope) {
49103
49118
  const startLine = typeof msg.startLine === "number" ? msg.startLine : void 0;
@@ -49114,14 +49129,17 @@ async function handleFileBrowserRead(socket, e2ee, msg, reqPath, sessionParentPa
49114
49129
  lineOffset,
49115
49130
  lineChunkSize,
49116
49131
  encoding
49117
- ) : await readFileAsync(
49118
- reqPath,
49119
- startLine,
49120
- endLine,
49121
- lineOffset,
49122
- lineChunkSize,
49123
- sessionParentPath,
49124
- 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
+ )
49125
49143
  );
49126
49144
  if ("error" in result) {
49127
49145
  sendWsMessage(socket, { type: "file_browser_response", id: msg.id, error: result.error });
@@ -49138,6 +49156,10 @@ async function handleFileBrowserRead(socket, e2ee, msg, reqPath, sessionParentPa
49138
49156
  if (result.mimeType != null) payload.mimeType = result.mimeType;
49139
49157
  if (result.resolvedPath != null) payload.resolvedPath = result.resolvedPath;
49140
49158
  sendFileBrowserMessage(socket, e2ee, payload);
49159
+ if (!gitScope) {
49160
+ const parentDir = path79.dirname(reqPath.replace(/^\/+/, "") || ".");
49161
+ scheduleDirectoryResolveCacheWarmup(sessionParentPath ?? getBridgeRoot(), parentDir === "" ? "." : parentDir);
49162
+ }
49141
49163
  }
49142
49164
 
49143
49165
  // src/files/browser/resolve-git-branch-scope.ts
@@ -49151,22 +49173,67 @@ function resolveGitBranchScope(msg) {
49151
49173
 
49152
49174
  // src/files/browser/index.ts
49153
49175
  function handleFileBrowserRequest(msg, socket, e2ee, sessionWorktreeManager) {
49176
+ beginFileBrowserRequest();
49154
49177
  void (async () => {
49155
- const reqPath = msg.path.replace(/^\/+/, "") || ".";
49156
- const op = msg.op === "read" ? "read" : "list";
49157
- const sessionParentPath = sessionWorktreeManager != null ? await resolveFileBrowserSessionParent(sessionWorktreeManager, msg.sessionId) : void 0;
49158
- const gitScope = resolveGitBranchScope(msg);
49159
- if (msg.source === "git_branch" && typeof msg.repoRelPath === "string" && typeof msg.branch === "string" && msg.branch.trim().length > 0 && !gitScope) {
49160
- sendWsMessage(socket, { type: "file_browser_response", id: msg.id, error: "Invalid repository path" });
49161
- 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();
49162
49193
  }
49163
- if (op === "list") {
49164
- await handleFileBrowserList(socket, e2ee, msg.id, reqPath, sessionParentPath, gitScope);
49165
- } else {
49166
- 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;
49167
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);
49168
49228
  })();
49169
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
+ }
49170
49237
 
49171
49238
  // src/routing/handlers/file-browser-messages.ts
49172
49239
  function handleFileBrowserRequestMessage(msg, { getWs, e2ee, sessionWorktreeManager }) {
@@ -49187,6 +49254,235 @@ function handleFileBrowserSearchMessage(msg, { getWs, e2ee, sessionWorktreeManag
49187
49254
  );
49188
49255
  }
49189
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
+
49190
49486
  // src/routing/handlers/code-nav-messages.ts
49191
49487
  function handleFileBrowserCodeNavMessage(msg, { getWs, e2ee, sessionWorktreeManager }) {
49192
49488
  if (typeof msg.id !== "string" || typeof msg.path !== "string") return;
@@ -49209,6 +49505,7 @@ function handleFileBrowserCodeNavMessage(msg, { getWs, e2ee, sessionWorktreeMana
49209
49505
  }
49210
49506
 
49211
49507
  // src/routing/handlers/skill-layout-request.ts
49508
+ init_cwd();
49212
49509
  function handleSkillLayoutRequest(msg, deps) {
49213
49510
  const id = typeof msg.id === "string" ? msg.id : "";
49214
49511
  void (async () => {
@@ -49220,6 +49517,9 @@ function handleSkillLayoutRequest(msg, deps) {
49220
49517
  })();
49221
49518
  }
49222
49519
 
49520
+ // src/routing/handlers/install-skills.ts
49521
+ init_cwd();
49522
+
49223
49523
  // src/skills/install/is-valid-install-item.ts
49224
49524
  function isValidRemoteSkillInstallItem(item) {
49225
49525
  if (item === null || typeof item !== "object") return false;
@@ -49228,8 +49528,9 @@ function isValidRemoteSkillInstallItem(item) {
49228
49528
  }
49229
49529
 
49230
49530
  // src/skills/install/install-remote-skills-async.ts
49231
- import fs53 from "node:fs";
49232
- import path78 from "node:path";
49531
+ init_yield_to_event_loop();
49532
+ import fs56 from "node:fs";
49533
+ import path81 from "node:path";
49233
49534
 
49234
49535
  // src/skills/install/constants.ts
49235
49536
  var INSTALL_SKILLS_YIELD_EVERY = 16;
@@ -49240,12 +49541,12 @@ async function writeInstallFileAsync(skillDir, f, filesWritten) {
49240
49541
  if (++filesWritten.count % INSTALL_SKILLS_YIELD_EVERY === 0) {
49241
49542
  await yieldToEventLoop();
49242
49543
  }
49243
- const dest = path78.join(skillDir, f.path);
49244
- 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 });
49245
49546
  if (f.text !== void 0) {
49246
- await fs53.promises.writeFile(dest, f.text, "utf8");
49547
+ await fs56.promises.writeFile(dest, f.text, "utf8");
49247
49548
  } else if (f.base64) {
49248
- await fs53.promises.writeFile(dest, Buffer.from(f.base64, "base64"));
49549
+ await fs56.promises.writeFile(dest, Buffer.from(f.base64, "base64"));
49249
49550
  }
49250
49551
  }
49251
49552
  async function installRemoteSkillsAsync(cwd, targetDir, items) {
@@ -49257,7 +49558,7 @@ async function installRemoteSkillsAsync(cwd, targetDir, items) {
49257
49558
  try {
49258
49559
  for (const item of items) {
49259
49560
  if (!isValidRemoteSkillInstallItem(item)) continue;
49260
- const skillDir = path78.join(cwd, targetDir, item.skillName);
49561
+ const skillDir = path81.join(cwd, targetDir, item.skillName);
49261
49562
  for (const f of item.files) {
49262
49563
  await writeInstallFileAsync(skillDir, f, filesWritten);
49263
49564
  }
@@ -49539,7 +49840,8 @@ var handleSessionDiscardedMessage = (msg, deps) => {
49539
49840
  };
49540
49841
 
49541
49842
  // src/routing/handlers/revert-turn-snapshot.ts
49542
- import * as fs54 from "node:fs";
49843
+ init_cwd();
49844
+ import * as fs57 from "node:fs";
49543
49845
  var handleRevertTurnSnapshotMessage = (msg, deps) => {
49544
49846
  const id = typeof msg.id === "string" ? msg.id : "";
49545
49847
  const sessionId = typeof msg.sessionId === "string" ? msg.sessionId : "";
@@ -49552,7 +49854,7 @@ var handleRevertTurnSnapshotMessage = (msg, deps) => {
49552
49854
  const agentBase = sessionWorktreeManager.getSessionWorktreeRootForSession(sessionId) ?? getBridgeRoot();
49553
49855
  const file2 = snapshotFilePath(agentBase, turnId);
49554
49856
  try {
49555
- await fs54.promises.access(file2, fs54.constants.F_OK);
49857
+ await fs57.promises.access(file2, fs57.constants.F_OK);
49556
49858
  } catch {
49557
49859
  sendWsMessage(s, {
49558
49860
  type: "revert_turn_snapshot_result",
@@ -49637,7 +49939,9 @@ var handleDeploySessionToPreviewMessage = (msg, deps) => {
49637
49939
  };
49638
49940
 
49639
49941
  // src/git/bridge-git-context.ts
49640
- import * as path79 from "node:path";
49942
+ init_cwd();
49943
+ init_yield_to_event_loop();
49944
+ import * as path82 from "node:path";
49641
49945
 
49642
49946
  // src/git/branches/get-current-branch.ts
49643
49947
  async function getCurrentBranch(repoPath) {
@@ -49687,12 +49991,12 @@ async function listRepoBranchRefs(repoPath) {
49687
49991
  // src/git/bridge-git-context.ts
49688
49992
  function folderNameForRelPath(relPath, bridgeRoot) {
49689
49993
  if (relPath === "." || relPath === "") {
49690
- return path79.basename(path79.resolve(bridgeRoot)) || "repo";
49994
+ return path82.basename(path82.resolve(bridgeRoot)) || "repo";
49691
49995
  }
49692
- return path79.basename(relPath) || relPath;
49996
+ return path82.basename(relPath) || relPath;
49693
49997
  }
49694
49998
  async function discoverGitReposForBridgeContext(bridgeRoot) {
49695
- const root = path79.resolve(bridgeRoot);
49999
+ const root = path82.resolve(bridgeRoot);
49696
50000
  if (await isGitRepoDirectory(root)) {
49697
50001
  const remoteUrl = await getRemoteOriginUrl(root);
49698
50002
  return [{ absolutePath: root, remoteUrl }];
@@ -49700,19 +50004,19 @@ async function discoverGitReposForBridgeContext(bridgeRoot) {
49700
50004
  const [deep, shallow] = await Promise.all([discoverGitReposUnderRoot(root), discoverGitRepos(root)]);
49701
50005
  const byPath = /* @__PURE__ */ new Map();
49702
50006
  for (const repo of [...deep, ...shallow]) {
49703
- byPath.set(path79.resolve(repo.absolutePath), repo);
50007
+ byPath.set(path82.resolve(repo.absolutePath), repo);
49704
50008
  }
49705
50009
  return [...byPath.values()];
49706
50010
  }
49707
50011
  async function getBridgeGitContext(bridgeRoot = getBridgeRoot()) {
49708
- const bridgeResolved = path79.resolve(bridgeRoot);
50012
+ const bridgeResolved = path82.resolve(bridgeRoot);
49709
50013
  const repos = await discoverGitReposForBridgeContext(bridgeResolved);
49710
50014
  const rows = [];
49711
50015
  for (let i = 0; i < repos.length; i++) {
49712
50016
  if (i > 0) await yieldToEventLoop();
49713
50017
  const repo = repos[i];
49714
- let rel = path79.relative(bridgeResolved, repo.absolutePath);
49715
- if (rel.startsWith("..") || path79.isAbsolute(rel)) continue;
50018
+ let rel = path82.relative(bridgeResolved, repo.absolutePath);
50019
+ if (rel.startsWith("..") || path82.isAbsolute(rel)) continue;
49716
50020
  const relPath = rel === "" ? "." : rel.replace(/\\/g, "/");
49717
50021
  const currentBranch = await getCurrentBranch(repo.absolutePath);
49718
50022
  const remoteUrl = repo.remoteUrl.trim() || null;
@@ -49727,11 +50031,11 @@ async function getBridgeGitContext(bridgeRoot = getBridgeRoot()) {
49727
50031
  return rows;
49728
50032
  }
49729
50033
  async function listRepoBranchesForBridge(repoRelPath, bridgeRoot = getBridgeRoot()) {
49730
- const bridgeResolved = path79.resolve(bridgeRoot);
50034
+ const bridgeResolved = path82.resolve(bridgeRoot);
49731
50035
  const rel = repoRelPath.trim() === "." ? "" : repoRelPath.trim().replace(/\\/g, "/");
49732
- const repoPath = rel === "" ? bridgeResolved : path79.join(bridgeResolved, rel);
49733
- const resolved = path79.resolve(repoPath);
49734
- 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) {
49735
50039
  return [];
49736
50040
  }
49737
50041
  return listRepoBranchRefs(resolved);
@@ -50407,9 +50711,9 @@ async function runCliAction(program2, opts) {
50407
50711
  const firehoseServerUrl = opts.firehoseUrl ?? opts.proxyUrl ?? process.env.BUILDAUTOMATON_FIREHOSE_URL ?? process.env.BUILDAUTOMATON_PROXY_URL ?? DEFAULT_FIREHOSE_URL;
50408
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);
50409
50713
  if (bridgeRootOpt) {
50410
- const resolvedBridgeRoot = path80.resolve(process.cwd(), bridgeRootOpt);
50714
+ const resolvedBridgeRoot = path83.resolve(process.cwd(), bridgeRootOpt);
50411
50715
  try {
50412
- const st = fs55.statSync(resolvedBridgeRoot);
50716
+ const st = fs58.statSync(resolvedBridgeRoot);
50413
50717
  if (!st.isDirectory()) {
50414
50718
  console.error(`Bridge root is not a directory: ${resolvedBridgeRoot}`);
50415
50719
  process.exit(1);
@@ -50429,7 +50733,7 @@ async function runCliAction(program2, opts) {
50429
50733
  );
50430
50734
  let worktreesRootPath;
50431
50735
  if (opts.worktreesRoot && opts.worktreesRoot.trim()) {
50432
- worktreesRootPath = path80.resolve(opts.worktreesRoot.trim());
50736
+ worktreesRootPath = path83.resolve(opts.worktreesRoot.trim());
50433
50737
  }
50434
50738
  const e2eCertificates = opts.e2eeCertificatesDir?.trim() ? await loadOrCreateE2eCertificates(opts.e2eeCertificatesDir.trim()) : void 0;
50435
50739
  if (e2eCertificates) {