@buildautomaton/cli 0.1.63 → 0.1.64

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -3653,6 +3653,47 @@ var require_websocket_server = __commonJS({
3653
3653
  }
3654
3654
  });
3655
3655
 
3656
+ // src/paths/normalize-resolved-path.ts
3657
+ import fs from "node:fs";
3658
+ import path from "node:path";
3659
+ function normalizeResolvedPath(resolved) {
3660
+ const abs = path.resolve(resolved);
3661
+ try {
3662
+ return fs.realpathSync.native(abs);
3663
+ } catch {
3664
+ return abs;
3665
+ }
3666
+ }
3667
+ var init_normalize_resolved_path = __esm({
3668
+ "src/paths/normalize-resolved-path.ts"() {
3669
+ "use strict";
3670
+ }
3671
+ });
3672
+
3673
+ // src/files/cwd/bridge-root.ts
3674
+ function getBridgeRoot() {
3675
+ if (bridgeRootPath == null) {
3676
+ bridgeRootPath = normalizeResolvedPath(process.cwd());
3677
+ }
3678
+ return bridgeRootPath;
3679
+ }
3680
+ var bridgeRootPath;
3681
+ var init_bridge_root = __esm({
3682
+ "src/files/cwd/bridge-root.ts"() {
3683
+ "use strict";
3684
+ init_normalize_resolved_path();
3685
+ bridgeRootPath = null;
3686
+ }
3687
+ });
3688
+
3689
+ // src/files/cwd/index.ts
3690
+ var init_cwd = __esm({
3691
+ "src/files/cwd/index.ts"() {
3692
+ "use strict";
3693
+ init_bridge_root();
3694
+ }
3695
+ });
3696
+
3656
3697
  // ../../node_modules/.pnpm/tree-kill@1.2.2/node_modules/tree-kill/index.js
3657
3698
  var require_tree_kill = __commonJS({
3658
3699
  "../../node_modules/.pnpm/tree-kill@1.2.2/node_modules/tree-kill/index.js"(exports, module) {
@@ -4175,8 +4216,8 @@ var init_parseUtil = __esm({
4175
4216
  init_errors();
4176
4217
  init_en();
4177
4218
  makeIssue = (params) => {
4178
- const { data, path: path79, errorMaps, issueData } = params;
4179
- const fullPath = [...path79, ...issueData.path || []];
4219
+ const { data, path: path82, errorMaps, issueData } = params;
4220
+ const fullPath = [...path82, ...issueData.path || []];
4180
4221
  const fullIssue = {
4181
4222
  ...issueData,
4182
4223
  path: fullPath
@@ -4484,11 +4525,11 @@ var init_types = __esm({
4484
4525
  init_parseUtil();
4485
4526
  init_util();
4486
4527
  ParseInputLazyPath = class {
4487
- constructor(parent, value, path79, key) {
4528
+ constructor(parent, value, path82, key) {
4488
4529
  this._cachedPath = [];
4489
4530
  this.parent = parent;
4490
4531
  this.data = value;
4491
- this._path = path79;
4532
+ this._path = path82;
4492
4533
  this._key = key;
4493
4534
  }
4494
4535
  get path() {
@@ -8103,10 +8144,10 @@ function assignProp(target, prop, value) {
8103
8144
  configurable: true
8104
8145
  });
8105
8146
  }
8106
- function getElementAtPath(obj, path79) {
8107
- if (!path79)
8147
+ function getElementAtPath(obj, path82) {
8148
+ if (!path82)
8108
8149
  return obj;
8109
- return path79.reduce((acc, key) => acc?.[key], obj);
8150
+ return path82.reduce((acc, key) => acc?.[key], obj);
8110
8151
  }
8111
8152
  function promiseAllObject(promisesObj) {
8112
8153
  const keys = Object.keys(promisesObj);
@@ -8355,11 +8396,11 @@ function aborted(x, startIndex = 0) {
8355
8396
  }
8356
8397
  return false;
8357
8398
  }
8358
- function prefixIssues(path79, issues) {
8399
+ function prefixIssues(path82, issues) {
8359
8400
  return issues.map((iss) => {
8360
8401
  var _a2;
8361
8402
  (_a2 = iss).path ?? (_a2.path = []);
8362
- iss.path.unshift(path79);
8403
+ iss.path.unshift(path82);
8363
8404
  return iss;
8364
8405
  });
8365
8406
  }
@@ -8548,7 +8589,7 @@ function treeifyError(error40, _mapper) {
8548
8589
  return issue2.message;
8549
8590
  };
8550
8591
  const result = { errors: [] };
8551
- const processError = (error41, path79 = []) => {
8592
+ const processError = (error41, path82 = []) => {
8552
8593
  var _a2, _b;
8553
8594
  for (const issue2 of error41.issues) {
8554
8595
  if (issue2.code === "invalid_union" && issue2.errors.length) {
@@ -8558,7 +8599,7 @@ function treeifyError(error40, _mapper) {
8558
8599
  } else if (issue2.code === "invalid_element") {
8559
8600
  processError({ issues: issue2.issues }, issue2.path);
8560
8601
  } else {
8561
- const fullpath = [...path79, ...issue2.path];
8602
+ const fullpath = [...path82, ...issue2.path];
8562
8603
  if (fullpath.length === 0) {
8563
8604
  result.errors.push(mapper(issue2));
8564
8605
  continue;
@@ -8588,9 +8629,9 @@ function treeifyError(error40, _mapper) {
8588
8629
  processError(error40);
8589
8630
  return result;
8590
8631
  }
8591
- function toDotPath(path79) {
8632
+ function toDotPath(path82) {
8592
8633
  const segs = [];
8593
- for (const seg of path79) {
8634
+ for (const seg of path82) {
8594
8635
  if (typeof seg === "number")
8595
8636
  segs.push(`[${seg}]`);
8596
8637
  else if (typeof seg === "symbol")
@@ -21299,6 +21340,16 @@ var init_acp = __esm({
21299
21340
  }
21300
21341
  });
21301
21342
 
21343
+ // src/runtime/yield-to-event-loop.ts
21344
+ function yieldToEventLoop() {
21345
+ return new Promise((resolve35) => setImmediate(resolve35));
21346
+ }
21347
+ var init_yield_to_event_loop = __esm({
21348
+ "src/runtime/yield-to-event-loop.ts"() {
21349
+ "use strict";
21350
+ }
21351
+ });
21352
+
21302
21353
  // ../../node_modules/.pnpm/ignore@7.0.5/node_modules/ignore/index.js
21303
21354
  var require_ignore = __commonJS({
21304
21355
  "../../node_modules/.pnpm/ignore@7.0.5/node_modules/ignore/index.js"(exports, module) {
@@ -21596,7 +21647,7 @@ var require_ignore = __commonJS({
21596
21647
  // path matching.
21597
21648
  // - check `string` either `MODE_IGNORE` or `MODE_CHECK_IGNORE`
21598
21649
  // @returns {TestResult} true if a file is ignored
21599
- test(path79, checkUnignored, mode) {
21650
+ test(path82, checkUnignored, mode) {
21600
21651
  let ignored = false;
21601
21652
  let unignored = false;
21602
21653
  let matchedRule;
@@ -21605,7 +21656,7 @@ var require_ignore = __commonJS({
21605
21656
  if (unignored === negative && ignored !== unignored || negative && !ignored && !unignored && !checkUnignored) {
21606
21657
  return;
21607
21658
  }
21608
- const matched = rule[mode].test(path79);
21659
+ const matched = rule[mode].test(path82);
21609
21660
  if (!matched) {
21610
21661
  return;
21611
21662
  }
@@ -21626,17 +21677,17 @@ var require_ignore = __commonJS({
21626
21677
  var throwError = (message, Ctor) => {
21627
21678
  throw new Ctor(message);
21628
21679
  };
21629
- var checkPath = (path79, originalPath, doThrow) => {
21630
- if (!isString(path79)) {
21680
+ var checkPath = (path82, originalPath, doThrow) => {
21681
+ if (!isString(path82)) {
21631
21682
  return doThrow(
21632
21683
  `path must be a string, but got \`${originalPath}\``,
21633
21684
  TypeError
21634
21685
  );
21635
21686
  }
21636
- if (!path79) {
21687
+ if (!path82) {
21637
21688
  return doThrow(`path must not be empty`, TypeError);
21638
21689
  }
21639
- if (checkPath.isNotRelative(path79)) {
21690
+ if (checkPath.isNotRelative(path82)) {
21640
21691
  const r = "`path.relative()`d";
21641
21692
  return doThrow(
21642
21693
  `path should be a ${r} string, but got "${originalPath}"`,
@@ -21645,7 +21696,7 @@ var require_ignore = __commonJS({
21645
21696
  }
21646
21697
  return true;
21647
21698
  };
21648
- var isNotRelative = (path79) => REGEX_TEST_INVALID_PATH.test(path79);
21699
+ var isNotRelative = (path82) => REGEX_TEST_INVALID_PATH.test(path82);
21649
21700
  checkPath.isNotRelative = isNotRelative;
21650
21701
  checkPath.convert = (p) => p;
21651
21702
  var Ignore = class {
@@ -21675,19 +21726,19 @@ var require_ignore = __commonJS({
21675
21726
  }
21676
21727
  // @returns {TestResult}
21677
21728
  _test(originalPath, cache2, checkUnignored, slices) {
21678
- const path79 = originalPath && checkPath.convert(originalPath);
21729
+ const path82 = originalPath && checkPath.convert(originalPath);
21679
21730
  checkPath(
21680
- path79,
21731
+ path82,
21681
21732
  originalPath,
21682
21733
  this._strictPathCheck ? throwError : RETURN_FALSE
21683
21734
  );
21684
- return this._t(path79, cache2, checkUnignored, slices);
21735
+ return this._t(path82, cache2, checkUnignored, slices);
21685
21736
  }
21686
- checkIgnore(path79) {
21687
- if (!REGEX_TEST_TRAILING_SLASH.test(path79)) {
21688
- return this.test(path79);
21737
+ checkIgnore(path82) {
21738
+ if (!REGEX_TEST_TRAILING_SLASH.test(path82)) {
21739
+ return this.test(path82);
21689
21740
  }
21690
- const slices = path79.split(SLASH).filter(Boolean);
21741
+ const slices = path82.split(SLASH).filter(Boolean);
21691
21742
  slices.pop();
21692
21743
  if (slices.length) {
21693
21744
  const parent = this._t(
@@ -21700,18 +21751,18 @@ var require_ignore = __commonJS({
21700
21751
  return parent;
21701
21752
  }
21702
21753
  }
21703
- return this._rules.test(path79, false, MODE_CHECK_IGNORE);
21754
+ return this._rules.test(path82, false, MODE_CHECK_IGNORE);
21704
21755
  }
21705
- _t(path79, cache2, checkUnignored, slices) {
21706
- if (path79 in cache2) {
21707
- return cache2[path79];
21756
+ _t(path82, cache2, checkUnignored, slices) {
21757
+ if (path82 in cache2) {
21758
+ return cache2[path82];
21708
21759
  }
21709
21760
  if (!slices) {
21710
- slices = path79.split(SLASH).filter(Boolean);
21761
+ slices = path82.split(SLASH).filter(Boolean);
21711
21762
  }
21712
21763
  slices.pop();
21713
21764
  if (!slices.length) {
21714
- return cache2[path79] = this._rules.test(path79, checkUnignored, MODE_IGNORE);
21765
+ return cache2[path82] = this._rules.test(path82, checkUnignored, MODE_IGNORE);
21715
21766
  }
21716
21767
  const parent = this._t(
21717
21768
  slices.join(SLASH) + SLASH,
@@ -21719,29 +21770,29 @@ var require_ignore = __commonJS({
21719
21770
  checkUnignored,
21720
21771
  slices
21721
21772
  );
21722
- return cache2[path79] = parent.ignored ? parent : this._rules.test(path79, checkUnignored, MODE_IGNORE);
21773
+ return cache2[path82] = parent.ignored ? parent : this._rules.test(path82, checkUnignored, MODE_IGNORE);
21723
21774
  }
21724
- ignores(path79) {
21725
- return this._test(path79, this._ignoreCache, false).ignored;
21775
+ ignores(path82) {
21776
+ return this._test(path82, this._ignoreCache, false).ignored;
21726
21777
  }
21727
21778
  createFilter() {
21728
- return (path79) => !this.ignores(path79);
21779
+ return (path82) => !this.ignores(path82);
21729
21780
  }
21730
21781
  filter(paths) {
21731
21782
  return makeArray(paths).filter(this.createFilter());
21732
21783
  }
21733
21784
  // @returns {TestResult}
21734
- test(path79) {
21735
- return this._test(path79, this._testCache, true);
21785
+ test(path82) {
21786
+ return this._test(path82, this._testCache, true);
21736
21787
  }
21737
21788
  };
21738
21789
  var factory = (options) => new Ignore(options);
21739
- var isPathValid = (path79) => checkPath(path79 && checkPath.convert(path79), path79, RETURN_FALSE);
21790
+ var isPathValid = (path82) => checkPath(path82 && checkPath.convert(path82), path82, RETURN_FALSE);
21740
21791
  var setupWindows = () => {
21741
21792
  const makePosix = (str) => /^\\\\\?\\/.test(str) || /["<>|\u0000-\u001F]+/u.test(str) ? str : str.replace(/\\/g, "/");
21742
21793
  checkPath.convert = makePosix;
21743
21794
  const REGEX_TEST_WINDOWS_PATH_ABSOLUTE = /^[a-z]:\//i;
21744
- checkPath.isNotRelative = (path79) => REGEX_TEST_WINDOWS_PATH_ABSOLUTE.test(path79) || isNotRelative(path79);
21795
+ checkPath.isNotRelative = (path82) => REGEX_TEST_WINDOWS_PATH_ABSOLUTE.test(path82) || isNotRelative(path82);
21745
21796
  };
21746
21797
  if (
21747
21798
  // Detect `process` so that it can run in browsers.
@@ -22530,10 +22581,10 @@ var require_src2 = __commonJS({
22530
22581
  var fs_1 = __require("fs");
22531
22582
  var debug_1 = __importDefault(require_src());
22532
22583
  var log2 = debug_1.default("@kwsites/file-exists");
22533
- function check2(path79, isFile, isDirectory) {
22534
- log2(`checking %s`, path79);
22584
+ function check2(path82, isFile, isDirectory) {
22585
+ log2(`checking %s`, path82);
22535
22586
  try {
22536
- const stat2 = fs_1.statSync(path79);
22587
+ const stat2 = fs_1.statSync(path82);
22537
22588
  if (stat2.isFile() && isFile) {
22538
22589
  log2(`[OK] path represents a file`);
22539
22590
  return true;
@@ -22553,8 +22604,8 @@ var require_src2 = __commonJS({
22553
22604
  throw e;
22554
22605
  }
22555
22606
  }
22556
- function exists2(path79, type = exports.READABLE) {
22557
- return check2(path79, (type & exports.FILE) > 0, (type & exports.FOLDER) > 0);
22607
+ function exists2(path82, type = exports.READABLE) {
22608
+ return check2(path82, (type & exports.FILE) > 0, (type & exports.FOLDER) > 0);
22558
22609
  }
22559
22610
  exports.exists = exists2;
22560
22611
  exports.FILE = 1;
@@ -22617,6 +22668,112 @@ var require_dist2 = __commonJS({
22617
22668
  }
22618
22669
  });
22619
22670
 
22671
+ // src/files/ensure-under-cwd.ts
22672
+ import path73 from "node:path";
22673
+ function ensureUnderCwd(relativePath, cwd = getBridgeRoot()) {
22674
+ const normalized = path73.normalize(relativePath).replace(/^(\.\/)+/, "");
22675
+ const resolved = path73.resolve(cwd, normalized);
22676
+ if (!resolved.startsWith(cwd + path73.sep) && resolved !== cwd) {
22677
+ return null;
22678
+ }
22679
+ return resolved;
22680
+ }
22681
+ var init_ensure_under_cwd = __esm({
22682
+ "src/files/ensure-under-cwd.ts"() {
22683
+ "use strict";
22684
+ init_cwd();
22685
+ }
22686
+ });
22687
+
22688
+ // src/files/list-dir/types.ts
22689
+ var LIST_DIR_YIELD_EVERY;
22690
+ var init_types2 = __esm({
22691
+ "src/files/list-dir/types.ts"() {
22692
+ "use strict";
22693
+ LIST_DIR_YIELD_EVERY = 256;
22694
+ }
22695
+ });
22696
+
22697
+ // src/files/list-dir/map-dir-entry.ts
22698
+ import path74 from "node:path";
22699
+ import fs47 from "node:fs";
22700
+ async function mapDirEntry(d, relativePath, resolved) {
22701
+ const entryPath = path74.join(relativePath || ".", d.name).replace(/\\/g, "/");
22702
+ const fullPath = path74.join(resolved, d.name);
22703
+ let isDir = d.isDirectory();
22704
+ if (d.isSymbolicLink()) {
22705
+ try {
22706
+ const targetStat = await fs47.promises.stat(fullPath);
22707
+ isDir = targetStat.isDirectory();
22708
+ } catch {
22709
+ isDir = false;
22710
+ }
22711
+ }
22712
+ return {
22713
+ name: d.name,
22714
+ path: entryPath,
22715
+ isDir,
22716
+ isSymlink: d.isSymbolicLink()
22717
+ };
22718
+ }
22719
+ var init_map_dir_entry = __esm({
22720
+ "src/files/list-dir/map-dir-entry.ts"() {
22721
+ "use strict";
22722
+ }
22723
+ });
22724
+
22725
+ // src/files/list-dir/sort-entries.ts
22726
+ function sortListEntries(entries) {
22727
+ return entries.sort((a, b) => {
22728
+ if (a.isDir !== b.isDir) return a.isDir ? -1 : 1;
22729
+ return a.name.localeCompare(b.name, void 0, { sensitivity: "base" });
22730
+ });
22731
+ }
22732
+ var init_sort_entries = __esm({
22733
+ "src/files/list-dir/sort-entries.ts"() {
22734
+ "use strict";
22735
+ }
22736
+ });
22737
+
22738
+ // src/files/list-dir/index.ts
22739
+ var list_dir_exports = {};
22740
+ __export(list_dir_exports, {
22741
+ listDirAsync: () => listDirAsync
22742
+ });
22743
+ import fs48 from "node:fs";
22744
+ async function listDirAsync(relativePath, sessionParentPath = getBridgeRoot()) {
22745
+ await yieldToEventLoop();
22746
+ const resolved = ensureUnderCwd(relativePath || ".", sessionParentPath);
22747
+ if (!resolved) {
22748
+ return { error: "Path is outside working directory" };
22749
+ }
22750
+ try {
22751
+ const names = await fs48.promises.readdir(resolved, { withFileTypes: true });
22752
+ const entries = [];
22753
+ for (let i = 0; i < names.length; i++) {
22754
+ if (i > 0 && i % LIST_DIR_YIELD_EVERY === 0) {
22755
+ await yieldToEventLoop();
22756
+ }
22757
+ entries.push(await mapDirEntry(names[i], relativePath, resolved));
22758
+ }
22759
+ return { entries: sortListEntries(entries) };
22760
+ } catch (err) {
22761
+ const message = err instanceof Error ? err.message : String(err);
22762
+ return { error: message };
22763
+ }
22764
+ }
22765
+ var init_list_dir = __esm({
22766
+ "src/files/list-dir/index.ts"() {
22767
+ "use strict";
22768
+ init_ensure_under_cwd();
22769
+ init_cwd();
22770
+ init_yield_to_event_loop();
22771
+ init_types2();
22772
+ init_map_dir_entry();
22773
+ init_sort_entries();
22774
+ }
22775
+ });
22776
+
22620
22777
  // ../../node_modules/.pnpm/ws@8.19.0/node_modules/ws/wrapper.mjs
22621
22778
  var import_stream = __toESM(require_stream(), 1);
22622
22779
  var import_receiver = __toESM(require_receiver(), 1);
@@ -22787,26 +22944,8 @@ function sendWsMessage(ws, payload) {
22787
22944
  }
22788
22945
  }
22789
22946
 
22790
- // src/paths/normalize-resolved-path.ts
22791
- import fs from "node:fs";
22792
- import path from "node:path";
22793
- function normalizeResolvedPath(resolved) {
22794
- const abs = path.resolve(resolved);
22795
- try {
22796
- return fs.realpathSync.native(abs);
22797
- } catch {
22798
- return abs;
22799
- }
22800
- }
22801
-
22802
- // src/files/cwd/bridge-root.ts
22803
- var bridgeRootPath = null;
22804
- function getBridgeRoot() {
22805
- if (bridgeRootPath == null) {
22806
- bridgeRootPath = normalizeResolvedPath(process.cwd());
22807
- }
22808
- return bridgeRootPath;
22809
- }
22947
+ // src/agents/acp/clients/sdk/sdk-stdio-acp-client.ts
22948
+ init_cwd();
22810
22949
 
22811
22950
  // src/agents/acp/clients/agent-stderr-capture.ts
22812
22951
  var STDERR_CAPTURE_MAX = 48e3;
@@ -24034,11 +24173,11 @@ function createSdkStdioExtNotificationHandler(options) {
24034
24173
 
24035
24174
  // src/agents/acp/clients/sdk/sdk-stdio-permission-request-handshake.ts
24036
24175
  function awaitSdkStdioPermissionRequestHandshake(params) {
24037
- const { requestId, paramsRecord, pending: pending2, onRequest } = params;
24176
+ const { requestId, paramsRecord, pending, onRequest } = params;
24038
24177
  return new Promise((resolve35) => {
24039
- pending2.set(requestId, { resolve: resolve35, params: paramsRecord });
24178
+ pending.set(requestId, { resolve: resolve35, params: paramsRecord });
24040
24179
  if (onRequest == null) {
24041
- pending2.delete(requestId);
24180
+ pending.delete(requestId);
24042
24181
  resolve35({ outcome: { outcome: "denied" } });
24043
24182
  return;
24044
24183
  }
@@ -24054,9 +24193,9 @@ function awaitSdkStdioPermissionRequestHandshake(params) {
24054
24193
  }
24055
24194
 
24056
24195
  // src/agents/acp/clients/sdk/sdk-stdio-permission-pending.ts
24057
- function resolvePendingSdkStdioPermissionCancellations(pending2) {
24058
- for (const [id, entry] of [...pending2.entries()]) {
24059
- pending2.delete(id);
24196
+ function resolvePendingSdkStdioPermissionCancellations(pending) {
24197
+ for (const [id, entry] of [...pending.entries()]) {
24198
+ pending.delete(id);
24060
24199
  entry.resolve({ outcome: { outcome: "cancelled" } });
24061
24200
  }
24062
24201
  }
@@ -24938,6 +25077,7 @@ async function proxyToLocalStreaming(request, callbacks) {
24938
25077
  }
24939
25078
 
24940
25079
  // src/skills/preview.ts
25080
+ init_cwd();
24941
25081
  import { spawn as spawn2 } from "node:child_process";
24942
25082
  var PREVIEW_API_BASE_PATH = "/__preview";
24943
25083
  var PREVIEW_SECRET_HEADER = "X-Preview-Secret";
@@ -24958,8 +25098,8 @@ function randomSecret() {
24958
25098
  }
24959
25099
  return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
24960
25100
  }
24961
- async function requestPreviewApi(port, secret, method, path79, body) {
24962
- const url2 = `http://127.0.0.1:${port}${path79}`;
25101
+ async function requestPreviewApi(port, secret, method, path82, body) {
25102
+ const url2 = `http://127.0.0.1:${port}${path82}`;
24963
25103
  const headers = {
24964
25104
  [PREVIEW_SECRET_HEADER]: secret,
24965
25105
  "Content-Type": "application/json"
@@ -24971,7 +25111,7 @@ async function requestPreviewApi(port, secret, method, path79, body) {
24971
25111
  });
24972
25112
  const data = await res.json().catch(() => ({}));
24973
25113
  if (!res.ok) {
24974
- throw new Error(data?.error ?? `Preview API ${method} ${path79}: ${res.status}`);
25114
+ throw new Error(data?.error ?? `Preview API ${method} ${path82}: ${res.status}`);
24975
25115
  }
24976
25116
  return data;
24977
25117
  }
@@ -25186,7 +25326,7 @@ function installBridgeProcessResilience() {
25186
25326
  }
25187
25327
 
25188
25328
  // src/cli-version.ts
25189
- var CLI_VERSION = "0.1.63".length > 0 ? "0.1.63" : "0.0.0-dev";
25329
+ var CLI_VERSION = "0.1.64".length > 0 ? "0.1.64" : "0.0.0-dev";
25190
25330
 
25191
25331
  // src/connection/heartbeat/constants.ts
25192
25332
  var BRIDGE_APP_HEARTBEAT_INTERVAL_MS = 1e4;
@@ -26301,7 +26441,11 @@ function runPendingAuth(options) {
26301
26441
  };
26302
26442
  }
26303
26443
 
26444
+ // src/connection/create-bridge-connection.ts
26445
+ init_cwd();
26446
+
26304
26447
  // src/files/watch-file-index.ts
26448
+ init_cwd();
26305
26449
  import path25 from "node:path";
26306
26450
 
26307
26451
  // src/files/index/paths.ts
@@ -26311,7 +26455,7 @@ import crypto2 from "node:crypto";
26311
26455
  // src/files/index/constants.ts
26312
26456
  import path5 from "node:path";
26313
26457
  import os3 from "node:os";
26314
- var INDEX_WORK_YIELD_EVERY = 256;
26458
+ var INDEX_WORK_YIELD_EVERY = 128;
26315
26459
  var INDEX_DIR = path5.join(os3.homedir(), ".buildautomaton");
26316
26460
  var INDEX_HASH_LEN = 16;
26317
26461
 
@@ -26323,9 +26467,78 @@ function getCwdHashForFileIndex(resolvedCwd) {
26323
26467
  // src/files/index/build-file-index.ts
26324
26468
  import path15 from "node:path";
26325
26469
 
26326
- // src/runtime/yield-to-event-loop.ts
26327
- function yieldToEventLoop() {
26328
- return new Promise((resolve35) => setImmediate(resolve35));
26470
+ // src/files/browser/file-browser-in-flight.ts
26471
+ init_yield_to_event_loop();
26472
+
26473
+ // src/code-nav/symbol-index/deferred-indexing.ts
26474
+ var SymbolIndexDeferredError = class extends Error {
26475
+ constructor() {
26476
+ super("Symbol indexing deferred for file browser");
26477
+ this.name = "SymbolIndexDeferredError";
26478
+ }
26479
+ };
26480
+ function isSymbolIndexDeferredError(err) {
26481
+ return err instanceof SymbolIndexDeferredError;
26482
+ }
26483
+
26484
+ // src/files/browser/file-browser-in-flight.ts
26485
+ var BROWSE_INDEX_COOLDOWN_MS = 2500;
26486
+ var inFlightFileBrowserRequests = 0;
26487
+ var lastBrowseActivityAt = 0;
26488
+ var activityListeners = /* @__PURE__ */ new Set();
26489
+ var requestStartListeners = /* @__PURE__ */ new Set();
26490
+ function touchBrowseActivity() {
26491
+ lastBrowseActivityAt = Date.now();
26492
+ }
26493
+ function registerFileBrowserActivityListener(listener) {
26494
+ activityListeners.add(listener);
26495
+ return () => {
26496
+ activityListeners.delete(listener);
26497
+ };
26498
+ }
26499
+ function registerFileBrowserRequestStartListener(listener) {
26500
+ requestStartListeners.add(listener);
26501
+ return () => {
26502
+ requestStartListeners.delete(listener);
26503
+ };
26504
+ }
26505
+ function notifyFileBrowserActivity() {
26506
+ for (const listener of activityListeners) listener();
26507
+ }
26508
+ function notifyFileBrowserRequestStart() {
26509
+ for (const listener of requestStartListeners) listener();
26510
+ }
26511
+ function beginFileBrowserRequest() {
26512
+ inFlightFileBrowserRequests += 1;
26513
+ touchBrowseActivity();
26514
+ notifyFileBrowserRequestStart();
26515
+ notifyFileBrowserActivity();
26516
+ }
26517
+ function endFileBrowserRequest() {
26518
+ inFlightFileBrowserRequests = Math.max(0, inFlightFileBrowserRequests - 1);
26519
+ touchBrowseActivity();
26520
+ }
26521
+ function fileBrowserRequestInFlight() {
26522
+ return inFlightFileBrowserRequests > 0;
26523
+ }
26524
+ function isBridgeBrowseInteractiveActive() {
26525
+ if (fileBrowserRequestInFlight()) return true;
26526
+ return Date.now() - lastBrowseActivityAt < BROWSE_INDEX_COOLDOWN_MS;
26527
+ }
26528
+ function assertBackgroundIndexingAllowed() {
26529
+ if (isBridgeBrowseInteractiveActive()) throw new SymbolIndexDeferredError();
26530
+ }
26531
+ async function yieldUntilFileBrowserIdle(pollMs = 5) {
26532
+ while (isBridgeBrowseInteractiveActive()) {
26533
+ await yieldToEventLoop();
26534
+ if (isBridgeBrowseInteractiveActive()) {
26535
+ await new Promise((resolve35) => setTimeout(resolve35, pollMs));
26536
+ }
26537
+ }
26538
+ }
26539
+ async function yieldForBridgeInteractivePriority() {
26540
+ await yieldToEventLoop();
26541
+ await yieldUntilFileBrowserIdle();
26329
26542
  }
26330
26543
 
26331
26544
  // src/runtime/cli-process-interrupt.ts
@@ -26348,7 +26561,11 @@ async function delayMsUnlessShutdownRequested(ms) {
26348
26561
  return !isCliImmediateShutdownRequested();
26349
26562
  }
26350
26563
 
26564
+ // src/sqlite/code-nav-cache/code-nav-cache-database.ts
26565
+ init_yield_to_event_loop();
26566
+
26351
26567
  // src/sqlite/create-sqlite-database-access.ts
26568
+ init_yield_to_event_loop();
26352
26569
  import sqliteWasm from "node-sqlite3-wasm";
26353
26570
 
26354
26571
  // src/sqlite/sqlite-errors.ts
@@ -26393,6 +26610,7 @@ function applySqliteMemoryPragmas(db) {
26393
26610
  }
26394
26611
 
26395
26612
  // src/sqlite/sqlite-lock-retry.ts
26613
+ init_yield_to_event_loop();
26396
26614
  var SYNC_RETRY_MAX = 40;
26397
26615
  var ASYNC_RETRY_MAX = 60;
26398
26616
  var ASYNC_BASE_DELAY_MS = 20;
@@ -26554,7 +26772,7 @@ function readMigrationSql(filename, ...searchSubdirs) {
26554
26772
  join(moduleDir, "..", sub, filename),
26555
26773
  join(moduleDir, "..", "..", "dist", sub, filename)
26556
26774
  ]);
26557
- const resolved = candidates.find((path79) => existsSync(path79));
26775
+ const resolved = candidates.find((path82) => existsSync(path82));
26558
26776
  if (!resolved) {
26559
26777
  throw new Error(`Missing SQLite migration SQL: ${filename} (searched ${searchSubdirs.join(", ")})`);
26560
26778
  }
@@ -26943,14 +27161,14 @@ function legacyCliDiskMigrationIsPending() {
26943
27161
  return false;
26944
27162
  }
26945
27163
  function importCliSqliteLegacyDiskData(db, log2) {
26946
- const pending2 = legacyCliDiskMigrationIsPending();
26947
- if (pending2 && log2) {
27164
+ const pending = legacyCliDiskMigrationIsPending();
27165
+ if (pending && log2) {
26948
27166
  log2("Migrating legacy on-disk CLI data to SQLite\u2026");
26949
27167
  }
26950
27168
  archiveLegacyFileIndexJsonFiles();
26951
27169
  importLegacyAgentSessionsFromDisk(db);
26952
27170
  importLegacyPromptQueuesFromDisk(db);
26953
- if (pending2 && log2) {
27171
+ if (pending && log2) {
26954
27172
  log2("Legacy on-disk CLI data migration finished.");
26955
27173
  }
26956
27174
  }
@@ -27059,7 +27277,7 @@ async function walkWorkspaceTreeAsync(dir, baseDir, onFile, state) {
27059
27277
  if (shouldSkipWorkspaceWalkEntry(name)) continue;
27060
27278
  if (state.n > 0 && state.n % INDEX_WORK_YIELD_EVERY === 0) {
27061
27279
  if (isCliImmediateShutdownRequested()) throw new CliSqliteInterrupted();
27062
- await yieldToEventLoop();
27280
+ await yieldForBridgeInteractivePriority();
27063
27281
  if (isCliImmediateShutdownRequested()) throw new CliSqliteInterrupted();
27064
27282
  }
27065
27283
  state.n++;
@@ -27166,7 +27384,7 @@ async function persistFileIndexPathsAsync(resolved, paths) {
27166
27384
  assertFileIndexPersistNotShutdown();
27167
27385
  const batch = paths.slice(offset, offset + FILE_INDEX_INSERT_BUFFER);
27168
27386
  pathCount += await withCodeNavCacheSqlite((db) => insertFileIndexChildPathBatch(db, resolved, batch));
27169
- await yieldToEventLoop();
27387
+ await yieldForBridgeInteractivePriority();
27170
27388
  }
27171
27389
  return pathCount;
27172
27390
  }
@@ -27177,10 +27395,10 @@ function assertNotShutdown2() {
27177
27395
  }
27178
27396
  async function buildFileIndexAsync(cwd) {
27179
27397
  const resolved = path15.resolve(cwd);
27180
- await yieldToEventLoop();
27398
+ await yieldForBridgeInteractivePriority();
27181
27399
  assertNotShutdown2();
27182
27400
  const paths = await collectWorkspacePathsAsync(resolved);
27183
- await yieldToEventLoop();
27401
+ await yieldForBridgeInteractivePriority();
27184
27402
  assertNotShutdown2();
27185
27403
  return await withFileIndexSqliteLock(async () => {
27186
27404
  const pathCount = await persistFileIndexPathsAsync(resolved, paths);
@@ -27192,6 +27410,7 @@ async function buildFileIndexAsync(cwd) {
27192
27410
  import path16 from "node:path";
27193
27411
 
27194
27412
  // src/files/index/search-file-index.ts
27413
+ init_yield_to_event_loop();
27195
27414
  function escapeLikePattern(fragment) {
27196
27415
  return fragment.replace(/\\/g, "\\\\").replace(/%/g, "\\%").replace(/_/g, "\\_");
27197
27416
  }
@@ -27248,8 +27467,11 @@ async function ensureFileIndexAsync(cwd) {
27248
27467
  return { ...await buildFileIndexAsync(resolved), fromCache: false };
27249
27468
  }
27250
27469
 
27470
+ // src/code-nav/symbol-index/build/build-symbol-index.ts
27471
+ init_normalize_resolved_path();
27472
+
27251
27473
  // src/code-nav/yield-during-work.ts
27252
- var CODE_NAV_YIELD_EVERY = INDEX_WORK_YIELD_EVERY;
27474
+ var CODE_NAV_YIELD_EVERY = 64;
27253
27475
  function createCodeNavYieldState() {
27254
27476
  return { n: 0 };
27255
27477
  }
@@ -27257,7 +27479,7 @@ async function yieldDuringCodeNavWork(state) {
27257
27479
  state.n++;
27258
27480
  if (state.n % CODE_NAV_YIELD_EVERY !== 0) return;
27259
27481
  if (isCliImmediateShutdownRequested()) throw new CliSqliteInterrupted();
27260
- await yieldToEventLoop();
27482
+ await yieldForBridgeInteractivePriority();
27261
27483
  if (isCliImmediateShutdownRequested()) throw new CliSqliteInterrupted();
27262
27484
  }
27263
27485
 
@@ -27390,7 +27612,7 @@ async function walkCodeNavFilesInDirectory(dir, baseDir, relDir, filter, onFile,
27390
27612
  if (shouldSkipWorkspaceWalkEntry(name)) continue;
27391
27613
  if (state.n > 0 && state.n % INDEX_WORK_YIELD_EVERY === 0) {
27392
27614
  if (isCliImmediateShutdownRequested()) throw new CliSqliteInterrupted();
27393
- await yieldToEventLoop();
27615
+ await yieldForBridgeInteractivePriority();
27394
27616
  if (isCliImmediateShutdownRequested()) throw new CliSqliteInterrupted();
27395
27617
  }
27396
27618
  state.n++;
@@ -27424,6 +27646,8 @@ async function walkCodeNavFilesAsync(rootDir, onFile, state = createWalkYieldSta
27424
27646
  var SYMBOL_INDEX_VERSION = 11;
27425
27647
 
27426
27648
  // src/code-nav/symbol-index/sqlite/parent-path.ts
27649
+ init_bridge_root();
27650
+ init_normalize_resolved_path();
27427
27651
  function normalizeParentPath(resolved) {
27428
27652
  return normalizeResolvedPath(resolved);
27429
27653
  }
@@ -27718,128 +27942,11 @@ function withSymbolIndexSqliteLock(fn) {
27718
27942
  return withCodeNavCacheSqliteWorkLock(fn);
27719
27943
  }
27720
27944
 
27721
- // src/code-nav/symbol-index/imports/star-reexport-names.ts
27722
- var STAR_LOCAL_NAME = "*";
27723
- function isModuleLevelDef(tag) {
27724
- return tag.role === "def" && tag.parentScopeStartLine == null && tag.parentScopeStartColumn == null;
27725
- }
27726
- function collectExportableNamesFromTags(tags) {
27727
- const names = /* @__PURE__ */ new Map();
27728
- for (const tag of tags) {
27729
- if (!isModuleLevelDef(tag)) continue;
27730
- if (!names.has(tag.name)) names.set(tag.name, tag.name);
27731
- }
27732
- return names;
27733
- }
27734
- function existingLocalNames(imports) {
27735
- return new Set(imports.map((binding) => binding.localName));
27736
- }
27737
- function resolveExportableNames(filePath, entriesByPath, visited) {
27738
- if (visited.has(filePath)) return /* @__PURE__ */ new Map();
27739
- visited.add(filePath);
27740
- const entry = entriesByPath.get(filePath);
27741
- if (!entry) return /* @__PURE__ */ new Map();
27742
- const out = collectExportableNamesFromTags(entry.tags);
27743
- const resolved = /* @__PURE__ */ new Map();
27744
- for (const [name, sourceName] of out) {
27745
- resolved.set(name, { sourceName, sourceFilePath: filePath });
27746
- }
27747
- for (const binding of entry.imports) {
27748
- if (binding.importKind !== "star" || !binding.sourceFilePath) continue;
27749
- const upstream = resolveExportableNames(binding.sourceFilePath, entriesByPath, visited);
27750
- for (const [name, info] of upstream) {
27751
- if (!resolved.has(name)) resolved.set(name, info);
27752
- }
27753
- }
27754
- for (const binding of entry.imports) {
27755
- if (binding.importKind !== "reexport" && binding.importKind !== "type") continue;
27756
- if (!binding.sourceFilePath) continue;
27757
- if (!resolved.has(binding.localName)) {
27758
- resolved.set(binding.localName, {
27759
- sourceName: binding.sourceName,
27760
- sourceFilePath: binding.sourceFilePath
27761
- });
27762
- }
27763
- }
27764
- return resolved;
27765
- }
27766
-
27767
- // src/code-nav/symbol-index/imports/star-reexport-upstream.ts
27768
- function collectUpstreamEntries(entry, resolveEntry) {
27769
- const entriesByPath = /* @__PURE__ */ new Map();
27770
- entriesByPath.set(entry.relPath, entry);
27771
- const visit = (filePath, visited) => {
27772
- if (visited.has(filePath)) return;
27773
- visited.add(filePath);
27774
- const resolved = resolveEntry(filePath);
27775
- if (resolved == null) return;
27776
- entriesByPath.set(filePath, resolved);
27777
- for (const binding of resolved.imports) {
27778
- if (binding.sourceFilePath) visit(binding.sourceFilePath, visited);
27779
- }
27780
- };
27781
- for (const star of entry.imports) {
27782
- if (star.importKind !== "star" || !star.sourceFilePath) continue;
27783
- visit(star.sourceFilePath, /* @__PURE__ */ new Set());
27784
- }
27785
- return [...entriesByPath.values()];
27786
- }
27787
-
27788
- // src/code-nav/symbol-index/imports/expand-star-reexports.ts
27789
- function expandStarReexportForFile(entry, resolveEntry) {
27790
- const collected = collectUpstreamEntries(entry, resolveEntry);
27791
- return expandStarReexportBindings(collected).find((row) => row.relPath === entry.relPath) ?? entry;
27792
- }
27793
- function expandStarReexportBindings(collected) {
27794
- const entriesByPath = new Map(collected.map((entry) => [entry.relPath, entry]));
27795
- return collected.map((entry) => {
27796
- const stars = entry.imports.filter((binding) => binding.importKind === "star");
27797
- if (stars.length === 0) return entry;
27798
- const localNames = existingLocalNames(entry.imports);
27799
- const materialized = [];
27800
- for (const star of stars) {
27801
- if (!star.sourceFilePath) continue;
27802
- const exportable = resolveExportableNames(star.sourceFilePath, entriesByPath, /* @__PURE__ */ new Set());
27803
- for (const [localName, info] of exportable) {
27804
- if (localName === STAR_LOCAL_NAME || localNames.has(localName)) continue;
27805
- localNames.add(localName);
27806
- materialized.push({
27807
- localName,
27808
- sourceName: info.sourceName,
27809
- moduleSpecifier: star.moduleSpecifier,
27810
- sourceFilePath: info.sourceFilePath,
27811
- importKind: star.importKind === "type" ? "type" : "reexport",
27812
- startLine: star.startLine,
27813
- startColumn: star.startColumn
27814
- });
27815
- }
27816
- }
27817
- if (materialized.length === 0) return entry;
27818
- return { ...entry, imports: [...entry.imports, ...materialized] };
27819
- });
27820
- }
27945
+ // src/code-nav/symbol-index/build/ensure-symbol-index-file.ts
27946
+ init_normalize_resolved_path();
27821
27947
 
27822
- // src/code-nav/symbol-index/persistence/persist-single-file.ts
27823
- async function persistSymbolIndexFileAsync(resolved, relPath, source, tags, imports) {
27824
- await withCodeNavCacheSqlite(async (db) => {
27825
- runCodeNavCacheWriteTransaction(db, () => {
27826
- upsertSymbolIndexParentPath(db, resolved);
27827
- const ctx = getSymbolIndexParentContext(db, resolved);
27828
- if (ctx == null) throw new Error(`Failed to resolve symbol index parent: ${resolved}`);
27829
- persistSymbolIndexFileData(db, ctx, relPath, source, tags, imports);
27830
- });
27831
- });
27832
- }
27833
- async function removeSymbolIndexFileAsync(resolved, relPath) {
27834
- await withCodeNavCacheSqlite(async (db) => {
27835
- runCodeNavCacheWriteTransaction(db, () => {
27836
- upsertSymbolIndexParentPath(db, resolved);
27837
- const ctx = getSymbolIndexParentContext(db, resolved);
27838
- if (ctx == null) throw new Error(`Failed to resolve symbol index parent: ${resolved}`);
27839
- removeSymbolIndexFileData(db, ctx, relPath);
27840
- });
27841
- });
27842
- }
27948
+ // src/code-nav/symbol-index/query/list-direct-import-targets.ts
27949
+ init_normalize_resolved_path();
27843
27950
 
27844
27951
  // src/code-nav/symbol-index/query/tag-query-shared.ts
27845
27952
  var TAG_SELECT = `file_path, name, role, kind, start_line, start_column, end_line, end_column,
@@ -27989,6 +28096,7 @@ async function listDirectImportTargetsForFileAsync(parentPath, filePath) {
27989
28096
  }
27990
28097
 
27991
28098
  // src/code-nav/symbol-index/lifecycle/symbol-index-file-ready.ts
28099
+ init_normalize_resolved_path();
27992
28100
  function symbolIndexFileIsReadyWithDb(db, parentPath, filePath) {
27993
28101
  const normalizedParent = normalizeResolvedPath(parentPath);
27994
28102
  const normalizedFile = filePath.replace(/\\/g, "/").replace(/^\/+/, "");
@@ -28018,6 +28126,129 @@ async function loadSymbolIndexReadyFileSet(parentPath) {
28018
28126
  return new Set(paths);
28019
28127
  }
28020
28128
 
28129
+ // src/code-nav/symbol-index/imports/star-reexport-names.ts
28130
+ var STAR_LOCAL_NAME = "*";
28131
+ function isModuleLevelDef(tag) {
28132
+ return tag.role === "def" && tag.parentScopeStartLine == null && tag.parentScopeStartColumn == null;
28133
+ }
28134
+ function collectExportableNamesFromTags(tags) {
28135
+ const names = /* @__PURE__ */ new Map();
28136
+ for (const tag of tags) {
28137
+ if (!isModuleLevelDef(tag)) continue;
28138
+ if (!names.has(tag.name)) names.set(tag.name, tag.name);
28139
+ }
28140
+ return names;
28141
+ }
28142
+ function existingLocalNames(imports) {
28143
+ return new Set(imports.map((binding) => binding.localName));
28144
+ }
28145
+ function resolveExportableNames(filePath, entriesByPath, visited) {
28146
+ if (visited.has(filePath)) return /* @__PURE__ */ new Map();
28147
+ visited.add(filePath);
28148
+ const entry = entriesByPath.get(filePath);
28149
+ if (!entry) return /* @__PURE__ */ new Map();
28150
+ const out = collectExportableNamesFromTags(entry.tags);
28151
+ const resolved = /* @__PURE__ */ new Map();
28152
+ for (const [name, sourceName] of out) {
28153
+ resolved.set(name, { sourceName, sourceFilePath: filePath });
28154
+ }
28155
+ for (const binding of entry.imports) {
28156
+ if (binding.importKind !== "star" || !binding.sourceFilePath) continue;
28157
+ const upstream = resolveExportableNames(binding.sourceFilePath, entriesByPath, visited);
28158
+ for (const [name, info] of upstream) {
28159
+ if (!resolved.has(name)) resolved.set(name, info);
28160
+ }
28161
+ }
28162
+ for (const binding of entry.imports) {
28163
+ if (binding.importKind !== "reexport" && binding.importKind !== "type") continue;
28164
+ if (!binding.sourceFilePath) continue;
28165
+ if (!resolved.has(binding.localName)) {
28166
+ resolved.set(binding.localName, {
28167
+ sourceName: binding.sourceName,
28168
+ sourceFilePath: binding.sourceFilePath
28169
+ });
28170
+ }
28171
+ }
28172
+ return resolved;
28173
+ }
28174
+
28175
+ // src/code-nav/symbol-index/imports/star-reexport-upstream.ts
28176
+ function collectUpstreamEntries(entry, resolveEntry) {
28177
+ const entriesByPath = /* @__PURE__ */ new Map();
28178
+ entriesByPath.set(entry.relPath, entry);
28179
+ const visit = (filePath, visited) => {
28180
+ if (visited.has(filePath)) return;
28181
+ visited.add(filePath);
28182
+ const resolved = resolveEntry(filePath);
28183
+ if (resolved == null) return;
28184
+ entriesByPath.set(filePath, resolved);
28185
+ for (const binding of resolved.imports) {
28186
+ if (binding.sourceFilePath) visit(binding.sourceFilePath, visited);
28187
+ }
28188
+ };
28189
+ for (const star of entry.imports) {
28190
+ if (star.importKind !== "star" || !star.sourceFilePath) continue;
28191
+ visit(star.sourceFilePath, /* @__PURE__ */ new Set());
28192
+ }
28193
+ return [...entriesByPath.values()];
28194
+ }
28195
+
28196
+ // src/code-nav/symbol-index/imports/expand-star-reexports.ts
28197
+ function expandStarReexportForFile(entry, resolveEntry) {
28198
+ const collected = collectUpstreamEntries(entry, resolveEntry);
28199
+ return expandStarReexportBindings(collected).find((row) => row.relPath === entry.relPath) ?? entry;
28200
+ }
28201
+ function expandStarReexportBindings(collected) {
28202
+ const entriesByPath = new Map(collected.map((entry) => [entry.relPath, entry]));
28203
+ return collected.map((entry) => {
28204
+ const stars = entry.imports.filter((binding) => binding.importKind === "star");
28205
+ if (stars.length === 0) return entry;
28206
+ const localNames = existingLocalNames(entry.imports);
28207
+ const materialized = [];
28208
+ for (const star of stars) {
28209
+ if (!star.sourceFilePath) continue;
28210
+ const exportable = resolveExportableNames(star.sourceFilePath, entriesByPath, /* @__PURE__ */ new Set());
28211
+ for (const [localName, info] of exportable) {
28212
+ if (localName === STAR_LOCAL_NAME || localNames.has(localName)) continue;
28213
+ localNames.add(localName);
28214
+ materialized.push({
28215
+ localName,
28216
+ sourceName: info.sourceName,
28217
+ moduleSpecifier: star.moduleSpecifier,
28218
+ sourceFilePath: info.sourceFilePath,
28219
+ importKind: star.importKind === "type" ? "type" : "reexport",
28220
+ startLine: star.startLine,
28221
+ startColumn: star.startColumn
28222
+ });
28223
+ }
28224
+ }
28225
+ if (materialized.length === 0) return entry;
28226
+ return { ...entry, imports: [...entry.imports, ...materialized] };
28227
+ });
28228
+ }
28229
+
28230
+ // src/code-nav/symbol-index/persistence/persist-single-file.ts
28231
+ async function persistSymbolIndexFileAsync(resolved, relPath, source, tags, imports) {
28232
+ await withCodeNavCacheSqlite(async (db) => {
28233
+ runCodeNavCacheWriteTransaction(db, () => {
28234
+ upsertSymbolIndexParentPath(db, resolved);
28235
+ const ctx = getSymbolIndexParentContext(db, resolved);
28236
+ if (ctx == null) throw new Error(`Failed to resolve symbol index parent: ${resolved}`);
28237
+ persistSymbolIndexFileData(db, ctx, relPath, source, tags, imports);
28238
+ });
28239
+ });
28240
+ }
28241
+ async function removeSymbolIndexFileAsync(resolved, relPath) {
28242
+ await withCodeNavCacheSqlite(async (db) => {
28243
+ runCodeNavCacheWriteTransaction(db, () => {
28244
+ upsertSymbolIndexParentPath(db, resolved);
28245
+ const ctx = getSymbolIndexParentContext(db, resolved);
28246
+ if (ctx == null) throw new Error(`Failed to resolve symbol index parent: ${resolved}`);
28247
+ removeSymbolIndexFileData(db, ctx, relPath);
28248
+ });
28249
+ });
28250
+ }
28251
+
28021
28252
  // src/code-nav/symbol-index/build/extract-file-symbol-data.ts
28022
28253
  import fs19 from "node:fs";
28023
28254
  import path21 from "node:path";
@@ -28704,6 +28935,7 @@ async function parseSourceRoot(filePath, source) {
28704
28935
  const languageKey = getLanguageKeyForFilePath(filePath);
28705
28936
  if (!languageKey) return null;
28706
28937
  return withTreeSitterRuntimeLock(async () => {
28938
+ await yieldForBridgeInteractivePriority();
28707
28939
  let loaded;
28708
28940
  try {
28709
28941
  loaded = await loadLanguage(languageKey);
@@ -28715,7 +28947,11 @@ async function parseSourceRoot(filePath, source) {
28715
28947
  parser4.setLanguage(loaded.language);
28716
28948
  let tree = null;
28717
28949
  try {
28950
+ await yieldForBridgeInteractivePriority();
28951
+ assertBackgroundIndexingAllowed();
28718
28952
  tree = parser4.parse(source);
28953
+ assertBackgroundIndexingAllowed();
28954
+ await yieldForBridgeInteractivePriority();
28719
28955
  if (!tree) return null;
28720
28956
  return {
28721
28957
  root: tree.rootNode,
@@ -28725,9 +28961,10 @@ async function parseSourceRoot(filePath, source) {
28725
28961
  parser4.delete();
28726
28962
  }
28727
28963
  };
28728
- } catch {
28964
+ } catch (err) {
28729
28965
  tree?.delete();
28730
28966
  parser4.delete();
28967
+ if (isSymbolIndexDeferredError(err)) throw err;
28731
28968
  return null;
28732
28969
  }
28733
28970
  });
@@ -28735,9 +28972,11 @@ async function parseSourceRoot(filePath, source) {
28735
28972
 
28736
28973
  // src/code-nav/parser/run-tags-query.ts
28737
28974
  async function runTagsQuery(loaded, root) {
28738
- await yieldToEventLoop();
28975
+ await yieldForBridgeInteractivePriority();
28976
+ assertBackgroundIndexingAllowed();
28739
28977
  const matches = loaded.query.matches(root);
28740
- await yieldToEventLoop();
28978
+ assertBackgroundIndexingAllowed();
28979
+ await yieldForBridgeInteractivePriority();
28741
28980
  return matches;
28742
28981
  }
28743
28982
 
@@ -28818,7 +29057,7 @@ async function tagsFromMatchesAsync(matches, state) {
28818
29057
  // src/code-nav/parser/extract-tags.ts
28819
29058
  async function extractTagsFromSource(filePath, source) {
28820
29059
  const languageKey = getLanguageKeyForFilePath(filePath);
28821
- await yieldToEventLoop();
29060
+ await yieldForBridgeInteractivePriority();
28822
29061
  const parsed = await parseSourceRoot(filePath, source);
28823
29062
  if (!parsed) return [];
28824
29063
  try {
@@ -28834,13 +29073,17 @@ async function extractTagsFromSource(filePath, source) {
28834
29073
  const withReceivers = await augmentMemberReceiverTags(withFunctionTypeParamRefs, nameNodes, parsed.root, languageKey);
28835
29074
  await yieldDuringCodeNavWork(yieldState);
28836
29075
  return await enrichTagsWithEnclosingScope(withReceivers, nameNodes);
28837
- } catch {
29076
+ } catch (err) {
29077
+ if (isSymbolIndexDeferredError(err)) throw err;
28838
29078
  return [];
28839
29079
  } finally {
28840
29080
  parsed.cleanup();
28841
29081
  }
28842
29082
  }
28843
29083
 
29084
+ // src/code-nav/symbol-index/imports/index.ts
29085
+ init_yield_to_event_loop();
29086
+
28844
29087
  // src/code-nav/symbol-index/imports/shared.ts
28845
29088
  function pushBinding(out, filePath, workspaceFiles, moduleSpecifier, localName, sourceName, importKind, nameNode) {
28846
29089
  if (!localName) return;
@@ -29209,6 +29452,7 @@ async function extractImportBindingsFromSource(filePath, source, workspaceFiles)
29209
29452
  var MAX_INDEX_FILE_BYTES = 512 * 1024;
29210
29453
 
29211
29454
  // src/code-nav/symbol-index/build/workspace-files.ts
29455
+ init_normalize_resolved_path();
29212
29456
  function listWorkspaceFiles(db, workspacePath, includePath) {
29213
29457
  const files = /* @__PURE__ */ new Set([includePath.replace(/\\/g, "/")]);
29214
29458
  const normalizedWorkspace = normalizeResolvedPath(workspacePath);
@@ -29230,6 +29474,7 @@ function listWorkspaceFiles(db, workspacePath, includePath) {
29230
29474
 
29231
29475
  // src/code-nav/symbol-index/build/extract-file-symbol-data.ts
29232
29476
  async function extractFileSymbolData(resolved, relPath, workspaceFilesOverride) {
29477
+ await yieldForBridgeInteractivePriority();
29233
29478
  const absPath = path21.join(resolved, relPath);
29234
29479
  let tags = [];
29235
29480
  let source = null;
@@ -29238,15 +29483,16 @@ async function extractFileSymbolData(resolved, relPath, workspaceFilesOverride)
29238
29483
  const stat2 = await fs19.promises.stat(absPath);
29239
29484
  if (stat2.isFile() && stat2.size <= MAX_INDEX_FILE_BYTES) {
29240
29485
  source = await fs19.promises.readFile(absPath, "utf8");
29241
- await yieldToEventLoop();
29486
+ await yieldForBridgeInteractivePriority();
29242
29487
  tags = await extractTagsFromSource(relPath, source);
29243
29488
  }
29244
- } catch {
29489
+ } catch (err) {
29490
+ if (isSymbolIndexDeferredError(err)) throw err;
29245
29491
  tags = [];
29246
29492
  source = null;
29247
29493
  }
29248
29494
  }
29249
- await yieldToEventLoop();
29495
+ await yieldForBridgeInteractivePriority();
29250
29496
  const workspaceFiles = workspaceFilesOverride ?? await withCodeNavCacheSqlite((db) => listWorkspaceFiles(db, resolved, relPath));
29251
29497
  const imports = source != null ? await extractImportBindingsFromSource(relPath, source, workspaceFiles) : [];
29252
29498
  const yieldState = createCodeNavYieldState();
@@ -29257,12 +29503,9 @@ async function extractFileSymbolData(resolved, relPath, workspaceFilesOverride)
29257
29503
  };
29258
29504
  }
29259
29505
 
29260
- // src/code-nav/symbol-index/build/ensure-symbol-index-file.ts
29261
- var MAX_IMPORT_PREFETCH_COUNT = 8;
29262
- function normalizeRelPath3(filePath) {
29263
- return filePath.replace(/\\/g, "/").replace(/^\/+/, "");
29264
- }
29506
+ // src/code-nav/symbol-index/build/index-one-symbol-file-for-build.ts
29265
29507
  async function indexOneSymbolFileForBuild(resolved, relPath, workspaceFiles) {
29508
+ await yieldForBridgeInteractivePriority();
29266
29509
  const data = await extractFileSymbolData(resolved, relPath, workspaceFiles);
29267
29510
  let entry = {
29268
29511
  relPath,
@@ -29271,7 +29514,7 @@ async function indexOneSymbolFileForBuild(resolved, relPath, workspaceFiles) {
29271
29514
  imports: data.imports
29272
29515
  };
29273
29516
  if (data.imports.some((binding) => binding.importKind === "star")) {
29274
- await yieldToEventLoop();
29517
+ await yieldForBridgeInteractivePriority();
29275
29518
  entry = await withCodeNavCacheSqlite((db) => {
29276
29519
  const ctx = getSymbolIndexParentContext(db, resolved);
29277
29520
  if (ctx == null) return entry;
@@ -29281,13 +29524,30 @@ async function indexOneSymbolFileForBuild(resolved, relPath, workspaceFiles) {
29281
29524
  entry.source = data.source;
29282
29525
  }
29283
29526
  await withSymbolIndexSqliteLock(async () => {
29284
- await yieldToEventLoop();
29527
+ await yieldForBridgeInteractivePriority();
29285
29528
  await persistSymbolIndexFileAsync(resolved, relPath, entry.source, entry.tags, entry.imports);
29286
29529
  });
29287
29530
  }
29531
+
29532
+ // src/code-nav/symbol-index/build/normalize-symbol-index-rel-path.ts
29533
+ function normalizeSymbolIndexRelPath(filePath) {
29534
+ return filePath.replace(/\\/g, "/").replace(/^\/+/, "");
29535
+ }
29536
+
29537
+ // src/code-nav/symbol-index/build/register-symbol-index-parent.ts
29538
+ init_normalize_resolved_path();
29539
+ async function registerSymbolIndexParentAsync(parentPath) {
29540
+ const resolved = normalizeResolvedPath(parentPath);
29541
+ await withCodeNavCacheSqlite((db) => {
29542
+ upsertSymbolIndexParentPath(db, resolved);
29543
+ });
29544
+ }
29545
+
29546
+ // src/code-nav/symbol-index/build/ensure-symbol-index-file.ts
29547
+ var MAX_IMPORT_PREFETCH_COUNT = 8;
29288
29548
  async function ensureSymbolIndexFileAsync(parentPath, filePath, opts) {
29289
29549
  const resolved = normalizeResolvedPath(parentPath);
29290
- const relPath = normalizeRelPath3(filePath);
29550
+ const relPath = normalizeSymbolIndexRelPath(filePath);
29291
29551
  if (!relPath) return false;
29292
29552
  const importDepth = opts?.importDepth ?? 0;
29293
29553
  await withCodeNavCacheSqlite((db) => {
@@ -29302,7 +29562,7 @@ async function ensureSymbolIndexFileAsync(parentPath, filePath, opts) {
29302
29562
  MAX_IMPORT_PREFETCH_COUNT
29303
29563
  );
29304
29564
  for (const target of targets) {
29305
- await yieldToEventLoop();
29565
+ await yieldForBridgeInteractivePriority();
29306
29566
  if (!await symbolIndexFileIsReadyAsync(resolved, target)) {
29307
29567
  await ensureSymbolIndexFileAsync(resolved, target, { importDepth: importDepth - 1 });
29308
29568
  }
@@ -29310,18 +29570,12 @@ async function ensureSymbolIndexFileAsync(parentPath, filePath, opts) {
29310
29570
  }
29311
29571
  return await symbolIndexFileIsReadyAsync(resolved, relPath);
29312
29572
  }
29313
- async function registerSymbolIndexParentAsync(parentPath) {
29314
- const resolved = normalizeResolvedPath(parentPath);
29315
- await withCodeNavCacheSqlite((db) => {
29316
- upsertSymbolIndexParentPath(db, resolved);
29317
- });
29318
- }
29319
29573
 
29320
29574
  // src/code-nav/symbol-index/build/build-symbol-index.ts
29321
29575
  var SYMBOL_PARENT_CLEAR_BATCH_SIZE = 256;
29322
29576
  async function buildSymbolIndexAsync(parentPath) {
29323
29577
  const resolved = normalizeResolvedPath(parentPath);
29324
- await yieldToEventLoop();
29578
+ await yieldForBridgeInteractivePriority();
29325
29579
  let clearRemaining = true;
29326
29580
  while (clearRemaining) {
29327
29581
  await withSymbolIndexSqliteLock(async () => {
@@ -29333,7 +29587,7 @@ async function buildSymbolIndexAsync(parentPath) {
29333
29587
  })
29334
29588
  );
29335
29589
  });
29336
- if (clearRemaining) await yieldToEventLoop();
29590
+ if (clearRemaining) await yieldForBridgeInteractivePriority();
29337
29591
  }
29338
29592
  const workspaceFiles = /* @__PURE__ */ new Set();
29339
29593
  const walkState = createWalkYieldState();
@@ -29356,10 +29610,17 @@ async function buildSymbolIndexAsync(parentPath) {
29356
29610
  },
29357
29611
  walkState
29358
29612
  );
29359
- await yieldToEventLoop();
29613
+ await yieldForBridgeInteractivePriority();
29360
29614
  return { fileCount, tagCount: 0 };
29361
29615
  }
29362
29616
 
29617
+ // src/code-nav/symbol-index/build/ensure-symbol-index.ts
29618
+ init_bridge_root();
29619
+ init_normalize_resolved_path();
29620
+
29621
+ // src/code-nav/symbol-index/scheduler/task-queue-enqueue.ts
29622
+ init_normalize_resolved_path();
29623
+
29363
29624
  // src/code-nav/symbol-index/scheduler/task-priority-heap.ts
29364
29625
  function higherPriority(a, b) {
29365
29626
  return a.priority > b.priority;
@@ -29417,122 +29678,185 @@ function symbolIndexTaskKey(parentPath, filePath) {
29417
29678
  return `${parentPath}\0${filePath}`;
29418
29679
  }
29419
29680
 
29420
- // src/code-nav/symbol-index/scheduler/task-queue.ts
29421
- var pending = /* @__PURE__ */ new Map();
29422
- var heap = new SymbolIndexTaskPriorityHeap();
29681
+ // src/code-nav/symbol-index/scheduler/task-queue-store.ts
29682
+ var pendingSymbolIndexTasks = /* @__PURE__ */ new Map();
29683
+ var symbolIndexTaskHeap = new SymbolIndexTaskPriorityHeap();
29423
29684
  var latestActiveSequenceByParent = /* @__PURE__ */ new Map();
29424
- var workerRunning = false;
29685
+ var symbolIndexWorkerRunning = false;
29686
+ function setSymbolIndexWorkerRunning(running) {
29687
+ symbolIndexWorkerRunning = running;
29688
+ }
29689
+ function deferBackgroundSymbolIndexTasks() {
29690
+ if (pendingSymbolIndexTasks.size === 0) return;
29691
+ pendingSymbolIndexTasks.clear();
29692
+ symbolIndexTaskHeap.clear();
29693
+ }
29694
+ registerFileBrowserRequestStartListener(() => {
29695
+ deferBackgroundSymbolIndexTasks();
29696
+ });
29425
29697
  function taskMatchesCurrentPending(task) {
29426
- const current = pending.get(symbolIndexTaskKey(task.parentPath, task.filePath));
29698
+ const current = pendingSymbolIndexTasks.get(symbolIndexTaskKey(task.parentPath, task.filePath));
29427
29699
  return current === task;
29428
29700
  }
29429
- function pickNextTask() {
29430
- while (heap.size > 0) {
29431
- const task = heap.pop();
29701
+ function pickNextSymbolIndexTask() {
29702
+ while (symbolIndexTaskHeap.size > 0) {
29703
+ const task = symbolIndexTaskHeap.pop();
29432
29704
  if (task == null || !taskMatchesCurrentPending(task)) continue;
29433
29705
  return task;
29434
29706
  }
29435
29707
  return void 0;
29436
29708
  }
29709
+ function addPendingSymbolIndexTask(task) {
29710
+ const key = symbolIndexTaskKey(task.parentPath, task.filePath);
29711
+ const existing = pendingSymbolIndexTasks.get(key);
29712
+ if (existing != null && existing.priority >= task.priority) return false;
29713
+ pendingSymbolIndexTasks.set(key, task);
29714
+ symbolIndexTaskHeap.push(task);
29715
+ return true;
29716
+ }
29717
+ function clearSymbolIndexHeapIfEmpty() {
29718
+ if (pendingSymbolIndexTasks.size === 0) symbolIndexTaskHeap.clear();
29719
+ }
29720
+
29721
+ // src/code-nav/symbol-index/scheduler/task-queue-worker.ts
29437
29722
  async function runWorker() {
29438
- if (workerRunning) return;
29439
- workerRunning = true;
29723
+ if (symbolIndexWorkerRunning) return;
29724
+ setSymbolIndexWorkerRunning(true);
29440
29725
  try {
29441
29726
  const yieldState = createCodeNavYieldState();
29442
- while (pending.size > 0) {
29443
- const task = pickNextTask();
29727
+ while (pendingSymbolIndexTasks.size > 0) {
29728
+ await yieldForBridgeInteractivePriority();
29729
+ const task = pickNextSymbolIndexTask();
29444
29730
  if (task == null) break;
29445
- pending.delete(symbolIndexTaskKey(task.parentPath, task.filePath));
29731
+ pendingSymbolIndexTasks.delete(symbolIndexTaskKey(task.parentPath, task.filePath));
29446
29732
  await yieldDuringCodeNavWork(yieldState);
29447
29733
  const latestActiveSequence = latestActiveSequenceByParent.get(task.parentPath);
29448
29734
  if (latestActiveSequence != null && task.sequence != null && task.sequence < latestActiveSequence) {
29449
29735
  continue;
29450
29736
  }
29451
29737
  if (!await symbolIndexFileIsReadyAsync(task.parentPath, task.filePath)) {
29452
- await ensureSymbolIndexFileAsync(task.parentPath, task.filePath);
29738
+ try {
29739
+ await ensureSymbolIndexFileAsync(task.parentPath, task.filePath);
29740
+ } catch (err) {
29741
+ if (isSymbolIndexDeferredError(err)) {
29742
+ if (addPendingSymbolIndexTask(task)) void runWorker();
29743
+ continue;
29744
+ }
29745
+ throw err;
29746
+ }
29453
29747
  }
29454
- await yieldToEventLoop();
29748
+ await yieldForBridgeInteractivePriority();
29455
29749
  }
29456
29750
  } finally {
29457
- if (pending.size === 0) heap.clear();
29458
- workerRunning = false;
29459
- if (pending.size > 0) void runWorker();
29751
+ clearSymbolIndexHeapIfEmpty();
29752
+ setSymbolIndexWorkerRunning(false);
29753
+ if (pendingSymbolIndexTasks.size > 0) void runWorker();
29460
29754
  }
29461
29755
  }
29756
+ function kickSymbolIndexWorker() {
29757
+ void runWorker();
29758
+ }
29759
+
29760
+ // src/code-nav/symbol-index/scheduler/task-queue-enqueue.ts
29462
29761
  function enqueueSymbolIndexTask(parentPath, filePath, priority, sequence) {
29463
29762
  const normalizedParent = normalizeResolvedPath(parentPath);
29464
29763
  const normalizedFile = filePath.replace(/\\/g, "/").replace(/^\/+/, "");
29465
29764
  if (!normalizedFile) return;
29466
- const key = symbolIndexTaskKey(normalizedParent, normalizedFile);
29467
- const existing = pending.get(key);
29468
- if (existing != null && existing.priority >= priority) return;
29469
- const task = { parentPath: normalizedParent, filePath: normalizedFile, priority, sequence };
29470
- pending.set(key, task);
29471
- heap.push(task);
29472
- void runWorker();
29765
+ const added = addPendingSymbolIndexTask({
29766
+ parentPath: normalizedParent,
29767
+ filePath: normalizedFile,
29768
+ priority,
29769
+ sequence
29770
+ });
29771
+ if (added) kickSymbolIndexWorker();
29473
29772
  }
29474
29773
  function markLatestActiveSymbolIndexTask(parentPath, sequence) {
29475
29774
  const normalizedParent = normalizeResolvedPath(parentPath);
29476
29775
  const existing = latestActiveSequenceByParent.get(normalizedParent);
29477
29776
  if (existing != null && existing >= sequence) return;
29478
29777
  latestActiveSequenceByParent.set(normalizedParent, sequence);
29479
- for (const [key, task] of pending) {
29778
+ for (const [key, task] of pendingSymbolIndexTasks) {
29480
29779
  if (task.parentPath === normalizedParent && task.sequence != null && task.sequence < sequence) {
29481
- pending.delete(key);
29780
+ pendingSymbolIndexTasks.delete(key);
29482
29781
  }
29483
29782
  }
29484
- if (pending.size === 0) heap.clear();
29783
+ if (pendingSymbolIndexTasks.size === 0) symbolIndexTaskHeap.clear();
29485
29784
  }
29486
29785
 
29487
- // src/code-nav/symbol-index/scheduler/symbol-index-scheduler.ts
29786
+ // src/code-nav/symbol-index/scheduler/symbol-index-warmup.ts
29787
+ init_normalize_resolved_path();
29488
29788
  var requestSeq = 0;
29489
29789
  var warmupSeq = 0;
29490
- var warmupScheduled = /* @__PURE__ */ new Set();
29491
29790
  var warmupCompleted = /* @__PURE__ */ new Set();
29791
+ var pendingWarmupParents = /* @__PURE__ */ new Set();
29792
+ var warmupWalkInProgress = /* @__PURE__ */ new Set();
29793
+ var WARMUP_IDLE_MS = 3e3;
29794
+ var warmupIdleTimer = null;
29795
+ function scheduleWarmupWhenIdle() {
29796
+ if (warmupIdleTimer != null) clearTimeout(warmupIdleTimer);
29797
+ warmupIdleTimer = setTimeout(() => {
29798
+ warmupIdleTimer = null;
29799
+ if (fileBrowserRequestInFlight()) {
29800
+ scheduleWarmupWhenIdle();
29801
+ return;
29802
+ }
29803
+ for (const parentPath of [...pendingWarmupParents]) {
29804
+ void runWarmupWalk(parentPath);
29805
+ }
29806
+ }, WARMUP_IDLE_MS);
29807
+ }
29808
+ registerFileBrowserActivityListener(() => {
29809
+ if (pendingWarmupParents.size > 0) scheduleWarmupWhenIdle();
29810
+ });
29811
+ async function runWarmupWalk(resolved) {
29812
+ if (warmupCompleted.has(resolved) || warmupWalkInProgress.has(resolved)) {
29813
+ pendingWarmupParents.delete(resolved);
29814
+ return;
29815
+ }
29816
+ warmupWalkInProgress.add(resolved);
29817
+ pendingWarmupParents.delete(resolved);
29818
+ try {
29819
+ const readyFiles = await loadSymbolIndexReadyFileSet(resolved);
29820
+ const walkState = createWalkYieldState();
29821
+ const yieldState = createCodeNavYieldState();
29822
+ await walkCodeNavFilesAsync(
29823
+ resolved,
29824
+ async (relPath) => {
29825
+ await yieldDuringCodeNavWork(yieldState);
29826
+ if (!readyFiles.has(relPath)) {
29827
+ enqueueSymbolIndexTask(resolved, relPath, ++warmupSeq, requestSeq);
29828
+ }
29829
+ },
29830
+ walkState
29831
+ );
29832
+ warmupCompleted.add(resolved);
29833
+ } finally {
29834
+ warmupWalkInProgress.delete(resolved);
29835
+ }
29836
+ }
29837
+
29838
+ // src/code-nav/symbol-index/scheduler/symbol-index-scheduler.ts
29839
+ var requestSeq2 = 0;
29492
29840
  function scheduleSymbolIndexFile(parentPath, filePath) {
29493
- const sequence = ++requestSeq;
29841
+ const sequence = ++requestSeq2;
29494
29842
  markLatestActiveSymbolIndexTask(parentPath, sequence);
29495
29843
  enqueueSymbolIndexTask(parentPath, filePath, 1e6 + sequence, sequence);
29496
29844
  }
29497
29845
  function scheduleSymbolIndexImportNeighbors(parentPath, filePaths) {
29498
- let priority = 5e5 + requestSeq;
29846
+ let priority = 5e5 + requestSeq2;
29499
29847
  for (const filePath of filePaths) {
29500
- enqueueSymbolIndexTask(parentPath, filePath, priority, requestSeq);
29848
+ enqueueSymbolIndexTask(parentPath, filePath, priority, requestSeq2);
29501
29849
  priority -= 1;
29502
29850
  }
29503
29851
  }
29504
- function scheduleSymbolIndexWarmup(parentPath) {
29505
- const resolved = normalizeResolvedPath(parentPath);
29506
- if (warmupCompleted.has(resolved)) return;
29507
- if (warmupScheduled.has(resolved)) return;
29508
- warmupScheduled.add(resolved);
29509
- setImmediate(() => {
29510
- void (async () => {
29511
- try {
29512
- const readyFiles = await loadSymbolIndexReadyFileSet(resolved);
29513
- const walkState = createWalkYieldState();
29514
- const yieldState = createCodeNavYieldState();
29515
- await walkCodeNavFilesAsync(
29516
- resolved,
29517
- async (relPath) => {
29518
- await yieldDuringCodeNavWork(yieldState);
29519
- if (!readyFiles.has(relPath)) {
29520
- enqueueSymbolIndexTask(resolved, relPath, ++warmupSeq, requestSeq);
29521
- }
29522
- },
29523
- walkState
29524
- );
29525
- warmupCompleted.add(resolved);
29526
- } finally {
29527
- warmupScheduled.delete(resolved);
29528
- }
29529
- })();
29530
- });
29531
- }
29852
+
29853
+ // src/code-nav/symbol-index/build/update-symbol-index-file.ts
29854
+ init_normalize_resolved_path();
29855
+ init_yield_to_event_loop();
29532
29856
 
29533
29857
  // src/code-nav/symbol-index/lifecycle/normalize-symbol-index-path.ts
29534
29858
  import path22 from "node:path";
29535
- function normalizeSymbolIndexRelPath(parentPath, changedPath) {
29859
+ function normalizeSymbolIndexRelPath2(parentPath, changedPath) {
29536
29860
  const resolvedParent = path22.resolve(parentPath);
29537
29861
  const abs = path22.isAbsolute(changedPath) ? path22.resolve(changedPath) : path22.resolve(resolvedParent, changedPath);
29538
29862
  const rel = path22.relative(resolvedParent, abs).replace(/\\/g, "/");
@@ -29542,7 +29866,7 @@ function normalizeSymbolIndexRelPath(parentPath, changedPath) {
29542
29866
 
29543
29867
  // src/code-nav/symbol-index/build/update-symbol-index-file.ts
29544
29868
  async function updateSymbolIndexForFile(parentPath, changedPath) {
29545
- const relPath = normalizeSymbolIndexRelPath(parentPath, changedPath);
29869
+ const relPath = normalizeSymbolIndexRelPath2(parentPath, changedPath);
29546
29870
  if (relPath == null) return;
29547
29871
  const resolved = normalizeResolvedPath(parentPath);
29548
29872
  const { source, tags, imports } = await extractFileSymbolData(resolved, relPath);
@@ -29552,7 +29876,7 @@ async function updateSymbolIndexForFile(parentPath, changedPath) {
29552
29876
  });
29553
29877
  }
29554
29878
  async function removeSymbolIndexForFile(parentPath, changedPath) {
29555
- const relPath = normalizeSymbolIndexRelPath(parentPath, changedPath);
29879
+ const relPath = normalizeSymbolIndexRelPath2(parentPath, changedPath);
29556
29880
  if (relPath == null) return;
29557
29881
  const resolved = normalizeResolvedPath(parentPath);
29558
29882
  await withSymbolIndexSqliteLock(async () => {
@@ -29560,6 +29884,10 @@ async function removeSymbolIndexForFile(parentPath, changedPath) {
29560
29884
  });
29561
29885
  }
29562
29886
 
29887
+ // src/code-nav/symbol-index/query/query-definitions.ts
29888
+ init_normalize_resolved_path();
29889
+ init_yield_to_event_loop();
29890
+
29563
29891
  // src/code-nav/symbol-index/sqlite/symbol-index-import-sqlite.ts
29564
29892
  function prefersTypeImport(refKind) {
29565
29893
  return refKind === "type";
@@ -30060,6 +30388,8 @@ async function queryDefinitionAt(parentPath, filePath, line, column) {
30060
30388
  }
30061
30389
 
30062
30390
  // src/code-nav/symbol-index/query/query-references.ts
30391
+ init_normalize_resolved_path();
30392
+ init_yield_to_event_loop();
30063
30393
  async function queryReferencesAt(parentPath, filePath, line, column) {
30064
30394
  await yieldToEventLoop();
30065
30395
  const resolved = normalizeResolvedPath(parentPath);
@@ -30083,6 +30413,8 @@ async function queryReferencesAt(parentPath, filePath, line, column) {
30083
30413
  }
30084
30414
 
30085
30415
  // src/code-nav/symbol-index/query/query-symbols-in-file.ts
30416
+ init_normalize_resolved_path();
30417
+ init_yield_to_event_loop();
30086
30418
  function rowToSymbolSpan(row, clickable) {
30087
30419
  return {
30088
30420
  name: row.name,
@@ -30168,6 +30500,7 @@ function createFileIndexFsWatcher(resolved, schedule) {
30168
30500
  // src/files/index/file-index-incremental-symbol-updates.ts
30169
30501
  import fs20 from "node:fs";
30170
30502
  import path23 from "node:path";
30503
+ init_yield_to_event_loop();
30171
30504
  async function applyIncrementalSymbolIndexUpdates(resolved, relPaths) {
30172
30505
  for (const rel of relPaths) {
30173
30506
  const absPath = path23.join(resolved, rel);
@@ -30191,6 +30524,7 @@ async function applyIncrementalSymbolIndexUpdates(resolved, relPaths) {
30191
30524
 
30192
30525
  // src/files/index/file-index-initial-builds.ts
30193
30526
  import path24 from "node:path";
30527
+ init_cwd();
30194
30528
  async function runInitialIndexBuilds(cwd = getBridgeRoot()) {
30195
30529
  const resolved = path24.resolve(cwd);
30196
30530
  try {
@@ -30408,6 +30742,7 @@ import * as fs21 from "node:fs";
30408
30742
  import * as path29 from "node:path";
30409
30743
 
30410
30744
  // src/paths/session-layout-paths.ts
30745
+ init_cwd();
30411
30746
  import * as path26 from "node:path";
30412
30747
  function resolveIsolatedSessionParentPathFromCheckouts(worktreePaths) {
30413
30748
  const resolved = worktreePaths.map((p) => path26.resolve(p)).filter(Boolean);
@@ -30539,6 +30874,7 @@ __export(cursor_acp_client_exports, {
30539
30874
  createCursorAcpClient: () => createCursorAcpClient,
30540
30875
  detectLocalAgentPresence: () => detectLocalAgentPresence3
30541
30876
  });
30877
+ init_cwd();
30542
30878
 
30543
30879
  // src/agents/acp/clients/cursor/cursor-spawn-command.ts
30544
30880
  function buildCursorAcpSpawnCommand(base, sessionMode) {
@@ -30570,8 +30906,8 @@ function createCursorAcpSessionContext(options) {
30570
30906
 
30571
30907
  // src/agents/acp/clients/cursor/cancel-pending-cursor-permission-requests.ts
30572
30908
  function cancelPendingCursorPermissionRequests(pendingRequests, respond) {
30573
- for (const [reqId, pending2] of [...pendingRequests.entries()]) {
30574
- if (pending2.method === "session/request_permission") {
30909
+ for (const [reqId, pending] of [...pendingRequests.entries()]) {
30910
+ if (pending.method === "session/request_permission") {
30575
30911
  respond(reqId, { outcome: { outcome: "cancelled" } });
30576
30912
  pendingRequests.delete(reqId);
30577
30913
  }
@@ -30750,8 +31086,8 @@ function handleCursorIncomingPermissionRequest(id, method, msg, deps) {
30750
31086
 
30751
31087
  // src/agents/acp/clients/cursor/cursor-incoming-resolve-request.ts
30752
31088
  function resolveCursorIncomingRequest(pendingRequests, respond, requestId, result) {
30753
- const pending2 = pendingRequests.get(requestId);
30754
- const payload = pending2?.method === "session/request_permission" ? enrichAcpPermissionRpcResultFromRequestParams(result, pending2.params) : result;
31089
+ const pending = pendingRequests.get(requestId);
31090
+ const payload = pending?.method === "session/request_permission" ? enrichAcpPermissionRpcResultFromRequestParams(result, pending.params) : result;
30755
31091
  respond(requestId, payload);
30756
31092
  pendingRequests.delete(requestId);
30757
31093
  }
@@ -30888,25 +31224,25 @@ function createCursorJsonRpcInboundRespond(stdin) {
30888
31224
 
30889
31225
  // src/agents/acp/clients/cursor/cursor-json-rpc-outbound.ts
30890
31226
  function createCursorJsonRpcOutboundPending() {
30891
- const pending2 = /* @__PURE__ */ new Map();
31227
+ const pending = /* @__PURE__ */ new Map();
30892
31228
  let nextId = 1;
30893
31229
  function allocateId() {
30894
31230
  return nextId++;
30895
31231
  }
30896
31232
  function register(id, waiter) {
30897
- pending2.set(id, waiter);
31233
+ pending.set(id, waiter);
30898
31234
  }
30899
31235
  function settleResponse(id, msg) {
30900
- const waiter = pending2.get(id);
31236
+ const waiter = pending.get(id);
30901
31237
  if (!waiter) return false;
30902
- pending2.delete(id);
31238
+ pending.delete(id);
30903
31239
  if (msg.error) waiter.reject(msg.error);
30904
31240
  else waiter.resolve(msg.result);
30905
31241
  return true;
30906
31242
  }
30907
31243
  function rejectOnWriteError(id, err) {
30908
- const waiter = pending2.get(id);
30909
- pending2.delete(id);
31244
+ const waiter = pending.get(id);
31245
+ pending.delete(id);
30910
31246
  waiter?.reject(err);
30911
31247
  }
30912
31248
  return { allocateId, register, settleResponse, rejectOnWriteError };
@@ -32426,8 +32762,8 @@ async function execGitFile(args, options) {
32426
32762
  }
32427
32763
 
32428
32764
  // src/git/changes/parse/normalize-git-diff-path.ts
32429
- function normalizeGitDiffPath(path79) {
32430
- return path79.replace(/\\/g, "/").replace(/\/ +/g, "/").trim();
32765
+ function normalizeGitDiffPath(path82) {
32766
+ return path82.replace(/\\/g, "/").replace(/\/ +/g, "/").trim();
32431
32767
  }
32432
32768
 
32433
32769
  // src/git/changes/parse/parse-name-status-entries.ts
@@ -34043,8 +34379,10 @@ async function createBridgeAccessState(options = {}) {
34043
34379
 
34044
34380
  // src/agents/capabilities/warmup-agent-capabilities-on-connect.ts
34045
34381
  import * as path35 from "node:path";
34382
+ init_cwd();
34046
34383
 
34047
34384
  // src/agents/detect-local-agent-types.ts
34385
+ init_yield_to_event_loop();
34048
34386
  var LOCAL_AGENT_ACP_MODULES = [
34049
34387
  cursor_acp_client_exports,
34050
34388
  codex_acp_client_exports,
@@ -34073,6 +34411,9 @@ async function detectLocalAgentTypes() {
34073
34411
  }
34074
34412
  }
34075
34413
 
34414
+ // src/agents/capabilities/probe-agent-capabilities-for-types.ts
34415
+ init_yield_to_event_loop();
34416
+
34076
34417
  // src/sqlite/hash-json-sha256.ts
34077
34418
  import { createHash } from "node:crypto";
34078
34419
  function hashJsonUtf8Sha256(value) {
@@ -34249,6 +34590,9 @@ async function probeAgentCapabilitiesForDetectedTypes(params) {
34249
34590
  return changedCount;
34250
34591
  }
34251
34592
 
34593
+ // src/agents/capabilities/warmup-agent-capabilities-on-connect.ts
34594
+ init_yield_to_event_loop();
34595
+
34252
34596
  // src/agents/capabilities/agent-capability-warmup-run.ts
34253
34597
  var warmupEpoch = 0;
34254
34598
  function cancelInFlightAgentCapabilityWarmup() {
@@ -34390,6 +34734,7 @@ async function createBridgeAccessAndAcp(options) {
34390
34734
  }
34391
34735
 
34392
34736
  // src/connection/create-bridge-preview-stack.ts
34737
+ init_cwd();
34393
34738
  import * as path38 from "node:path";
34394
34739
 
34395
34740
  // src/preview-environments/manager/firehose-messages.ts
@@ -35678,11 +36023,11 @@ function tryConsumeBinaryProxyBody(raw, deps) {
35678
36023
  if (!PROXY_ID_RE.test(id)) return false;
35679
36024
  const body = raw.slice(PROXY_ID_BYTES);
35680
36025
  const bodyBytes = body.length > 0 ? new Uint8Array(body) : new Uint8Array(0);
35681
- const pending2 = deps.pendingProxyBody.get(id);
35682
- if (pending2) {
36026
+ const pending = deps.pendingProxyBody.get(id);
36027
+ if (pending) {
35683
36028
  deps.pendingProxyBody.delete(id);
35684
36029
  deps.startStreamingProxy({
35685
- ...pending2.pr,
36030
+ ...pending.pr,
35686
36031
  body: bodyBytes.length > 0 ? bodyBytes : void 0
35687
36032
  });
35688
36033
  return true;
@@ -36044,7 +36389,11 @@ function createBridgeMessageDeps(params) {
36044
36389
  };
36045
36390
  }
36046
36391
 
36392
+ // src/connection/create-bridge-local-reports.ts
36393
+ init_cwd();
36394
+
36047
36395
  // src/skills/discovery/skill-discovery-roots.ts
36396
+ init_yield_to_event_loop();
36048
36397
  var SKILL_DISCOVERY_ROOTS = [".agents/skills", ".claude/skills", ".cursor/skills", "skills"];
36049
36398
  async function yieldSkillDiscoveryWork(entryCount) {
36050
36399
  if (entryCount > 0 && entryCount % INDEX_WORK_YIELD_EVERY === 0) {
@@ -36235,9 +36584,9 @@ function createBridgeHeartbeatController(params) {
36235
36584
  if (awaitingSeq === null) return;
36236
36585
  if (!Number.isFinite(seq)) return;
36237
36586
  const ack = Math.trunc(seq);
36238
- const pending2 = awaitingSeq;
36239
- if (ack < pending2) return;
36240
- if (ack === pending2) {
36587
+ const pending = awaitingSeq;
36588
+ if (ack < pending) return;
36589
+ if (ack === pending) {
36241
36590
  const rtt = Date.now() - sentAtMs;
36242
36591
  if (Number.isFinite(rtt) && rtt >= 0 && rtt < 6e5) {
36243
36592
  rttSamples.push(rtt);
@@ -36369,6 +36718,7 @@ function allocateDirNameForLauncherCwd(layout, bridgeRootPath2) {
36369
36718
  }
36370
36719
 
36371
36720
  // src/worktrees/manager/session-worktree-cache.ts
36721
+ init_normalize_resolved_path();
36372
36722
  var SessionWorktreeCache = class {
36373
36723
  sessionRepoCheckoutPaths = /* @__PURE__ */ new Map();
36374
36724
  sessionParentPathBySession = /* @__PURE__ */ new Map();
@@ -36409,6 +36759,9 @@ function createSessionWorktreeManagerContext(options) {
36409
36759
  };
36410
36760
  }
36411
36761
 
36762
+ // src/worktrees/manager/git/commit-session-worktree.ts
36763
+ init_cwd();
36764
+
36412
36765
  // ../../node_modules/.pnpm/simple-git@3.32.3/node_modules/simple-git/dist/esm/index.js
36413
36766
  var import_file_exists = __toESM(require_dist(), 1);
36414
36767
  var import_debug = __toESM(require_src(), 1);
@@ -36446,8 +36799,8 @@ function pathspec(...paths) {
36446
36799
  cache.set(key, paths);
36447
36800
  return key;
36448
36801
  }
36449
- function isPathSpec(path79) {
36450
- return path79 instanceof String && cache.has(path79);
36802
+ function isPathSpec(path82) {
36803
+ return path82 instanceof String && cache.has(path82);
36451
36804
  }
36452
36805
  function toPaths(pathSpec) {
36453
36806
  return cache.get(pathSpec) || [];
@@ -36536,8 +36889,8 @@ function toLinesWithContent(input = "", trimmed2 = true, separator = "\n") {
36536
36889
  function forEachLineWithContent(input, callback) {
36537
36890
  return toLinesWithContent(input, true).map((line) => callback(line));
36538
36891
  }
36539
- function folderExists(path79) {
36540
- return (0, import_file_exists.exists)(path79, import_file_exists.FOLDER);
36892
+ function folderExists(path82) {
36893
+ return (0, import_file_exists.exists)(path82, import_file_exists.FOLDER);
36541
36894
  }
36542
36895
  function append(target, item) {
36543
36896
  if (Array.isArray(target)) {
@@ -36941,8 +37294,8 @@ function checkIsRepoRootTask() {
36941
37294
  commands,
36942
37295
  format: "utf-8",
36943
37296
  onError,
36944
- parser(path79) {
36945
- return /^\.(git)?$/.test(path79.trim());
37297
+ parser(path82) {
37298
+ return /^\.(git)?$/.test(path82.trim());
36946
37299
  }
36947
37300
  };
36948
37301
  }
@@ -37376,11 +37729,11 @@ function parseGrep(grep) {
37376
37729
  const paths = /* @__PURE__ */ new Set();
37377
37730
  const results = {};
37378
37731
  forEachLineWithContent(grep, (input) => {
37379
- const [path79, line, preview] = input.split(NULL);
37380
- paths.add(path79);
37381
- (results[path79] = results[path79] || []).push({
37732
+ const [path82, line, preview] = input.split(NULL);
37733
+ paths.add(path82);
37734
+ (results[path82] = results[path82] || []).push({
37382
37735
  line: asNumber(line),
37383
- path: path79,
37736
+ path: path82,
37384
37737
  preview
37385
37738
  });
37386
37739
  });
@@ -38145,14 +38498,14 @@ var init_hash_object = __esm2({
38145
38498
  init_task();
38146
38499
  }
38147
38500
  });
38148
- function parseInit(bare, path79, text) {
38501
+ function parseInit(bare, path82, text) {
38149
38502
  const response = String(text).trim();
38150
38503
  let result;
38151
38504
  if (result = initResponseRegex.exec(response)) {
38152
- return new InitSummary(bare, path79, false, result[1]);
38505
+ return new InitSummary(bare, path82, false, result[1]);
38153
38506
  }
38154
38507
  if (result = reInitResponseRegex.exec(response)) {
38155
- return new InitSummary(bare, path79, true, result[1]);
38508
+ return new InitSummary(bare, path82, true, result[1]);
38156
38509
  }
38157
38510
  let gitDir = "";
38158
38511
  const tokens = response.split(" ");
@@ -38163,7 +38516,7 @@ function parseInit(bare, path79, text) {
38163
38516
  break;
38164
38517
  }
38165
38518
  }
38166
- return new InitSummary(bare, path79, /^re/i.test(response), gitDir);
38519
+ return new InitSummary(bare, path82, /^re/i.test(response), gitDir);
38167
38520
  }
38168
38521
  var InitSummary;
38169
38522
  var initResponseRegex;
@@ -38172,9 +38525,9 @@ var init_InitSummary = __esm2({
38172
38525
  "src/lib/responses/InitSummary.ts"() {
38173
38526
  "use strict";
38174
38527
  InitSummary = class {
38175
- constructor(bare, path79, existing, gitDir) {
38528
+ constructor(bare, path82, existing, gitDir) {
38176
38529
  this.bare = bare;
38177
- this.path = path79;
38530
+ this.path = path82;
38178
38531
  this.existing = existing;
38179
38532
  this.gitDir = gitDir;
38180
38533
  }
@@ -38186,7 +38539,7 @@ var init_InitSummary = __esm2({
38186
38539
  function hasBareCommand(command) {
38187
38540
  return command.includes(bareCommand);
38188
38541
  }
38189
- function initTask(bare = false, path79, customArgs) {
38542
+ function initTask(bare = false, path82, customArgs) {
38190
38543
  const commands = ["init", ...customArgs];
38191
38544
  if (bare && !hasBareCommand(commands)) {
38192
38545
  commands.splice(1, 0, bareCommand);
@@ -38195,7 +38548,7 @@ function initTask(bare = false, path79, customArgs) {
38195
38548
  commands,
38196
38549
  format: "utf-8",
38197
38550
  parser(text) {
38198
- return parseInit(commands.includes("--bare"), path79, text);
38551
+ return parseInit(commands.includes("--bare"), path82, text);
38199
38552
  }
38200
38553
  };
38201
38554
  }
@@ -39011,12 +39364,12 @@ var init_FileStatusSummary = __esm2({
39011
39364
  "use strict";
39012
39365
  fromPathRegex = /^(.+)\0(.+)$/;
39013
39366
  FileStatusSummary = class {
39014
- constructor(path79, index, working_dir) {
39015
- this.path = path79;
39367
+ constructor(path82, index, working_dir) {
39368
+ this.path = path82;
39016
39369
  this.index = index;
39017
39370
  this.working_dir = working_dir;
39018
39371
  if (index === "R" || working_dir === "R") {
39019
- const detail = fromPathRegex.exec(path79) || [null, path79, path79];
39372
+ const detail = fromPathRegex.exec(path82) || [null, path82, path82];
39020
39373
  this.from = detail[2] || "";
39021
39374
  this.path = detail[1] || "";
39022
39375
  }
@@ -39047,14 +39400,14 @@ function splitLine(result, lineStr) {
39047
39400
  default:
39048
39401
  return;
39049
39402
  }
39050
- function data(index, workingDir, path79) {
39403
+ function data(index, workingDir, path82) {
39051
39404
  const raw = `${index}${workingDir}`;
39052
39405
  const handler = parsers6.get(raw);
39053
39406
  if (handler) {
39054
- handler(result, path79);
39407
+ handler(result, path82);
39055
39408
  }
39056
39409
  if (raw !== "##" && raw !== "!!") {
39057
- result.files.push(new FileStatusSummary(path79, index, workingDir));
39410
+ result.files.push(new FileStatusSummary(path82, index, workingDir));
39058
39411
  }
39059
39412
  }
39060
39413
  }
@@ -39363,9 +39716,9 @@ var init_simple_git_api = __esm2({
39363
39716
  next
39364
39717
  );
39365
39718
  }
39366
- hashObject(path79, write) {
39719
+ hashObject(path82, write) {
39367
39720
  return this._runTask(
39368
- hashObjectTask(path79, write === true),
39721
+ hashObjectTask(path82, write === true),
39369
39722
  trailingFunctionArgument(arguments)
39370
39723
  );
39371
39724
  }
@@ -39718,8 +40071,8 @@ var init_branch = __esm2({
39718
40071
  }
39719
40072
  });
39720
40073
  function toPath(input) {
39721
- const path79 = input.trim().replace(/^["']|["']$/g, "");
39722
- return path79 && normalize3(path79);
40074
+ const path82 = input.trim().replace(/^["']|["']$/g, "");
40075
+ return path82 && normalize3(path82);
39723
40076
  }
39724
40077
  var parseCheckIgnore;
39725
40078
  var init_CheckIgnore = __esm2({
@@ -40033,8 +40386,8 @@ __export2(sub_module_exports, {
40033
40386
  subModuleTask: () => subModuleTask,
40034
40387
  updateSubModuleTask: () => updateSubModuleTask
40035
40388
  });
40036
- function addSubModuleTask(repo, path79) {
40037
- return subModuleTask(["add", repo, path79]);
40389
+ function addSubModuleTask(repo, path82) {
40390
+ return subModuleTask(["add", repo, path82]);
40038
40391
  }
40039
40392
  function initSubModuleTask(customArgs) {
40040
40393
  return subModuleTask(["init", ...customArgs]);
@@ -40367,8 +40720,8 @@ var require_git = __commonJS2({
40367
40720
  }
40368
40721
  return this._runTask(straightThroughStringTask2(command, this._trimmed), next);
40369
40722
  };
40370
- Git2.prototype.submoduleAdd = function(repo, path79, then) {
40371
- return this._runTask(addSubModuleTask2(repo, path79), trailingFunctionArgument2(arguments));
40723
+ Git2.prototype.submoduleAdd = function(repo, path82, then) {
40724
+ return this._runTask(addSubModuleTask2(repo, path82), trailingFunctionArgument2(arguments));
40372
40725
  };
40373
40726
  Git2.prototype.submoduleUpdate = function(args, then) {
40374
40727
  return this._runTask(
@@ -41104,8 +41457,8 @@ function parseNumstatEntries(lines) {
41104
41457
  }
41105
41458
  function parseNumstat(lines) {
41106
41459
  const m = /* @__PURE__ */ new Map();
41107
- for (const [path79, entry] of parseNumstatEntries(lines)) {
41108
- m.set(path79, { additions: entry.additions, deletions: entry.deletions });
41460
+ for (const [path82, entry] of parseNumstatEntries(lines)) {
41461
+ m.set(path82, { additions: entry.additions, deletions: entry.deletions });
41109
41462
  }
41110
41463
  return m;
41111
41464
  }
@@ -41303,6 +41656,7 @@ async function pushAheadOfUpstreamForPaths(paths) {
41303
41656
  }
41304
41657
 
41305
41658
  // src/worktrees/manager/resolve-commit-targets.ts
41659
+ init_cwd();
41306
41660
  function bridgeRootBinding(bridgeRoot) {
41307
41661
  return {
41308
41662
  sessionParentPath: bridgeRoot,
@@ -41388,6 +41742,7 @@ function formatRemoteDisplayLabel(remoteUrl) {
41388
41742
  }
41389
41743
 
41390
41744
  // src/git/changes/repo/get-working-tree-change-repo-details.ts
41745
+ init_cwd();
41391
41746
  import * as path51 from "node:path";
41392
41747
 
41393
41748
  // src/git/changes/repo/build-working-tree-change-repo-detail.ts
@@ -41637,6 +41992,7 @@ function createHydrateSourceLines(options) {
41637
41992
  }
41638
41993
 
41639
41994
  // src/git/changes/patch/hydrate/create-hydrate-yield.ts
41995
+ init_yield_to_event_loop();
41640
41996
  function createHydrateYield() {
41641
41997
  let processedLines = 0;
41642
41998
  return async () => {
@@ -42400,6 +42756,7 @@ function parseWorkingTreeChangeKind(value) {
42400
42756
  }
42401
42757
 
42402
42758
  // src/worktrees/manager/git/get-session-working-tree-change-file-patch.ts
42759
+ init_cwd();
42403
42760
  import * as path53 from "node:path";
42404
42761
  async function getSessionWorkingTreeChangeFilePatch(cache2, sessionId, discover, opts) {
42405
42762
  const targets = await resolveCommitTargetsAsync(sessionId, cache2, discover);
@@ -42450,6 +42807,8 @@ import * as fs35 from "node:fs";
42450
42807
  import * as fs34 from "node:fs";
42451
42808
 
42452
42809
  // src/worktrees/is-removable-session-worktree-checkout-path.ts
42810
+ init_cwd();
42811
+ init_normalize_resolved_path();
42453
42812
  import path54 from "node:path";
42454
42813
  function isBridgeRootCheckoutPath(checkoutPath) {
42455
42814
  return normalizeResolvedPath(checkoutPath) === normalizeResolvedPath(getBridgeRoot());
@@ -42550,9 +42909,13 @@ async function renameSessionWorktreeBranch(cache2, sessionId, newBranch, log2) {
42550
42909
  await renameSessionWorktreeBranches(paths, newBranch, log2);
42551
42910
  }
42552
42911
 
42912
+ // src/worktrees/manager/discover-session-binding.ts
42913
+ init_cwd();
42914
+
42553
42915
  // src/worktrees/discovery/discover-session-worktree-on-disk.ts
42554
42916
  import * as fs39 from "node:fs";
42555
42917
  import * as path60 from "node:path";
42918
+ init_yield_to_event_loop();
42556
42919
 
42557
42920
  // src/worktrees/discovery/collect-worktree-paths.ts
42558
42921
  import * as fs37 from "node:fs";
@@ -42586,6 +42949,7 @@ function shouldSkipDiskWalkEntry(name) {
42586
42949
  // src/worktrees/discovery/disk-walk-utils.ts
42587
42950
  import * as fs36 from "node:fs";
42588
42951
  import * as path56 from "node:path";
42952
+ init_yield_to_event_loop();
42589
42953
  async function yieldDuringDiskWalk(state) {
42590
42954
  state.entries++;
42591
42955
  if (state.entries % DISK_WALK_YIELD_EVERY !== 0) return true;
@@ -42775,6 +43139,7 @@ import * as path62 from "node:path";
42775
43139
 
42776
43140
  // src/worktrees/discovery/discover-legacy-binding-ascending-from-checkout.ts
42777
43141
  import * as path61 from "node:path";
43142
+ init_yield_to_event_loop();
42778
43143
  async function discoverLegacyBindingAscendingFromCheckout(sessionId, checkoutPath) {
42779
43144
  const sid = sessionId.trim();
42780
43145
  if (!sid) return null;
@@ -42892,11 +43257,16 @@ function parseSessionParent(v) {
42892
43257
  return null;
42893
43258
  }
42894
43259
 
43260
+ // src/worktrees/manager/prepare-and-remember-session-worktrees.ts
43261
+ init_cwd();
43262
+
42895
43263
  // src/worktrees/prepare-new-isolated-worktrees.ts
42896
43264
  import * as fs42 from "node:fs";
42897
43265
  import * as path64 from "node:path";
42898
43266
 
42899
43267
  // src/git/discover-repos.ts
43268
+ init_cwd();
43269
+ init_yield_to_event_loop();
42900
43270
  import * as fs41 from "node:fs";
42901
43271
  import * as path63 from "node:path";
42902
43272
  var GIT_DISCOVER_YIELD_EVERY = 32;
@@ -43124,6 +43494,7 @@ async function resolveExistingSessionParentPath(sessionId, cache2, discover) {
43124
43494
 
43125
43495
  // src/worktrees/manager/resolve-explicit-session-parent-path.ts
43126
43496
  import * as path65 from "node:path";
43497
+ init_yield_to_event_loop();
43127
43498
  async function resolveExplicitSessionParentPath(params) {
43128
43499
  const resolved = path65.resolve(params.parentPathRaw);
43129
43500
  if (parseSessionParent(params.sessionParent) !== "worktrees_root") {
@@ -43289,7 +43660,12 @@ var SessionWorktreeManager = class {
43289
43660
  }
43290
43661
  };
43291
43662
 
43663
+ // src/worktrees/manager/preview-worktree-manager.ts
43664
+ init_cwd();
43665
+
43292
43666
  // src/worktrees/discovery/discover-preview-worktree-on-disk.ts
43667
+ init_cwd();
43668
+ init_yield_to_event_loop();
43293
43669
  import * as fs43 from "node:fs";
43294
43670
  import * as path66 from "node:path";
43295
43671
  async function discoverPreviewWorktreeOnDisk(options) {
@@ -43340,6 +43716,7 @@ async function discoverPreviewWorktreeForBridge(options) {
43340
43716
  }
43341
43717
 
43342
43718
  // src/worktrees/manager/preview-worktree-cache.ts
43719
+ init_normalize_resolved_path();
43343
43720
  var PreviewWorktreeCache = class {
43344
43721
  repoCheckoutPaths = /* @__PURE__ */ new Map();
43345
43722
  parentPathByEnvironment = /* @__PURE__ */ new Map();
@@ -43452,6 +43829,7 @@ var PreviewWorktreeManager = class {
43452
43829
  };
43453
43830
 
43454
43831
  // src/worktrees/deploy/deploy-session-to-preview-environment.ts
43832
+ init_cwd();
43455
43833
  import * as path70 from "node:path";
43456
43834
 
43457
43835
  // src/git/worktrees/reset-worktree-to-branch.ts
@@ -44149,6 +44527,7 @@ async function applyPreTurnSnapshot(filePath, log2) {
44149
44527
  }
44150
44528
 
44151
44529
  // src/prompt-turn-queue/runner/run-local-revert-before-queued-prompt.ts
44530
+ init_cwd();
44152
44531
  async function runLocalRevertBeforeQueuedPrompt(next, deps) {
44153
44532
  if (next.bridgeServerState !== "requeued_with_revert") return true;
44154
44533
  const sid = next.sessionId;
@@ -44338,6 +44717,7 @@ function parseWorktreeBaseBranches(msg) {
44338
44717
  }
44339
44718
 
44340
44719
  // src/agents/acp/from-bridge/bridge-prompt-preamble.ts
44720
+ init_cwd();
44341
44721
  import { execFile as execFile8 } from "node:child_process";
44342
44722
  import { promisify as promisify9 } from "node:util";
44343
44723
  var execFileAsync7 = promisify9(execFile8);
@@ -44569,6 +44949,8 @@ var handleSkillCallMessage = (msg, { getWs, log: log2 }) => {
44569
44949
  };
44570
44950
 
44571
44951
  // src/files/resolve-file-browser-session-parent.ts
44952
+ init_normalize_resolved_path();
44953
+ init_cwd();
44572
44954
  async function resolveFileBrowserSessionParent(sessionWorktreeManager, sessionId) {
44573
44955
  const sid = sessionId?.trim();
44574
44956
  if (sid) {
@@ -44579,301 +44961,18 @@ async function resolveFileBrowserSessionParent(sessionWorktreeManager, sessionId
44579
44961
  return getBridgeRoot();
44580
44962
  }
44581
44963
 
44582
- // src/files/list-dir/index.ts
44583
- import fs48 from "node:fs";
44584
-
44585
- // src/files/ensure-under-cwd.ts
44586
- import path73 from "node:path";
44587
- function ensureUnderCwd(relativePath, cwd = getBridgeRoot()) {
44588
- const normalized = path73.normalize(relativePath).replace(/^(\.\/)+/, "");
44589
- const resolved = path73.resolve(cwd, normalized);
44590
- if (!resolved.startsWith(cwd + path73.sep) && resolved !== cwd) {
44591
- return null;
44592
- }
44593
- return resolved;
44594
- }
44595
-
44596
- // src/files/list-dir/types.ts
44597
- var LIST_DIR_YIELD_EVERY = 256;
44598
-
44599
- // src/files/list-dir/map-dir-entry.ts
44600
- import path74 from "node:path";
44601
- import fs47 from "node:fs";
44602
- async function mapDirEntry(d, relativePath, resolved) {
44603
- const entryPath = path74.join(relativePath || ".", d.name).replace(/\\/g, "/");
44604
- const fullPath = path74.join(resolved, d.name);
44605
- let isDir = d.isDirectory();
44606
- if (d.isSymbolicLink()) {
44607
- try {
44608
- const targetStat = await fs47.promises.stat(fullPath);
44609
- isDir = targetStat.isDirectory();
44610
- } catch {
44611
- isDir = false;
44612
- }
44613
- }
44614
- return {
44615
- name: d.name,
44616
- path: entryPath,
44617
- isDir,
44618
- isSymlink: d.isSymbolicLink()
44619
- };
44620
- }
44621
-
44622
- // src/files/list-dir/sort-entries.ts
44623
- function sortListEntries(entries) {
44624
- return entries.sort((a, b) => {
44625
- if (a.isDir !== b.isDir) return a.isDir ? -1 : 1;
44626
- return a.name.localeCompare(b.name, void 0, { sensitivity: "base" });
44627
- });
44628
- }
44629
-
44630
- // src/files/list-dir/index.ts
44631
- async function listDirAsync(relativePath, sessionParentPath = getBridgeRoot()) {
44632
- await yieldToEventLoop();
44633
- const resolved = ensureUnderCwd(relativePath || ".", sessionParentPath);
44634
- if (!resolved) {
44635
- return { error: "Path is outside working directory" };
44636
- }
44637
- try {
44638
- const names = await fs48.promises.readdir(resolved, { withFileTypes: true });
44639
- const entries = [];
44640
- for (let i = 0; i < names.length; i++) {
44641
- if (i > 0 && i % LIST_DIR_YIELD_EVERY === 0) {
44642
- await yieldToEventLoop();
44643
- }
44644
- entries.push(await mapDirEntry(names[i], relativePath, resolved));
44645
- }
44646
- return { entries: sortListEntries(entries) };
44647
- } catch (err) {
44648
- const message = err instanceof Error ? err.message : String(err);
44649
- return { error: message };
44650
- }
44651
- }
44652
-
44653
- // src/files/handle-file-browser-search.ts
44654
- import path75 from "node:path";
44655
- var SEARCH_LIMIT = 100;
44656
- function handleFileBrowserSearch(msg, socket, e2ee, sessionWorktreeManager) {
44657
- void (async () => {
44658
- await yieldToEventLoop();
44659
- const q = typeof msg.q === "string" ? msg.q : "";
44660
- const sessionParentPath = path75.resolve(
44661
- sessionWorktreeManager != null ? await resolveFileBrowserSessionParent(sessionWorktreeManager, msg.sessionId) : getBridgeRoot()
44662
- );
44663
- if (!await bridgeFileIndexIsPopulated(sessionParentPath)) {
44664
- const payload2 = {
44665
- type: "file_browser_search_response",
44666
- id: msg.id,
44667
- paths: [],
44668
- indexReady: false
44669
- };
44670
- sendWsMessage(socket, e2ee ? e2ee.encryptFields(payload2, ["paths"]) : payload2);
44671
- return;
44672
- }
44673
- const results = await searchBridgeFilePathsAsync(sessionParentPath, q, SEARCH_LIMIT);
44674
- const payload = {
44675
- type: "file_browser_search_response",
44676
- id: msg.id,
44677
- paths: results,
44678
- indexReady: true
44679
- };
44680
- sendWsMessage(socket, e2ee ? e2ee.encryptFields(payload, ["paths"]) : payload);
44681
- })();
44682
- }
44683
- function triggerFileIndexBuild(sessionParentPath = getBridgeRoot()) {
44684
- setImmediate(() => {
44685
- void ensureFileIndexAsync(sessionParentPath).catch((e) => {
44686
- console.error("[file-index] Background build failed:", e);
44687
- });
44688
- });
44689
- }
44690
-
44691
- // src/code-nav/handlers/send-code-nav-response.ts
44692
- var ENCRYPTED_FIELDS = ["definition", "definitions", "references", "symbols", "confidentTarget"];
44693
- function sendCodeNavResponse(socket, e2ee, payload) {
44694
- const fieldsToEncrypt = ENCRYPTED_FIELDS.filter((field) => field in payload && payload[field] !== void 0);
44695
- sendWsMessage(
44696
- socket,
44697
- e2ee && fieldsToEncrypt.length > 0 ? e2ee.encryptFields(payload, [...fieldsToEncrypt]) : payload
44698
- );
44699
- }
44700
-
44701
- // src/code-nav/handlers/handle-definition-op.ts
44702
- async function handleDefinitionOp(ctx) {
44703
- const definition = await queryDefinitionAt(ctx.sessionParentPath, ctx.reqPath, ctx.line, ctx.column);
44704
- sendCodeNavResponse(ctx.socket, ctx.e2ee, {
44705
- type: "code_nav_response",
44706
- id: ctx.msg.id,
44707
- indexReady: true,
44708
- definition
44709
- });
44710
- }
44711
-
44712
- // src/code-nav/handlers/handle-definitions-op.ts
44713
- async function handleDefinitionsOp(ctx) {
44714
- const { definitions, confidentTarget } = await queryDefinitionsNavigation(
44715
- ctx.sessionParentPath,
44716
- ctx.reqPath,
44717
- ctx.line,
44718
- ctx.column
44719
- );
44720
- sendCodeNavResponse(ctx.socket, ctx.e2ee, {
44721
- type: "code_nav_response",
44722
- id: ctx.msg.id,
44723
- indexReady: true,
44724
- definitions,
44725
- confidentTarget
44726
- });
44727
- }
44728
-
44729
- // src/code-nav/handlers/handle-references-op.ts
44730
- async function handleReferencesOp(ctx) {
44731
- const references = await queryReferencesAt(ctx.sessionParentPath, ctx.reqPath, ctx.line, ctx.column);
44732
- sendCodeNavResponse(ctx.socket, ctx.e2ee, {
44733
- type: "code_nav_response",
44734
- id: ctx.msg.id,
44735
- indexReady: true,
44736
- references
44737
- });
44738
- }
44739
-
44740
- // src/code-nav/handlers/handle-symbols-op.ts
44741
- async function handleSymbolsOp(ctx) {
44742
- const symbols = await querySymbolsInFile(ctx.sessionParentPath, ctx.reqPath);
44743
- sendCodeNavResponse(ctx.socket, ctx.e2ee, {
44744
- type: "code_nav_response",
44745
- id: ctx.msg.id,
44746
- indexReady: true,
44747
- symbols
44748
- });
44749
- }
44750
-
44751
- // src/code-nav/handlers/code-nav-op-context.ts
44752
- function normalizeCodeNavOp(op) {
44753
- if (op === "references" || op === "symbols" || op === "definitions") return op;
44754
- return "definition";
44755
- }
44756
-
44757
- // src/code-nav/handlers/resolve-code-nav-parent.ts
44758
- async function resolveCodeNavParentPath(sessionWorktreeManager, sessionId) {
44759
- const parent = sessionWorktreeManager != null ? await resolveFileBrowserSessionParent(sessionWorktreeManager, sessionId) : getBridgeRoot();
44760
- return normalizeResolvedPath(parent);
44761
- }
44762
-
44763
- // src/code-nav/handlers/prepare-code-nav-request.ts
44764
- var CODE_NAV_INDEX_READY_WAIT_MS = 75;
44765
- var CODE_NAV_INDEX_READY_POLL_MS = 15;
44766
- function delay2(ms) {
44767
- return new Promise((resolve35) => setTimeout(resolve35, ms));
44768
- }
44769
- async function waitForSymbolIndexReady(sessionParentPath, reqPath) {
44770
- const deadline = Date.now() + CODE_NAV_INDEX_READY_WAIT_MS;
44771
- do {
44772
- if (await symbolIndexFileIsReadyAsync(sessionParentPath, reqPath)) return true;
44773
- await delay2(CODE_NAV_INDEX_READY_POLL_MS);
44774
- } while (Date.now() < deadline);
44775
- return await symbolIndexFileIsReadyAsync(sessionParentPath, reqPath);
44776
- }
44777
- async function prepareCodeNavRequest(msg, socket, e2ee, sessionWorktreeManager) {
44778
- await yieldToEventLoop();
44779
- const reqPath = msg.path.replace(/^\/+/, "") || "";
44780
- if (!reqPath) {
44781
- sendCodeNavResponse(socket, e2ee, {
44782
- type: "code_nav_response",
44783
- id: msg.id,
44784
- error: "Path required"
44785
- });
44786
- return null;
44787
- }
44788
- const sessionParentPath = await resolveCodeNavParentPath(sessionWorktreeManager, msg.sessionId);
44789
- await registerSymbolIndexParentAsync(sessionParentPath);
44790
- scheduleSymbolIndexFile(sessionParentPath, reqPath);
44791
- const indexReady = await waitForSymbolIndexReady(sessionParentPath, reqPath);
44792
- if (indexReady) {
44793
- const importTargets = await listDirectImportTargetsForFileAsync(sessionParentPath, reqPath);
44794
- scheduleSymbolIndexImportNeighbors(sessionParentPath, importTargets);
44795
- }
44796
- scheduleSymbolIndexWarmup(sessionParentPath);
44797
- await yieldToEventLoop();
44798
- return {
44799
- socket,
44800
- e2ee,
44801
- msg,
44802
- reqPath,
44803
- sessionParentPath,
44804
- line: typeof msg.line === "number" ? msg.line : 1,
44805
- column: typeof msg.column === "number" ? msg.column : 0,
44806
- indexReady
44807
- };
44808
- }
44809
- function sendIndexNotReadyResponse(ctx) {
44810
- sendCodeNavResponse(ctx.socket, ctx.e2ee, {
44811
- type: "code_nav_response",
44812
- id: ctx.msg.id,
44813
- indexReady: false,
44814
- definition: null,
44815
- definitions: [],
44816
- references: [],
44817
- symbols: []
44818
- });
44819
- }
44820
- function preparedOpContext(ctx) {
44821
- return {
44822
- socket: ctx.socket,
44823
- e2ee: ctx.e2ee,
44824
- msg: { ...ctx.msg, op: normalizeCodeNavOp(ctx.msg.op) },
44825
- reqPath: ctx.reqPath,
44826
- sessionParentPath: ctx.sessionParentPath,
44827
- line: ctx.line,
44828
- column: ctx.column
44829
- };
44830
- }
44831
-
44832
- // src/code-nav/handlers/handle-code-nav-request.ts
44833
- function handleCodeNavRequest(msg, socket, e2ee, sessionWorktreeManager) {
44834
- void (async () => {
44835
- const prepared = await prepareCodeNavRequest(msg, socket, e2ee, sessionWorktreeManager);
44836
- if (prepared == null) return;
44837
- if (!prepared.indexReady) {
44838
- sendIndexNotReadyResponse(prepared);
44839
- return;
44840
- }
44841
- const ctx = preparedOpContext(prepared);
44842
- switch (ctx.msg.op) {
44843
- case "symbols":
44844
- await handleSymbolsOp(ctx);
44845
- return;
44846
- case "references":
44847
- await handleReferencesOp(ctx);
44848
- return;
44849
- case "definitions":
44850
- await handleDefinitionsOp(ctx);
44851
- return;
44852
- default:
44853
- await handleDefinitionOp(ctx);
44854
- }
44855
- })();
44856
- }
44857
-
44858
- // src/code-nav/handlers/trigger-symbol-index-build.ts
44859
- function triggerSymbolIndexBuild(parentPath) {
44860
- setImmediate(() => {
44861
- void (async () => {
44862
- const resolved = normalizeResolvedPath(parentPath);
44863
- await registerSymbolIndexParentAsync(resolved);
44864
- scheduleSymbolIndexWarmup(resolved);
44865
- })();
44866
- });
44867
- }
44964
+ // src/files/browser/handle-file-browser-list.ts
44965
+ init_list_dir();
44868
44966
 
44869
44967
  // src/git/tree/resolve-repo-abs-path.ts
44870
- import * as path76 from "node:path";
44968
+ init_cwd();
44969
+ import * as path75 from "node:path";
44871
44970
  function resolveRepoAbsPathFromBridge(repoRelPath, bridgeRoot = getBridgeRoot()) {
44872
- const bridgeResolved = path76.resolve(bridgeRoot);
44971
+ const bridgeResolved = path75.resolve(bridgeRoot);
44873
44972
  const rel = repoRelPath.trim() === "." ? "" : repoRelPath.trim().replace(/\\/g, "/");
44874
- const repoPath = rel === "" ? bridgeResolved : path76.join(bridgeResolved, rel);
44875
- const resolved = path76.resolve(repoPath);
44876
- if (!resolved.startsWith(bridgeResolved + path76.sep) && resolved !== bridgeResolved) {
44973
+ const repoPath = rel === "" ? bridgeResolved : path75.join(bridgeResolved, rel);
44974
+ const resolved = path75.resolve(repoPath);
44975
+ if (!resolved.startsWith(bridgeResolved + path75.sep) && resolved !== bridgeResolved) {
44877
44976
  return null;
44878
44977
  }
44879
44978
  return resolved;
@@ -44891,6 +44990,9 @@ async function resolveBranchCommit(repoAbsPath, branch) {
44891
44990
  }
44892
44991
 
44893
44992
  // src/git/tree/list-git-tree-dir.ts
44993
+ init_yield_to_event_loop();
44994
+ init_types2();
44995
+ init_sort_entries();
44894
44996
  function parseLsTreeLine(line) {
44895
44997
  const tab = line.indexOf(" ");
44896
44998
  if (tab < 0) return null;
@@ -44953,6 +45055,9 @@ async function listGitTreeDirAsync(repoAbsPath, branch, relativePath) {
44953
45055
  }
44954
45056
  }
44955
45057
 
45058
+ // src/git/tree/file/index.ts
45059
+ init_yield_to_event_loop();
45060
+
44956
45061
  // src/files/read-file/types.ts
44957
45062
  var LINE_CHUNK_SIZE = 64 * 1024;
44958
45063
  var READ_RANGE_YIELD_EVERY_BYTES = 256 * 1024;
@@ -44989,6 +45094,7 @@ function guessMimeType(filePath) {
44989
45094
  }
44990
45095
 
44991
45096
  // src/git/tree/file/git-blob-ref.ts
45097
+ init_yield_to_event_loop();
44992
45098
  async function gitBlobRef(repoAbsPath, branch, relativePath) {
44993
45099
  const commit = await resolveBranchCommit(repoAbsPath, branch);
44994
45100
  await yieldToEventLoop();
@@ -45008,6 +45114,7 @@ function isBinaryBuffer(buf) {
45008
45114
  }
45009
45115
 
45010
45116
  // src/git/tree/file/read-git-blob-text-async.ts
45117
+ init_yield_to_event_loop();
45011
45118
  import { StringDecoder } from "node:string_decoder";
45012
45119
  async function countGitBlobLinesAsync(buf) {
45013
45120
  if (buf.length === 0) return 1;
@@ -45256,6 +45363,145 @@ function sendFileBrowserMessage(socket, e2ee, payload) {
45256
45363
  sendWsMessage(socket, e2ee ? e2ee.encryptFields(payload, ["entries", "content", "totalLines", "size", "lineOffset"]) : payload);
45257
45364
  }
45258
45365
 
45366
+ // src/files/read-file/resolve-file-cache-warmup.ts
45367
+ init_yield_to_event_loop();
45368
+ import path77 from "node:path";
45369
+
45370
+ // src/files/read-file/resolve-file-cache.ts
45371
+ import fs49 from "node:fs";
45372
+ import path76 from "node:path";
45373
+ var RESOLVE_CACHE_MAX = 4096;
45374
+ var resolveCache = /* @__PURE__ */ new Map();
45375
+ var warmedDirectories = /* @__PURE__ */ new Set();
45376
+ function resolveCacheKey(sessionParentPath, relativePath) {
45377
+ return `${sessionParentPath}\0${relativePath}`;
45378
+ }
45379
+ function warmedDirectoryKey(sessionParentPath, directoryRelativePath) {
45380
+ const dir = directoryRelativePath.replace(/^\/+/, "") || ".";
45381
+ return `${path76.resolve(sessionParentPath)}\0${dir}`;
45382
+ }
45383
+ function pathStaysUnderParent(filePath, sessionParentPath) {
45384
+ const parent = path76.resolve(sessionParentPath);
45385
+ const resolved = path76.resolve(filePath);
45386
+ return resolved === parent || resolved.startsWith(`${parent}${path76.sep}`);
45387
+ }
45388
+ async function statMatchesCache(entry) {
45389
+ try {
45390
+ const stat2 = await fs49.promises.stat(entry.path);
45391
+ return stat2.isFile() && stat2.mtimeMs === entry.mtimeMs && stat2.size === entry.size;
45392
+ } catch {
45393
+ return false;
45394
+ }
45395
+ }
45396
+ function getResolveCacheEntry(cacheKey) {
45397
+ return resolveCache.get(cacheKey);
45398
+ }
45399
+ function deleteResolveCacheEntry(cacheKey) {
45400
+ resolveCache.delete(cacheKey);
45401
+ }
45402
+ function storeResolveCacheEntry(cacheKey, entry) {
45403
+ if (resolveCache.size >= RESOLVE_CACHE_MAX) resolveCache.clear();
45404
+ resolveCache.set(cacheKey, entry);
45405
+ return entry;
45406
+ }
45407
+ function hasResolveCacheEntry(cacheKey) {
45408
+ return resolveCache.has(cacheKey);
45409
+ }
45410
+ function markDirectoryWarmed(dirKey) {
45411
+ if (warmedDirectories.has(dirKey)) return false;
45412
+ warmedDirectories.add(dirKey);
45413
+ return true;
45414
+ }
45415
+ function unmarkDirectoryWarmed(dirKey) {
45416
+ warmedDirectories.delete(dirKey);
45417
+ }
45418
+
45419
+ // src/files/read-file/resolve-file-path.ts
45420
+ init_ensure_under_cwd();
45421
+ init_cwd();
45422
+ import fs50 from "node:fs";
45423
+ async function resolveFileForReadAsync(relativePath, sessionParentPath = getBridgeRoot()) {
45424
+ const cacheKey = resolveCacheKey(sessionParentPath, relativePath);
45425
+ const cached2 = getResolveCacheEntry(cacheKey);
45426
+ if (cached2 != null && await statMatchesCache(cached2)) {
45427
+ return { path: cached2.path, size: cached2.size };
45428
+ }
45429
+ if (cached2 != null) deleteResolveCacheEntry(cacheKey);
45430
+ const resolved = ensureUnderCwd(relativePath, sessionParentPath);
45431
+ if (!resolved) return { error: "Path is outside working directory" };
45432
+ let real;
45433
+ let size;
45434
+ let mtimeMs;
45435
+ try {
45436
+ const lstat = await fs50.promises.lstat(resolved);
45437
+ if (lstat.isSymbolicLink()) {
45438
+ real = await fs50.promises.realpath(resolved);
45439
+ if (!pathStaysUnderParent(real, sessionParentPath)) {
45440
+ return { error: "Path is outside working directory" };
45441
+ }
45442
+ const stat2 = await fs50.promises.stat(real);
45443
+ if (!stat2.isFile()) return { error: "Not a file" };
45444
+ size = stat2.size;
45445
+ mtimeMs = stat2.mtimeMs;
45446
+ } else if (lstat.isFile()) {
45447
+ real = resolved;
45448
+ size = lstat.size;
45449
+ mtimeMs = lstat.mtimeMs;
45450
+ } else {
45451
+ return { error: "Not a file" };
45452
+ }
45453
+ } catch (err) {
45454
+ return { error: err instanceof Error ? err.message : String(err) };
45455
+ }
45456
+ const entry = storeResolveCacheEntry(cacheKey, { path: real, size, mtimeMs });
45457
+ return { path: entry.path, size: entry.size };
45458
+ }
45459
+ async function resolveFilePathAsync(relativePath, sessionParentPath = getBridgeRoot()) {
45460
+ const result = await resolveFileForReadAsync(relativePath, sessionParentPath);
45461
+ if ("error" in result) return result;
45462
+ return result.path;
45463
+ }
45464
+
45465
+ // src/files/read-file/resolve-file-cache-warmup.ts
45466
+ var WARMED_DIRECTORY_TTL_MS = 6e4;
45467
+ async function warmDirectoryResolveCache(sessionParentPath, directoryRelativePath) {
45468
+ const { listDirAsync: listDirAsync2 } = await Promise.resolve().then(() => (init_list_dir(), list_dir_exports));
45469
+ const result = await listDirAsync2(directoryRelativePath, sessionParentPath);
45470
+ if ("error" in result) return;
45471
+ for (const entry of result.entries) {
45472
+ if (entry.isDir) continue;
45473
+ if (fileBrowserRequestInFlight()) return;
45474
+ const cacheKey = resolveCacheKey(sessionParentPath, entry.path);
45475
+ if (hasResolveCacheEntry(cacheKey)) continue;
45476
+ await resolveFileForReadAsync(entry.path, sessionParentPath).catch(() => void 0);
45477
+ await yieldToEventLoop();
45478
+ }
45479
+ }
45480
+ function scheduleDirectoryResolveCacheWarmup(sessionParentPath, directoryRelativePath) {
45481
+ const parent = path77.resolve(sessionParentPath);
45482
+ const dirKey = warmedDirectoryKey(parent, directoryRelativePath);
45483
+ if (!markDirectoryWarmed(dirKey)) return;
45484
+ setTimeout(() => unmarkDirectoryWarmed(dirKey), WARMED_DIRECTORY_TTL_MS);
45485
+ setImmediate(() => {
45486
+ void warmDirectoryResolveCache(parent, directoryRelativePath.replace(/^\/+/, "") || ".");
45487
+ });
45488
+ }
45489
+ function scheduleResolveCacheWarmupForListedEntries(sessionParentPath, listRelativePath, entries) {
45490
+ scheduleDirectoryResolveCacheWarmup(sessionParentPath, listRelativePath);
45491
+ setImmediate(() => {
45492
+ void (async () => {
45493
+ for (const entry of entries) {
45494
+ if (entry.isDir) continue;
45495
+ if (fileBrowserRequestInFlight()) return;
45496
+ const cacheKey = resolveCacheKey(sessionParentPath, entry.path);
45497
+ if (hasResolveCacheEntry(cacheKey)) continue;
45498
+ await resolveFileForReadAsync(entry.path, sessionParentPath).catch(() => void 0);
45499
+ await yieldToEventLoop();
45500
+ }
45501
+ })();
45502
+ });
45503
+ }
45504
+
45259
45505
  // src/files/browser/handle-file-browser-list.ts
45260
45506
  async function handleFileBrowserList(socket, e2ee, id, reqPath, sessionParentPath, gitScope) {
45261
45507
  const result = gitScope ? await listGitTreeDirAsync(gitScope.repoAbsPath, gitScope.branch, reqPath) : await listDirAsync(reqPath, sessionParentPath);
@@ -45264,38 +45510,138 @@ async function handleFileBrowserList(socket, e2ee, id, reqPath, sessionParentPat
45264
45510
  return;
45265
45511
  }
45266
45512
  sendFileBrowserMessage(socket, e2ee, { type: "file_browser_response", id, entries: result.entries });
45267
- if (!gitScope && (reqPath === "." || reqPath === "")) {
45268
- triggerFileIndexBuild(sessionParentPath);
45269
- if (sessionParentPath) triggerSymbolIndexBuild(sessionParentPath);
45513
+ if (!gitScope && sessionParentPath) {
45514
+ scheduleResolveCacheWarmupForListedEntries(sessionParentPath, reqPath, result.entries);
45270
45515
  }
45271
45516
  }
45272
45517
 
45273
- // src/files/read-file/resolve-file-path.ts
45274
- import fs49 from "node:fs";
45275
- async function resolveFilePathAsync(relativePath, sessionParentPath = getBridgeRoot()) {
45276
- const resolved = ensureUnderCwd(relativePath, sessionParentPath);
45277
- if (!resolved) return { error: "Path is outside working directory" };
45278
- let real;
45279
- try {
45280
- real = await fs49.promises.realpath(resolved);
45281
- } catch {
45282
- real = resolved;
45518
+ // src/files/browser/handle-file-browser-read.ts
45519
+ import path78 from "node:path";
45520
+ init_cwd();
45521
+
45522
+ // src/files/read-file/index.ts
45523
+ init_cwd();
45524
+ init_yield_to_event_loop();
45525
+ import fs54 from "node:fs";
45526
+
45527
+ // src/files/read-file/read-file-range-async.ts
45528
+ init_yield_to_event_loop();
45529
+ import fs51 from "node:fs";
45530
+ import { StringDecoder as StringDecoder2 } from "node:string_decoder";
45531
+
45532
+ // src/files/read-file/read-file-range-line-zero.ts
45533
+ function createLineZeroStreamState(lineOffsetIn) {
45534
+ return {
45535
+ line0Accum: "",
45536
+ skipLine0Chars: typeof lineOffsetIn === "number" ? lineOffsetIn : 0,
45537
+ line0CharsReturned: 0
45538
+ };
45539
+ }
45540
+ function shouldTrackLineZero(startLine, lineOffsetIn) {
45541
+ return startLine === 0 || lineOffsetIn !== void 0;
45542
+ }
45543
+ function stripCarriageReturn(lineContent) {
45544
+ return lineContent.endsWith("\r") ? lineContent.slice(0, -1) : lineContent;
45545
+ }
45546
+ function lineContentBeforeNewline(text, lineStart, newlineIndex) {
45547
+ let lineEnd = newlineIndex;
45548
+ if (lineEnd > lineStart && text[lineEnd - 1] === "\r") lineEnd--;
45549
+ return text.slice(lineStart, lineEnd);
45550
+ }
45551
+ function buildLineZeroChunkResult(resultLines, fileSize, lineOffset, totalLines = 1) {
45552
+ return {
45553
+ content: resultLines.join("\n"),
45554
+ size: fileSize,
45555
+ lineOffset,
45556
+ totalLines
45557
+ };
45558
+ }
45559
+ function tryFinishLineZeroOnCompleteLine(state, lineContent, resultLines, fileSize, lineChunkSize, lineOffsetIn, endLine, currentLine) {
45560
+ state.line0Accum += lineContent;
45561
+ const totalLine0 = state.line0Accum.length;
45562
+ if (state.skipLine0Chars > 0) {
45563
+ if (totalLine0 <= state.skipLine0Chars) {
45564
+ state.skipLine0Chars -= totalLine0;
45565
+ state.line0Accum = "";
45566
+ return currentLine + 1 > endLine ? "done" : "continue";
45567
+ }
45568
+ const from = state.skipLine0Chars;
45569
+ const take = Math.min(lineChunkSize, totalLine0 - from);
45570
+ resultLines.push(state.line0Accum.slice(from, from + take));
45571
+ state.line0CharsReturned += take;
45572
+ if (from + take < totalLine0) {
45573
+ return buildLineZeroChunkResult(
45574
+ resultLines,
45575
+ fileSize,
45576
+ (lineOffsetIn ?? 0) + state.line0CharsReturned
45577
+ );
45578
+ }
45579
+ state.line0Accum = "";
45580
+ state.skipLine0Chars = 0;
45581
+ state.line0CharsReturned = 0;
45582
+ return "continue";
45583
+ }
45584
+ if (totalLine0 > lineChunkSize) {
45585
+ resultLines.push(state.line0Accum.slice(0, lineChunkSize));
45586
+ return buildLineZeroChunkResult(resultLines, fileSize, lineChunkSize);
45587
+ }
45588
+ resultLines.push(state.line0Accum);
45589
+ state.line0Accum = "";
45590
+ return "continue";
45591
+ }
45592
+ function tryFinishLineZeroPartial(state, partialLine, resultLines, fileSize, lineChunkSize, lineOffsetIn) {
45593
+ state.line0Accum += partialLine;
45594
+ const totalLine0 = state.line0Accum.length;
45595
+ if (state.skipLine0Chars > 0) {
45596
+ if (totalLine0 <= state.skipLine0Chars) {
45597
+ state.skipLine0Chars -= totalLine0;
45598
+ state.line0Accum = "";
45599
+ return null;
45600
+ }
45601
+ const from = state.skipLine0Chars;
45602
+ const take = Math.min(lineChunkSize, totalLine0 - from);
45603
+ resultLines.push(state.line0Accum.slice(from, from + take));
45604
+ return buildLineZeroChunkResult(resultLines, fileSize, (lineOffsetIn ?? 0) + take);
45283
45605
  }
45284
- try {
45285
- const stat2 = await fs49.promises.stat(real);
45286
- if (!stat2.isFile()) return { error: "Not a file" };
45287
- return real;
45288
- } catch (err) {
45289
- return { error: err instanceof Error ? err.message : String(err) };
45606
+ if (totalLine0 > lineChunkSize) {
45607
+ resultLines.push(state.line0Accum.slice(0, lineChunkSize));
45608
+ return buildLineZeroChunkResult(resultLines, fileSize, lineChunkSize);
45290
45609
  }
45610
+ return null;
45611
+ }
45612
+ function finishLineZeroTail(state, tail, resultLines, fileSize, lineChunkSize, lineOffsetIn) {
45613
+ if (tail.length === 0) return null;
45614
+ state.line0Accum += stripCarriageReturn(tail);
45615
+ const totalLine0 = state.line0Accum.length;
45616
+ if (state.skipLine0Chars > 0) {
45617
+ if (totalLine0 <= state.skipLine0Chars) {
45618
+ return { content: resultLines.join("\n"), size: fileSize };
45619
+ }
45620
+ const from = state.skipLine0Chars;
45621
+ const take = Math.min(lineChunkSize, totalLine0 - from);
45622
+ resultLines.push(state.line0Accum.slice(from, from + take));
45623
+ state.line0CharsReturned += take;
45624
+ if (from + take < totalLine0) {
45625
+ return buildLineZeroChunkResult(
45626
+ resultLines,
45627
+ fileSize,
45628
+ (lineOffsetIn ?? 0) + state.line0CharsReturned
45629
+ );
45630
+ }
45631
+ return null;
45632
+ }
45633
+ if (totalLine0 > lineChunkSize) {
45634
+ resultLines.push(state.line0Accum.slice(0, lineChunkSize));
45635
+ return buildLineZeroChunkResult(resultLines, fileSize, lineChunkSize);
45636
+ }
45637
+ resultLines.push(state.line0Accum);
45638
+ return null;
45291
45639
  }
45292
45640
 
45293
45641
  // src/files/read-file/read-file-range-async.ts
45294
- import fs50 from "node:fs";
45295
- import { StringDecoder as StringDecoder2 } from "node:string_decoder";
45296
- async function readFileRangeAsync(filePath, startLine, endLine, lineOffsetIn, lineChunkSize = LINE_CHUNK_SIZE) {
45297
- const fileSize = (await fs50.promises.stat(filePath)).size;
45298
- const fd = await fs50.promises.open(filePath, "r");
45642
+ async function readFileRangeAsync(filePath, startLine, endLine, lineOffsetIn, lineChunkSize = LINE_CHUNK_SIZE, fileSizeIn) {
45643
+ const fileSize = fileSizeIn ?? (await fs51.promises.stat(filePath)).size;
45644
+ const fd = await fs51.promises.open(filePath, "r");
45299
45645
  const bufSize = 64 * 1024;
45300
45646
  const buf = Buffer.alloc(bufSize);
45301
45647
  const decoder = new StringDecoder2("utf8");
@@ -45303,9 +45649,8 @@ async function readFileRangeAsync(filePath, startLine, endLine, lineOffsetIn, li
45303
45649
  const resultLines = [];
45304
45650
  let partial2 = "";
45305
45651
  let done = false;
45306
- let skipLine0Chars = typeof lineOffsetIn === "number" ? lineOffsetIn : 0;
45307
- let line0CharsReturned = 0;
45308
- let line0Accum = "";
45652
+ const trackLineZero = shouldTrackLineZero(startLine, lineOffsetIn);
45653
+ const lineZeroState = createLineZeroStreamState(lineOffsetIn);
45309
45654
  let bytesSinceYield = 0;
45310
45655
  try {
45311
45656
  let position = 0;
@@ -45322,130 +45667,70 @@ async function readFileRangeAsync(filePath, startLine, endLine, lineOffsetIn, li
45322
45667
  partial2 = "";
45323
45668
  let lineStart = 0;
45324
45669
  for (let i = 0; i < text.length; i++) {
45325
- if (text[i] === "\n") {
45326
- const lineContent = (() => {
45327
- let lineEnd = i;
45328
- if (lineEnd > lineStart && text[lineEnd - 1] === "\r") lineEnd--;
45329
- return text.slice(lineStart, lineEnd);
45330
- })();
45331
- if (currentLine === 0 && (startLine === 0 || lineOffsetIn !== void 0)) {
45332
- line0Accum += lineContent;
45333
- const totalLine0 = line0Accum.length;
45334
- if (skipLine0Chars > 0) {
45335
- if (totalLine0 <= skipLine0Chars) {
45336
- skipLine0Chars -= totalLine0;
45337
- line0Accum = "";
45338
- currentLine++;
45339
- lineStart = i + 1;
45340
- if (currentLine > endLine) {
45341
- done = true;
45342
- break;
45343
- }
45344
- continue;
45345
- }
45346
- const from = skipLine0Chars;
45347
- const take = Math.min(lineChunkSize, totalLine0 - from);
45348
- resultLines.push(line0Accum.slice(from, from + take));
45349
- line0CharsReturned += take;
45350
- if (from + take < totalLine0) {
45351
- return {
45352
- content: resultLines.join("\n"),
45353
- size: fileSize,
45354
- lineOffset: lineOffsetIn + line0CharsReturned,
45355
- totalLines: 1
45356
- };
45357
- }
45358
- line0Accum = "";
45359
- skipLine0Chars = 0;
45360
- line0CharsReturned = 0;
45361
- } else if (totalLine0 > lineChunkSize) {
45362
- resultLines.push(line0Accum.slice(0, lineChunkSize));
45363
- return {
45364
- content: resultLines.join("\n"),
45365
- size: fileSize,
45366
- lineOffset: lineChunkSize,
45367
- totalLines: 1
45368
- };
45369
- } else {
45370
- resultLines.push(line0Accum);
45371
- line0Accum = "";
45372
- }
45373
- } else if (currentLine >= startLine && currentLine <= endLine) {
45374
- resultLines.push(lineContent);
45670
+ if (text[i] !== "\n") continue;
45671
+ const lineContent2 = lineContentBeforeNewline(text, lineStart, i);
45672
+ if (currentLine === 0 && trackLineZero) {
45673
+ const lineZeroResult = tryFinishLineZeroOnCompleteLine(
45674
+ lineZeroState,
45675
+ lineContent2,
45676
+ resultLines,
45677
+ fileSize,
45678
+ lineChunkSize,
45679
+ lineOffsetIn,
45680
+ endLine,
45681
+ currentLine
45682
+ );
45683
+ if (lineZeroResult === "done") {
45684
+ done = true;
45685
+ break;
45375
45686
  }
45687
+ if (lineZeroResult !== "continue") return lineZeroResult;
45376
45688
  currentLine++;
45377
45689
  lineStart = i + 1;
45378
45690
  if (currentLine > endLine) {
45379
45691
  done = true;
45380
45692
  break;
45381
45693
  }
45694
+ continue;
45382
45695
  }
45383
- }
45384
- if (!done) {
45385
- const lineContent = text.slice(lineStart);
45386
- if (currentLine === 0 && (startLine === 0 || lineOffsetIn !== void 0)) {
45387
- line0Accum += lineContent;
45388
- const totalLine0 = line0Accum.length;
45389
- if (skipLine0Chars > 0) {
45390
- if (totalLine0 <= skipLine0Chars) {
45391
- skipLine0Chars -= totalLine0;
45392
- line0Accum = "";
45393
- } else {
45394
- const from = skipLine0Chars;
45395
- const take = Math.min(lineChunkSize, totalLine0 - from);
45396
- resultLines.push(line0Accum.slice(from, from + take));
45397
- return {
45398
- content: resultLines.join("\n"),
45399
- size: fileSize,
45400
- lineOffset: (lineOffsetIn ?? 0) + take,
45401
- totalLines: 1
45402
- };
45403
- }
45404
- } else if (totalLine0 > lineChunkSize) {
45405
- resultLines.push(line0Accum.slice(0, lineChunkSize));
45406
- return {
45407
- content: resultLines.join("\n"),
45408
- size: fileSize,
45409
- lineOffset: lineChunkSize,
45410
- totalLines: 1
45411
- };
45412
- }
45696
+ if (currentLine >= startLine && currentLine <= endLine) {
45697
+ resultLines.push(lineContent2);
45698
+ }
45699
+ currentLine++;
45700
+ lineStart = i + 1;
45701
+ if (currentLine > endLine) {
45702
+ done = true;
45703
+ break;
45413
45704
  }
45414
- partial2 = text.slice(lineStart);
45705
+ }
45706
+ if (done) continue;
45707
+ const lineContent = text.slice(lineStart);
45708
+ if (currentLine === 0 && trackLineZero) {
45709
+ const partialResult = tryFinishLineZeroPartial(
45710
+ lineZeroState,
45711
+ lineContent,
45712
+ resultLines,
45713
+ fileSize,
45714
+ lineChunkSize,
45715
+ lineOffsetIn
45716
+ );
45717
+ if (partialResult != null) return partialResult;
45718
+ } else {
45719
+ partial2 = lineContent;
45415
45720
  }
45416
45721
  }
45417
45722
  if (!done) {
45418
45723
  const tail = partial2 + decoder.end();
45419
- if (currentLine === 0 && (startLine === 0 || lineOffsetIn !== void 0) && tail.length > 0) {
45420
- line0Accum += tail.endsWith("\r") ? tail.slice(0, -1) : tail;
45421
- const totalLine0 = line0Accum.length;
45422
- if (skipLine0Chars > 0) {
45423
- if (totalLine0 <= skipLine0Chars) {
45424
- return { content: resultLines.join("\n"), size: fileSize };
45425
- }
45426
- const from = skipLine0Chars;
45427
- const take = Math.min(lineChunkSize, totalLine0 - from);
45428
- resultLines.push(line0Accum.slice(from, from + take));
45429
- line0CharsReturned += take;
45430
- if (from + take < totalLine0) {
45431
- return {
45432
- content: resultLines.join("\n"),
45433
- size: fileSize,
45434
- lineOffset: (lineOffsetIn ?? 0) + line0CharsReturned,
45435
- totalLines: 1
45436
- };
45437
- }
45438
- } else if (totalLine0 > lineChunkSize) {
45439
- resultLines.push(line0Accum.slice(0, lineChunkSize));
45440
- return {
45441
- content: resultLines.join("\n"),
45442
- size: fileSize,
45443
- lineOffset: lineChunkSize,
45444
- totalLines: 1
45445
- };
45446
- } else {
45447
- resultLines.push(line0Accum);
45448
- }
45724
+ if (currentLine === 0 && trackLineZero) {
45725
+ const tailResult = finishLineZeroTail(
45726
+ lineZeroState,
45727
+ tail,
45728
+ resultLines,
45729
+ fileSize,
45730
+ lineChunkSize,
45731
+ lineOffsetIn
45732
+ );
45733
+ if (tailResult != null) return tailResult;
45449
45734
  } else if (tail.length > 0 && currentLine >= startLine && currentLine <= endLine) {
45450
45735
  resultLines.push(tail.endsWith("\r") ? tail.slice(0, -1) : tail);
45451
45736
  }
@@ -45456,12 +45741,48 @@ async function readFileRangeAsync(filePath, startLine, endLine, lineOffsetIn, li
45456
45741
  }
45457
45742
  }
45458
45743
 
45744
+ // src/files/read-file/read-small-file-range-async.ts
45745
+ import fs52 from "node:fs";
45746
+ var SMALL_FILE_RANGE_MAX_BYTES = 512 * 1024;
45747
+ function sliceLineRange(lines, startLine, endLine, lineOffsetIn, lineChunkSize, fileSize) {
45748
+ if (startLine === 0 && lineOffsetIn == null && lines[0] != null && lines[0].length > lineChunkSize) {
45749
+ return {
45750
+ content: lines[0].slice(0, lineChunkSize),
45751
+ size: fileSize,
45752
+ lineOffset: lineChunkSize,
45753
+ totalLines: lines.length
45754
+ };
45755
+ }
45756
+ if (startLine === 0 && typeof lineOffsetIn === "number") {
45757
+ const line0 = lines[0] ?? "";
45758
+ const from = lineOffsetIn;
45759
+ const take = Math.min(lineChunkSize, Math.max(0, line0.length - from));
45760
+ return {
45761
+ content: line0.slice(from, from + take),
45762
+ size: fileSize,
45763
+ ...from + take < line0.length ? { lineOffset: from + take, totalLines: lines.length } : { totalLines: lines.length }
45764
+ };
45765
+ }
45766
+ const slice = lines.slice(startLine, endLine + 1);
45767
+ return {
45768
+ content: slice.join("\n"),
45769
+ size: fileSize,
45770
+ totalLines: lines.length
45771
+ };
45772
+ }
45773
+ async function readSmallFileRangeAsync(filePath, fileSize, startLine, endLine, lineOffsetIn, lineChunkSize = LINE_CHUNK_SIZE) {
45774
+ const raw = await fs52.promises.readFile(filePath, "utf8");
45775
+ const lines = raw.split(/\r?\n/);
45776
+ return sliceLineRange(lines, startLine, endLine, lineOffsetIn, lineChunkSize, fileSize);
45777
+ }
45778
+
45459
45779
  // src/files/read-file/read-file-buffer-full-async.ts
45460
- import fs51 from "node:fs";
45780
+ init_yield_to_event_loop();
45781
+ import fs53 from "node:fs";
45461
45782
  var READ_CHUNK_BYTES = 256 * 1024;
45462
45783
  async function readFileBufferFullAsync(filePath) {
45463
- const stat2 = await fs51.promises.stat(filePath);
45464
- const fd = await fs51.promises.open(filePath, "r");
45784
+ const stat2 = await fs53.promises.stat(filePath);
45785
+ const fd = await fs53.promises.open(filePath, "r");
45465
45786
  const chunks = [];
45466
45787
  let position = 0;
45467
45788
  let bytesSinceYield = 0;
@@ -45503,12 +45824,23 @@ async function readFileBinaryFullAsync(filePath) {
45503
45824
  }
45504
45825
 
45505
45826
  // src/files/read-file/index.ts
45506
- async function readFileAsync(relativePath, startLine, endLine, lineOffset, lineChunkSize = LINE_CHUNK_SIZE, sessionParentPath = getBridgeRoot(), encoding = "utf8") {
45507
- await yieldToEventLoop();
45827
+ async function readFileAsync(relativePath, startLine, endLine, lineOffset, lineChunkSize = LINE_CHUNK_SIZE, sessionParentPath = getBridgeRoot(), encoding = "utf8", options) {
45828
+ if (!options?.skipInitialYield) {
45829
+ await yieldToEventLoop();
45830
+ }
45508
45831
  try {
45509
- const result = await resolveFilePathAsync(relativePath, sessionParentPath);
45510
- if (typeof result === "object") return result;
45511
- const resolvedPath = result;
45832
+ let resolvedPath;
45833
+ let fileSize;
45834
+ if (options?.useResolvedSize) {
45835
+ const resolved = await resolveFileForReadAsync(relativePath, sessionParentPath);
45836
+ if ("error" in resolved) return resolved;
45837
+ resolvedPath = resolved.path;
45838
+ fileSize = resolved.size;
45839
+ } else {
45840
+ const result = await resolveFilePathAsync(relativePath, sessionParentPath);
45841
+ if (typeof result === "object") return result;
45842
+ resolvedPath = result;
45843
+ }
45512
45844
  const hasRange = typeof startLine === "number" && typeof endLine === "number";
45513
45845
  if (encoding === "base64") {
45514
45846
  if (hasRange) return { error: "base64 encoding requires a full file read (no line range)" };
@@ -45516,7 +45848,26 @@ async function readFileAsync(relativePath, startLine, endLine, lineOffset, lineC
45516
45848
  return { ...read2, resolvedPath };
45517
45849
  }
45518
45850
  if (hasRange) {
45519
- return readFileRangeAsync(resolvedPath, startLine, endLine, lineOffset, lineChunkSize);
45851
+ if (fileSize == null) {
45852
+ const stat2 = await fs54.promises.stat(resolvedPath);
45853
+ fileSize = stat2.size;
45854
+ }
45855
+ const read2 = fileSize <= SMALL_FILE_RANGE_MAX_BYTES ? await readSmallFileRangeAsync(
45856
+ resolvedPath,
45857
+ fileSize,
45858
+ startLine,
45859
+ endLine,
45860
+ lineOffset,
45861
+ lineChunkSize
45862
+ ) : await readFileRangeAsync(
45863
+ resolvedPath,
45864
+ startLine,
45865
+ endLine,
45866
+ lineOffset,
45867
+ lineChunkSize,
45868
+ fileSize
45869
+ );
45870
+ return read2;
45520
45871
  }
45521
45872
  const read = await readFileFullAsync(resolvedPath);
45522
45873
  return { ...read, resolvedPath };
@@ -45525,6 +45876,17 @@ async function readFileAsync(relativePath, startLine, endLine, lineOffset, lineC
45525
45876
  }
45526
45877
  }
45527
45878
 
45879
+ // src/files/browser/file-browser-read-queue.ts
45880
+ var readChain = Promise.resolve();
45881
+ function withFileBrowserReadQueue(fn) {
45882
+ const next = readChain.then(() => fn());
45883
+ readChain = next.then(
45884
+ () => void 0,
45885
+ () => void 0
45886
+ );
45887
+ return next;
45888
+ }
45889
+
45528
45890
  // src/files/browser/handle-file-browser-read.ts
45529
45891
  async function handleFileBrowserRead(socket, e2ee, msg, reqPath, sessionParentPath, gitScope) {
45530
45892
  const startLine = typeof msg.startLine === "number" ? msg.startLine : void 0;
@@ -45541,14 +45903,17 @@ async function handleFileBrowserRead(socket, e2ee, msg, reqPath, sessionParentPa
45541
45903
  lineOffset,
45542
45904
  lineChunkSize,
45543
45905
  encoding
45544
- ) : await readFileAsync(
45545
- reqPath,
45546
- startLine,
45547
- endLine,
45548
- lineOffset,
45549
- lineChunkSize,
45550
- sessionParentPath,
45551
- encoding
45906
+ ) : await withFileBrowserReadQueue(
45907
+ () => readFileAsync(
45908
+ reqPath,
45909
+ startLine,
45910
+ endLine,
45911
+ lineOffset,
45912
+ lineChunkSize,
45913
+ sessionParentPath,
45914
+ encoding,
45915
+ { skipInitialYield: true, useResolvedSize: true }
45916
+ )
45552
45917
  );
45553
45918
  if ("error" in result) {
45554
45919
  sendWsMessage(socket, { type: "file_browser_response", id: msg.id, error: result.error });
@@ -45565,6 +45930,10 @@ async function handleFileBrowserRead(socket, e2ee, msg, reqPath, sessionParentPa
45565
45930
  if (result.mimeType != null) payload.mimeType = result.mimeType;
45566
45931
  if (result.resolvedPath != null) payload.resolvedPath = result.resolvedPath;
45567
45932
  sendFileBrowserMessage(socket, e2ee, payload);
45933
+ if (!gitScope) {
45934
+ const parentDir = path78.dirname(reqPath.replace(/^\/+/, "") || ".");
45935
+ scheduleDirectoryResolveCacheWarmup(sessionParentPath ?? getBridgeRoot(), parentDir === "" ? "." : parentDir);
45936
+ }
45568
45937
  }
45569
45938
 
45570
45939
  // src/files/browser/resolve-git-branch-scope.ts
@@ -45578,22 +45947,67 @@ function resolveGitBranchScope(msg) {
45578
45947
 
45579
45948
  // src/files/browser/index.ts
45580
45949
  function handleFileBrowserRequest(msg, socket, e2ee, sessionWorktreeManager) {
45950
+ beginFileBrowserRequest();
45581
45951
  void (async () => {
45582
- const reqPath = msg.path.replace(/^\/+/, "") || ".";
45583
- const op = msg.op === "read" ? "read" : "list";
45584
- const sessionParentPath = sessionWorktreeManager != null ? await resolveFileBrowserSessionParent(sessionWorktreeManager, msg.sessionId) : void 0;
45585
- const gitScope = resolveGitBranchScope(msg);
45586
- if (msg.source === "git_branch" && typeof msg.repoRelPath === "string" && typeof msg.branch === "string" && msg.branch.trim().length > 0 && !gitScope) {
45587
- sendWsMessage(socket, { type: "file_browser_response", id: msg.id, error: "Invalid repository path" });
45588
- return;
45952
+ try {
45953
+ const reqPath = msg.path.replace(/^\/+/, "") || ".";
45954
+ const sessionParentPath = sessionWorktreeManager != null ? await resolveFileBrowserSessionParent(sessionWorktreeManager, msg.sessionId) : void 0;
45955
+ const gitScope = resolveGitBranchScope(msg);
45956
+ if (msg.source === "git_branch" && typeof msg.repoRelPath === "string" && typeof msg.branch === "string" && msg.branch.trim().length > 0 && !gitScope) {
45957
+ sendWsMessage(socket, { type: "file_browser_response", id: msg.id, error: "Invalid repository path" });
45958
+ return;
45959
+ }
45960
+ if (msg.op === "read") {
45961
+ await handleFileBrowserRead(socket, e2ee, msg, reqPath, sessionParentPath, gitScope);
45962
+ } else {
45963
+ await handleFileBrowserList(socket, e2ee, msg.id, reqPath, sessionParentPath, gitScope);
45964
+ }
45965
+ } finally {
45966
+ endFileBrowserRequest();
45589
45967
  }
45590
- if (op === "list") {
45591
- await handleFileBrowserList(socket, e2ee, msg.id, reqPath, sessionParentPath, gitScope);
45592
- } else {
45593
- await handleFileBrowserRead(socket, e2ee, msg, reqPath, sessionParentPath, gitScope);
45968
+ })();
45969
+ }
45970
+
45971
+ // src/files/handle-file-browser-search.ts
45972
+ init_cwd();
45973
+ init_yield_to_event_loop();
45974
+ import path79 from "node:path";
45975
+ var SEARCH_LIMIT = 100;
45976
+ function handleFileBrowserSearch(msg, socket, e2ee, sessionWorktreeManager) {
45977
+ void (async () => {
45978
+ await yieldToEventLoop();
45979
+ const q = typeof msg.q === "string" ? msg.q : "";
45980
+ const sessionParentPath = path79.resolve(
45981
+ sessionWorktreeManager != null ? await resolveFileBrowserSessionParent(sessionWorktreeManager, msg.sessionId) : getBridgeRoot()
45982
+ );
45983
+ if (!await bridgeFileIndexIsPopulated(sessionParentPath)) {
45984
+ triggerFileIndexBuild(sessionParentPath);
45985
+ const payload2 = {
45986
+ type: "file_browser_search_response",
45987
+ id: msg.id,
45988
+ paths: [],
45989
+ indexReady: false
45990
+ };
45991
+ sendWsMessage(socket, e2ee ? e2ee.encryptFields(payload2, ["paths"]) : payload2);
45992
+ return;
45594
45993
  }
45994
+ const results = await searchBridgeFilePathsAsync(sessionParentPath, q, SEARCH_LIMIT);
45995
+ const payload = {
45996
+ type: "file_browser_search_response",
45997
+ id: msg.id,
45998
+ paths: results,
45999
+ indexReady: true
46000
+ };
46001
+ sendWsMessage(socket, e2ee ? e2ee.encryptFields(payload, ["paths"]) : payload);
45595
46002
  })();
45596
46003
  }
46004
+ function triggerFileIndexBuild(sessionParentPath = getBridgeRoot()) {
46005
+ setImmediate(() => {
46006
+ void ensureFileIndexAsync(sessionParentPath).catch((e) => {
46007
+ console.error("[file-index] Background build failed:", e);
46008
+ });
46009
+ });
46010
+ }
45597
46011
 
45598
46012
  // src/routing/handlers/file-browser-messages.ts
45599
46013
  function handleFileBrowserRequestMessage(msg, { getWs, e2ee, sessionWorktreeManager }) {
@@ -45614,6 +46028,235 @@ function handleFileBrowserSearchMessage(msg, { getWs, e2ee, sessionWorktreeManag
45614
46028
  );
45615
46029
  }
45616
46030
 
46031
+ // src/code-nav/handlers/send-code-nav-response.ts
46032
+ var ENCRYPTED_FIELDS = ["definition", "definitions", "references", "symbols", "confidentTarget"];
46033
+ function sendCodeNavResponse(socket, e2ee, payload) {
46034
+ const fieldsToEncrypt = ENCRYPTED_FIELDS.filter((field) => field in payload && payload[field] !== void 0);
46035
+ sendWsMessage(
46036
+ socket,
46037
+ e2ee && fieldsToEncrypt.length > 0 ? e2ee.encryptFields(payload, [...fieldsToEncrypt]) : payload
46038
+ );
46039
+ }
46040
+
46041
+ // src/code-nav/handlers/handle-definition-op.ts
46042
+ async function handleDefinitionOp(ctx) {
46043
+ const definition = await queryDefinitionAt(ctx.sessionParentPath, ctx.reqPath, ctx.line, ctx.column);
46044
+ sendCodeNavResponse(ctx.socket, ctx.e2ee, {
46045
+ type: "code_nav_response",
46046
+ id: ctx.msg.id,
46047
+ indexReady: true,
46048
+ definition
46049
+ });
46050
+ }
46051
+
46052
+ // src/code-nav/handlers/handle-definitions-op.ts
46053
+ async function handleDefinitionsOp(ctx) {
46054
+ const { definitions, confidentTarget } = await queryDefinitionsNavigation(
46055
+ ctx.sessionParentPath,
46056
+ ctx.reqPath,
46057
+ ctx.line,
46058
+ ctx.column
46059
+ );
46060
+ sendCodeNavResponse(ctx.socket, ctx.e2ee, {
46061
+ type: "code_nav_response",
46062
+ id: ctx.msg.id,
46063
+ indexReady: true,
46064
+ definitions,
46065
+ confidentTarget
46066
+ });
46067
+ }
46068
+
46069
+ // src/code-nav/handlers/handle-references-op.ts
46070
+ async function handleReferencesOp(ctx) {
46071
+ const references = await queryReferencesAt(ctx.sessionParentPath, ctx.reqPath, ctx.line, ctx.column);
46072
+ sendCodeNavResponse(ctx.socket, ctx.e2ee, {
46073
+ type: "code_nav_response",
46074
+ id: ctx.msg.id,
46075
+ indexReady: true,
46076
+ references
46077
+ });
46078
+ }
46079
+
46080
+ // src/code-nav/handlers/handle-symbols-op.ts
46081
+ async function handleSymbolsOp(ctx) {
46082
+ const symbols = await querySymbolsInFile(ctx.sessionParentPath, ctx.reqPath);
46083
+ sendCodeNavResponse(ctx.socket, ctx.e2ee, {
46084
+ type: "code_nav_response",
46085
+ id: ctx.msg.id,
46086
+ indexReady: true,
46087
+ symbols
46088
+ });
46089
+ }
46090
+
46091
+ // src/code-nav/handlers/prepare-code-nav-request.ts
46092
+ init_yield_to_event_loop();
46093
+
46094
+ // src/code-nav/handlers/deferred-code-nav-index.ts
46095
+ var latestSeqBySession = /* @__PURE__ */ new Map();
46096
+ var pendingBySession = /* @__PURE__ */ new Map();
46097
+ var flushPromise = null;
46098
+ function scheduleDeferredCodeNavIndex(sessionKey, sessionParentPath, reqPath) {
46099
+ const seq = (latestSeqBySession.get(sessionKey) ?? 0) + 1;
46100
+ latestSeqBySession.set(sessionKey, seq);
46101
+ pendingBySession.set(sessionKey, { sessionParentPath, reqPath, seq });
46102
+ scheduleFlushWhenIdle();
46103
+ }
46104
+ function scheduleFlushWhenIdle() {
46105
+ if (flushPromise != null) return;
46106
+ flushPromise = runFlushWhenIdle().finally(() => {
46107
+ flushPromise = null;
46108
+ if (pendingBySession.size > 0) scheduleFlushWhenIdle();
46109
+ });
46110
+ }
46111
+ async function runFlushWhenIdle() {
46112
+ await yieldUntilFileBrowserIdle();
46113
+ const entries = [];
46114
+ for (const [sessionKey, entry] of pendingBySession) {
46115
+ pendingBySession.delete(sessionKey);
46116
+ if (entry.seq === latestSeqBySession.get(sessionKey)) entries.push(entry);
46117
+ }
46118
+ for (const entry of entries) {
46119
+ scheduleSymbolIndexFile(entry.sessionParentPath, entry.reqPath);
46120
+ }
46121
+ }
46122
+ registerFileBrowserActivityListener(() => {
46123
+ if (pendingBySession.size > 0 && !isBridgeBrowseInteractiveActive()) {
46124
+ scheduleFlushWhenIdle();
46125
+ }
46126
+ });
46127
+
46128
+ // src/code-nav/handlers/code-nav-session-key.ts
46129
+ function codeNavSessionKey(sessionId, sessionParentPath) {
46130
+ const trimmed2 = sessionId?.trim();
46131
+ return trimmed2 ? trimmed2 : sessionParentPath;
46132
+ }
46133
+
46134
+ // src/code-nav/handlers/wait-for-symbol-index-ready.ts
46135
+ var CODE_NAV_INDEX_READY_WAIT_MS = 75;
46136
+ var CODE_NAV_INDEX_READY_POLL_MS = 15;
46137
+ function delay2(ms) {
46138
+ return new Promise((resolve35) => setTimeout(resolve35, ms));
46139
+ }
46140
+ async function waitForSymbolIndexReady(sessionParentPath, reqPath, maxWaitMs = CODE_NAV_INDEX_READY_WAIT_MS) {
46141
+ const deadline = Date.now() + maxWaitMs;
46142
+ do {
46143
+ if (await symbolIndexFileIsReadyAsync(sessionParentPath, reqPath)) return true;
46144
+ await delay2(CODE_NAV_INDEX_READY_POLL_MS);
46145
+ } while (Date.now() < deadline);
46146
+ return await symbolIndexFileIsReadyAsync(sessionParentPath, reqPath);
46147
+ }
46148
+
46149
+ // src/code-nav/handlers/prepare-code-nav-base-context.ts
46150
+ function buildPreparedCodeNavBaseContext(msg, socket, e2ee, reqPath, sessionParentPath) {
46151
+ return {
46152
+ socket,
46153
+ e2ee,
46154
+ msg,
46155
+ reqPath,
46156
+ sessionParentPath,
46157
+ line: typeof msg.line === "number" ? msg.line : 1,
46158
+ column: typeof msg.column === "number" ? msg.column : 0
46159
+ };
46160
+ }
46161
+
46162
+ // src/code-nav/handlers/code-nav-op-context.ts
46163
+ function normalizeCodeNavOp(op) {
46164
+ if (op === "references" || op === "symbols" || op === "definitions") return op;
46165
+ return "definition";
46166
+ }
46167
+
46168
+ // src/code-nav/handlers/resolve-code-nav-parent.ts
46169
+ init_cwd();
46170
+ init_normalize_resolved_path();
46171
+ async function resolveCodeNavParentPath(sessionWorktreeManager, sessionId) {
46172
+ const parent = sessionWorktreeManager != null ? await resolveFileBrowserSessionParent(sessionWorktreeManager, sessionId) : getBridgeRoot();
46173
+ return normalizeResolvedPath(parent);
46174
+ }
46175
+
46176
+ // src/code-nav/handlers/prepare-code-nav-request.ts
46177
+ async function prepareCodeNavRequest(msg, socket, e2ee, sessionWorktreeManager) {
46178
+ await yieldToEventLoop();
46179
+ const reqPath = msg.path.replace(/^\/+/, "") || "";
46180
+ if (!reqPath) {
46181
+ sendCodeNavResponse(socket, e2ee, {
46182
+ type: "code_nav_response",
46183
+ id: msg.id,
46184
+ error: "Path required"
46185
+ });
46186
+ return null;
46187
+ }
46188
+ const sessionParentPath = await resolveCodeNavParentPath(sessionWorktreeManager, msg.sessionId);
46189
+ await registerSymbolIndexParentAsync(sessionParentPath);
46190
+ const sessionKey = codeNavSessionKey(msg.sessionId, sessionParentPath);
46191
+ const baseContext = buildPreparedCodeNavBaseContext(msg, socket, e2ee, reqPath, sessionParentPath);
46192
+ if (isBridgeBrowseInteractiveActive()) {
46193
+ scheduleDeferredCodeNavIndex(sessionKey, sessionParentPath, reqPath);
46194
+ return { ...baseContext, indexReady: false };
46195
+ }
46196
+ scheduleSymbolIndexFile(sessionParentPath, reqPath);
46197
+ const indexReady = await waitForSymbolIndexReady(sessionParentPath, reqPath);
46198
+ if (indexReady) {
46199
+ const importTargets = await listDirectImportTargetsForFileAsync(sessionParentPath, reqPath);
46200
+ scheduleSymbolIndexImportNeighbors(sessionParentPath, importTargets);
46201
+ }
46202
+ await yieldToEventLoop();
46203
+ return {
46204
+ ...baseContext,
46205
+ indexReady
46206
+ };
46207
+ }
46208
+ function sendIndexNotReadyResponse(ctx) {
46209
+ sendCodeNavResponse(ctx.socket, ctx.e2ee, {
46210
+ type: "code_nav_response",
46211
+ id: ctx.msg.id,
46212
+ indexReady: false,
46213
+ definition: null,
46214
+ definitions: [],
46215
+ references: [],
46216
+ symbols: []
46217
+ });
46218
+ }
46219
+ function preparedOpContext(ctx) {
46220
+ return {
46221
+ socket: ctx.socket,
46222
+ e2ee: ctx.e2ee,
46223
+ msg: { ...ctx.msg, op: normalizeCodeNavOp(ctx.msg.op) },
46224
+ reqPath: ctx.reqPath,
46225
+ sessionParentPath: ctx.sessionParentPath,
46226
+ line: ctx.line,
46227
+ column: ctx.column
46228
+ };
46229
+ }
46230
+
46231
+ // src/code-nav/handlers/handle-code-nav-request.ts
46232
+ function handleCodeNavRequest(msg, socket, e2ee, sessionWorktreeManager) {
46233
+ void (async () => {
46234
+ const prepared = await prepareCodeNavRequest(msg, socket, e2ee, sessionWorktreeManager);
46235
+ if (prepared == null) return;
46236
+ if (!prepared.indexReady) {
46237
+ sendIndexNotReadyResponse(prepared);
46238
+ return;
46239
+ }
46240
+ const ctx = preparedOpContext(prepared);
46241
+ switch (ctx.msg.op) {
46242
+ case "symbols":
46243
+ await handleSymbolsOp(ctx);
46244
+ return;
46245
+ case "references":
46246
+ await handleReferencesOp(ctx);
46247
+ return;
46248
+ case "definitions":
46249
+ await handleDefinitionsOp(ctx);
46250
+ return;
46251
+ default:
46252
+ await handleDefinitionOp(ctx);
46253
+ }
46254
+ })();
46255
+ }
46256
+
46257
+ // src/code-nav/handlers/trigger-symbol-index-build.ts
46258
+ init_normalize_resolved_path();
46259
+
45617
46260
  // src/routing/handlers/code-nav-messages.ts
45618
46261
  function handleFileBrowserCodeNavMessage(msg, { getWs, e2ee, sessionWorktreeManager }) {
45619
46262
  if (typeof msg.id !== "string" || typeof msg.path !== "string") return;
@@ -45636,6 +46279,7 @@ function handleFileBrowserCodeNavMessage(msg, { getWs, e2ee, sessionWorktreeMana
45636
46279
  }
45637
46280
 
45638
46281
  // src/routing/handlers/skill-layout-request.ts
46282
+ init_cwd();
45639
46283
  function handleSkillLayoutRequest(msg, deps) {
45640
46284
  const id = typeof msg.id === "string" ? msg.id : "";
45641
46285
  void (async () => {
@@ -45647,6 +46291,9 @@ function handleSkillLayoutRequest(msg, deps) {
45647
46291
  })();
45648
46292
  }
45649
46293
 
46294
+ // src/routing/handlers/install-skills.ts
46295
+ init_cwd();
46296
+
45650
46297
  // src/skills/install/is-valid-install-item.ts
45651
46298
  function isValidRemoteSkillInstallItem(item) {
45652
46299
  if (item === null || typeof item !== "object") return false;
@@ -45655,8 +46302,9 @@ function isValidRemoteSkillInstallItem(item) {
45655
46302
  }
45656
46303
 
45657
46304
  // src/skills/install/install-remote-skills-async.ts
45658
- import fs52 from "node:fs";
45659
- import path77 from "node:path";
46305
+ init_yield_to_event_loop();
46306
+ import fs55 from "node:fs";
46307
+ import path80 from "node:path";
45660
46308
 
45661
46309
  // src/skills/install/constants.ts
45662
46310
  var INSTALL_SKILLS_YIELD_EVERY = 16;
@@ -45667,12 +46315,12 @@ async function writeInstallFileAsync(skillDir, f, filesWritten) {
45667
46315
  if (++filesWritten.count % INSTALL_SKILLS_YIELD_EVERY === 0) {
45668
46316
  await yieldToEventLoop();
45669
46317
  }
45670
- const dest = path77.join(skillDir, f.path);
45671
- await fs52.promises.mkdir(path77.dirname(dest), { recursive: true });
46318
+ const dest = path80.join(skillDir, f.path);
46319
+ await fs55.promises.mkdir(path80.dirname(dest), { recursive: true });
45672
46320
  if (f.text !== void 0) {
45673
- await fs52.promises.writeFile(dest, f.text, "utf8");
46321
+ await fs55.promises.writeFile(dest, f.text, "utf8");
45674
46322
  } else if (f.base64) {
45675
- await fs52.promises.writeFile(dest, Buffer.from(f.base64, "base64"));
46323
+ await fs55.promises.writeFile(dest, Buffer.from(f.base64, "base64"));
45676
46324
  }
45677
46325
  }
45678
46326
  async function installRemoteSkillsAsync(cwd, targetDir, items) {
@@ -45684,7 +46332,7 @@ async function installRemoteSkillsAsync(cwd, targetDir, items) {
45684
46332
  try {
45685
46333
  for (const item of items) {
45686
46334
  if (!isValidRemoteSkillInstallItem(item)) continue;
45687
- const skillDir = path77.join(cwd, targetDir, item.skillName);
46335
+ const skillDir = path80.join(cwd, targetDir, item.skillName);
45688
46336
  for (const f of item.files) {
45689
46337
  await writeInstallFileAsync(skillDir, f, filesWritten);
45690
46338
  }
@@ -45966,7 +46614,8 @@ var handleSessionDiscardedMessage = (msg, deps) => {
45966
46614
  };
45967
46615
 
45968
46616
  // src/routing/handlers/revert-turn-snapshot.ts
45969
- import * as fs53 from "node:fs";
46617
+ init_cwd();
46618
+ import * as fs56 from "node:fs";
45970
46619
  var handleRevertTurnSnapshotMessage = (msg, deps) => {
45971
46620
  const id = typeof msg.id === "string" ? msg.id : "";
45972
46621
  const sessionId = typeof msg.sessionId === "string" ? msg.sessionId : "";
@@ -45979,7 +46628,7 @@ var handleRevertTurnSnapshotMessage = (msg, deps) => {
45979
46628
  const agentBase = sessionWorktreeManager.getSessionWorktreeRootForSession(sessionId) ?? getBridgeRoot();
45980
46629
  const file2 = snapshotFilePath(agentBase, turnId);
45981
46630
  try {
45982
- await fs53.promises.access(file2, fs53.constants.F_OK);
46631
+ await fs56.promises.access(file2, fs56.constants.F_OK);
45983
46632
  } catch {
45984
46633
  sendWsMessage(s, {
45985
46634
  type: "revert_turn_snapshot_result",
@@ -46064,7 +46713,9 @@ var handleDeploySessionToPreviewMessage = (msg, deps) => {
46064
46713
  };
46065
46714
 
46066
46715
  // src/git/bridge-git-context.ts
46067
- import * as path78 from "node:path";
46716
+ init_cwd();
46717
+ init_yield_to_event_loop();
46718
+ import * as path81 from "node:path";
46068
46719
 
46069
46720
  // src/git/branches/get-current-branch.ts
46070
46721
  async function getCurrentBranch(repoPath) {
@@ -46114,12 +46765,12 @@ async function listRepoBranchRefs(repoPath) {
46114
46765
  // src/git/bridge-git-context.ts
46115
46766
  function folderNameForRelPath(relPath, bridgeRoot) {
46116
46767
  if (relPath === "." || relPath === "") {
46117
- return path78.basename(path78.resolve(bridgeRoot)) || "repo";
46768
+ return path81.basename(path81.resolve(bridgeRoot)) || "repo";
46118
46769
  }
46119
- return path78.basename(relPath) || relPath;
46770
+ return path81.basename(relPath) || relPath;
46120
46771
  }
46121
46772
  async function discoverGitReposForBridgeContext(bridgeRoot) {
46122
- const root = path78.resolve(bridgeRoot);
46773
+ const root = path81.resolve(bridgeRoot);
46123
46774
  if (await isGitRepoDirectory(root)) {
46124
46775
  const remoteUrl = await getRemoteOriginUrl(root);
46125
46776
  return [{ absolutePath: root, remoteUrl }];
@@ -46127,19 +46778,19 @@ async function discoverGitReposForBridgeContext(bridgeRoot) {
46127
46778
  const [deep, shallow] = await Promise.all([discoverGitReposUnderRoot(root), discoverGitRepos(root)]);
46128
46779
  const byPath = /* @__PURE__ */ new Map();
46129
46780
  for (const repo of [...deep, ...shallow]) {
46130
- byPath.set(path78.resolve(repo.absolutePath), repo);
46781
+ byPath.set(path81.resolve(repo.absolutePath), repo);
46131
46782
  }
46132
46783
  return [...byPath.values()];
46133
46784
  }
46134
46785
  async function getBridgeGitContext(bridgeRoot = getBridgeRoot()) {
46135
- const bridgeResolved = path78.resolve(bridgeRoot);
46786
+ const bridgeResolved = path81.resolve(bridgeRoot);
46136
46787
  const repos = await discoverGitReposForBridgeContext(bridgeResolved);
46137
46788
  const rows = [];
46138
46789
  for (let i = 0; i < repos.length; i++) {
46139
46790
  if (i > 0) await yieldToEventLoop();
46140
46791
  const repo = repos[i];
46141
- let rel = path78.relative(bridgeResolved, repo.absolutePath);
46142
- if (rel.startsWith("..") || path78.isAbsolute(rel)) continue;
46792
+ let rel = path81.relative(bridgeResolved, repo.absolutePath);
46793
+ if (rel.startsWith("..") || path81.isAbsolute(rel)) continue;
46143
46794
  const relPath = rel === "" ? "." : rel.replace(/\\/g, "/");
46144
46795
  const currentBranch = await getCurrentBranch(repo.absolutePath);
46145
46796
  const remoteUrl = repo.remoteUrl.trim() || null;
@@ -46154,11 +46805,11 @@ async function getBridgeGitContext(bridgeRoot = getBridgeRoot()) {
46154
46805
  return rows;
46155
46806
  }
46156
46807
  async function listRepoBranchesForBridge(repoRelPath, bridgeRoot = getBridgeRoot()) {
46157
- const bridgeResolved = path78.resolve(bridgeRoot);
46808
+ const bridgeResolved = path81.resolve(bridgeRoot);
46158
46809
  const rel = repoRelPath.trim() === "." ? "" : repoRelPath.trim().replace(/\\/g, "/");
46159
- const repoPath = rel === "" ? bridgeResolved : path78.join(bridgeResolved, rel);
46160
- const resolved = path78.resolve(repoPath);
46161
- if (!resolved.startsWith(bridgeResolved + path78.sep) && resolved !== bridgeResolved) {
46810
+ const repoPath = rel === "" ? bridgeResolved : path81.join(bridgeResolved, rel);
46811
+ const resolved = path81.resolve(repoPath);
46812
+ if (!resolved.startsWith(bridgeResolved + path81.sep) && resolved !== bridgeResolved) {
46162
46813
  return [];
46163
46814
  }
46164
46815
  return listRepoBranchRefs(resolved);