opencode-codebase-index 0.20.1 → 0.21.0

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.
@@ -661,6 +661,8 @@ __export(pi_extension_exports, {
661
661
  default: () => codebaseIndexPiExtension
662
662
  });
663
663
  module.exports = __toCommonJS(pi_extension_exports);
664
+
665
+ // src/adapters/pi/extension.ts
664
666
  var import_typebox2 = require("typebox");
665
667
 
666
668
  // src/config/constants.ts
@@ -1454,7 +1456,7 @@ var path19 = __toESM(require("path"), 1);
1454
1456
  // src/config/paths.ts
1455
1457
  var import_fs4 = require("fs");
1456
1458
  var os2 = __toESM(require("os"), 1);
1457
- var path4 = __toESM(require("path"), 1);
1459
+ var path5 = __toESM(require("path"), 1);
1458
1460
 
1459
1461
  // src/git/index.ts
1460
1462
  var import_fs3 = require("fs");
@@ -1586,15 +1588,125 @@ function getBranchOrDefault(repoRoot) {
1586
1588
  return getCurrentBranch(repoRoot) ?? "default";
1587
1589
  }
1588
1590
 
1591
+ // src/utils/canonical-path.ts
1592
+ var crypto = __toESM(require("crypto"), 1);
1593
+ var fs = __toESM(require("fs"), 1);
1594
+ var path4 = __toESM(require("path"), 1);
1595
+
1596
+ // node_modules/unicode-case-folding/index.js
1597
+ var FOLDING_MAP = /* @__PURE__ */ new Map([[65, [97]], [66, [98]], [67, [99]], [68, [100]], [69, [101]], [70, [102]], [71, [103]], [72, [104]], [73, [105]], [74, [106]], [75, [107]], [76, [108]], [77, [109]], [78, [110]], [79, [111]], [80, [112]], [81, [113]], [82, [114]], [83, [115]], [84, [116]], [85, [117]], [86, [118]], [87, [119]], [88, [120]], [89, [121]], [90, [122]], [181, [956]], [192, [224]], [193, [225]], [194, [226]], [195, [227]], [196, [228]], [197, [229]], [198, [230]], [199, [231]], [200, [232]], [201, [233]], [202, [234]], [203, [235]], [204, [236]], [205, [237]], [206, [238]], [207, [239]], [208, [240]], [209, [241]], [210, [242]], [211, [243]], [212, [244]], [213, [245]], [214, [246]], [216, [248]], [217, [249]], [218, [250]], [219, [251]], [220, [252]], [221, [253]], [222, [254]], [223, [115, 115]], [256, [257]], [258, [259]], [260, [261]], [262, [263]], [264, [265]], [266, [267]], [268, [269]], [270, [271]], [272, [273]], [274, [275]], [276, [277]], [278, [279]], [280, [281]], [282, [283]], [284, [285]], [286, [287]], [288, [289]], [290, [291]], [292, [293]], [294, [295]], [296, [297]], [298, [299]], [300, [301]], [302, [303]], [304, [105, 775]], [306, [307]], [308, [309]], [310, [311]], [313, [314]], [315, [316]], [317, [318]], [319, [320]], [321, [322]], [323, [324]], [325, [326]], [327, [328]], [329, [700, 110]], [330, [331]], [332, [333]], [334, [335]], [336, [337]], [338, [339]], [340, [341]], [342, [343]], [344, [345]], [346, [347]], [348, [349]], [350, [351]], [352, [353]], [354, [355]], [356, [357]], [358, [359]], [360, [361]], [362, [363]], [364, [365]], [366, [367]], [368, [369]], [370, [371]], [372, [373]], [374, [375]], [376, [255]], [377, [378]], [379, [380]], [381, [382]], [383, [115]], [385, [595]], [386, [387]], [388, [389]], [390, [596]], [391, [392]], [393, [598]], [394, [599]], [395, [396]], [398, [477]], [399, [601]], [400, [603]], [401, [402]], [403, [608]], [404, [611]], [406, [617]], [407, [616]], [408, [409]], [412, [623]], [413, [626]], [415, [629]], [416, [417]], [418, [419]], [420, [421]], [422, [640]], [423, [424]], [425, [643]], [428, [429]], [430, [648]], [431, [432]], [433, [650]], [434, [651]], [435, [436]], [437, [438]], [439, [658]], [440, [441]], [444, [445]], [452, [454]], [453, [454]], [455, [457]], [456, [457]], [458, [460]], [459, [460]], [461, [462]], [463, [464]], [465, [466]], [467, [468]], [469, [470]], [471, [472]], [473, [474]], [475, [476]], [478, [479]], [480, [481]], [482, [483]], [484, [485]], [486, [487]], [488, [489]], [490, [491]], [492, [493]], [494, [495]], [496, [106, 780]], [497, [499]], [498, [499]], [500, [501]], [502, [405]], [503, [447]], [504, [505]], [506, [507]], [508, [509]], [510, [511]], [512, [513]], [514, [515]], [516, [517]], [518, [519]], [520, [521]], [522, [523]], [524, [525]], [526, [527]], [528, [529]], [530, [531]], [532, [533]], [534, [535]], [536, [537]], [538, [539]], [540, [541]], [542, [543]], [544, [414]], [546, [547]], [548, [549]], [550, [551]], [552, [553]], [554, [555]], [556, [557]], [558, [559]], [560, [561]], [562, [563]], [570, [11365]], [571, [572]], [573, [410]], [574, [11366]], [577, [578]], [579, [384]], [580, [649]], [581, [652]], [582, [583]], [584, [585]], [586, [587]], [588, [589]], [590, [591]], [837, [953]], [880, [881]], [882, [883]], [886, [887]], [895, [1011]], [902, [940]], [904, [941]], [905, [942]], [906, [943]], [908, [972]], [910, [973]], [911, [974]], [912, [953, 776, 769]], [913, [945]], [914, [946]], [915, [947]], [916, [948]], [917, [949]], [918, [950]], [919, [951]], [920, [952]], [921, [953]], [922, [954]], [923, [955]], [924, [956]], [925, [957]], [926, [958]], [927, [959]], [928, [960]], [929, [961]], [931, [963]], [932, [964]], [933, [965]], [934, [966]], [935, [967]], [936, [968]], [937, [969]], [938, [970]], [939, [971]], [944, [965, 776, 769]], [962, [963]], [975, [983]], [976, [946]], [977, [952]], [981, [966]], [982, [960]], [984, [985]], [986, [987]], [988, [989]], [990, [991]], [992, [993]], [994, [995]], [996, [997]], [998, [999]], [1e3, [1001]], [1002, [1003]], [1004, [1005]], [1006, [1007]], [1008, [954]], [1009, [961]], [1012, [952]], [1013, [949]], [1015, [1016]], [1017, [1010]], [1018, [1019]], [1021, [891]], [1022, [892]], [1023, [893]], [1024, [1104]], [1025, [1105]], [1026, [1106]], [1027, [1107]], [1028, [1108]], [1029, [1109]], [1030, [1110]], [1031, [1111]], [1032, [1112]], [1033, [1113]], [1034, [1114]], [1035, [1115]], [1036, [1116]], [1037, [1117]], [1038, [1118]], [1039, [1119]], [1040, [1072]], [1041, [1073]], [1042, [1074]], [1043, [1075]], [1044, [1076]], [1045, [1077]], [1046, [1078]], [1047, [1079]], [1048, [1080]], [1049, [1081]], [1050, [1082]], [1051, [1083]], [1052, [1084]], [1053, [1085]], [1054, [1086]], [1055, [1087]], [1056, [1088]], [1057, [1089]], [1058, [1090]], [1059, [1091]], [1060, [1092]], [1061, [1093]], [1062, [1094]], [1063, [1095]], [1064, [1096]], [1065, [1097]], [1066, [1098]], [1067, [1099]], [1068, [1100]], [1069, [1101]], [1070, [1102]], [1071, [1103]], [1120, [1121]], [1122, [1123]], [1124, [1125]], [1126, [1127]], [1128, [1129]], [1130, [1131]], [1132, [1133]], [1134, [1135]], [1136, [1137]], [1138, [1139]], [1140, [1141]], [1142, [1143]], [1144, [1145]], [1146, [1147]], [1148, [1149]], [1150, [1151]], [1152, [1153]], [1162, [1163]], [1164, [1165]], [1166, [1167]], [1168, [1169]], [1170, [1171]], [1172, [1173]], [1174, [1175]], [1176, [1177]], [1178, [1179]], [1180, [1181]], [1182, [1183]], [1184, [1185]], [1186, [1187]], [1188, [1189]], [1190, [1191]], [1192, [1193]], [1194, [1195]], [1196, [1197]], [1198, [1199]], [1200, [1201]], [1202, [1203]], [1204, [1205]], [1206, [1207]], [1208, [1209]], [1210, [1211]], [1212, [1213]], [1214, [1215]], [1216, [1231]], [1217, [1218]], [1219, [1220]], [1221, [1222]], [1223, [1224]], [1225, [1226]], [1227, [1228]], [1229, [1230]], [1232, [1233]], [1234, [1235]], [1236, [1237]], [1238, [1239]], [1240, [1241]], [1242, [1243]], [1244, [1245]], [1246, [1247]], [1248, [1249]], [1250, [1251]], [1252, [1253]], [1254, [1255]], [1256, [1257]], [1258, [1259]], [1260, [1261]], [1262, [1263]], [1264, [1265]], [1266, [1267]], [1268, [1269]], [1270, [1271]], [1272, [1273]], [1274, [1275]], [1276, [1277]], [1278, [1279]], [1280, [1281]], [1282, [1283]], [1284, [1285]], [1286, [1287]], [1288, [1289]], [1290, [1291]], [1292, [1293]], [1294, [1295]], [1296, [1297]], [1298, [1299]], [1300, [1301]], [1302, [1303]], [1304, [1305]], [1306, [1307]], [1308, [1309]], [1310, [1311]], [1312, [1313]], [1314, [1315]], [1316, [1317]], [1318, [1319]], [1320, [1321]], [1322, [1323]], [1324, [1325]], [1326, [1327]], [1329, [1377]], [1330, [1378]], [1331, [1379]], [1332, [1380]], [1333, [1381]], [1334, [1382]], [1335, [1383]], [1336, [1384]], [1337, [1385]], [1338, [1386]], [1339, [1387]], [1340, [1388]], [1341, [1389]], [1342, [1390]], [1343, [1391]], [1344, [1392]], [1345, [1393]], [1346, [1394]], [1347, [1395]], [1348, [1396]], [1349, [1397]], [1350, [1398]], [1351, [1399]], [1352, [1400]], [1353, [1401]], [1354, [1402]], [1355, [1403]], [1356, [1404]], [1357, [1405]], [1358, [1406]], [1359, [1407]], [1360, [1408]], [1361, [1409]], [1362, [1410]], [1363, [1411]], [1364, [1412]], [1365, [1413]], [1366, [1414]], [1415, [1381, 1410]], [4256, [11520]], [4257, [11521]], [4258, [11522]], [4259, [11523]], [4260, [11524]], [4261, [11525]], [4262, [11526]], [4263, [11527]], [4264, [11528]], [4265, [11529]], [4266, [11530]], [4267, [11531]], [4268, [11532]], [4269, [11533]], [4270, [11534]], [4271, [11535]], [4272, [11536]], [4273, [11537]], [4274, [11538]], [4275, [11539]], [4276, [11540]], [4277, [11541]], [4278, [11542]], [4279, [11543]], [4280, [11544]], [4281, [11545]], [4282, [11546]], [4283, [11547]], [4284, [11548]], [4285, [11549]], [4286, [11550]], [4287, [11551]], [4288, [11552]], [4289, [11553]], [4290, [11554]], [4291, [11555]], [4292, [11556]], [4293, [11557]], [4295, [11559]], [4301, [11565]], [5112, [5104]], [5113, [5105]], [5114, [5106]], [5115, [5107]], [5116, [5108]], [5117, [5109]], [7296, [1074]], [7297, [1076]], [7298, [1086]], [7299, [1089]], [7300, [1090]], [7301, [1090]], [7302, [1098]], [7303, [1123]], [7304, [42571]], [7305, [7306]], [7312, [4304]], [7313, [4305]], [7314, [4306]], [7315, [4307]], [7316, [4308]], [7317, [4309]], [7318, [4310]], [7319, [4311]], [7320, [4312]], [7321, [4313]], [7322, [4314]], [7323, [4315]], [7324, [4316]], [7325, [4317]], [7326, [4318]], [7327, [4319]], [7328, [4320]], [7329, [4321]], [7330, [4322]], [7331, [4323]], [7332, [4324]], [7333, [4325]], [7334, [4326]], [7335, [4327]], [7336, [4328]], [7337, [4329]], [7338, [4330]], [7339, [4331]], [7340, [4332]], [7341, [4333]], [7342, [4334]], [7343, [4335]], [7344, [4336]], [7345, [4337]], [7346, [4338]], [7347, [4339]], [7348, [4340]], [7349, [4341]], [7350, [4342]], [7351, [4343]], [7352, [4344]], [7353, [4345]], [7354, [4346]], [7357, [4349]], [7358, [4350]], [7359, [4351]], [7680, [7681]], [7682, [7683]], [7684, [7685]], [7686, [7687]], [7688, [7689]], [7690, [7691]], [7692, [7693]], [7694, [7695]], [7696, [7697]], [7698, [7699]], [7700, [7701]], [7702, [7703]], [7704, [7705]], [7706, [7707]], [7708, [7709]], [7710, [7711]], [7712, [7713]], [7714, [7715]], [7716, [7717]], [7718, [7719]], [7720, [7721]], [7722, [7723]], [7724, [7725]], [7726, [7727]], [7728, [7729]], [7730, [7731]], [7732, [7733]], [7734, [7735]], [7736, [7737]], [7738, [7739]], [7740, [7741]], [7742, [7743]], [7744, [7745]], [7746, [7747]], [7748, [7749]], [7750, [7751]], [7752, [7753]], [7754, [7755]], [7756, [7757]], [7758, [7759]], [7760, [7761]], [7762, [7763]], [7764, [7765]], [7766, [7767]], [7768, [7769]], [7770, [7771]], [7772, [7773]], [7774, [7775]], [7776, [7777]], [7778, [7779]], [7780, [7781]], [7782, [7783]], [7784, [7785]], [7786, [7787]], [7788, [7789]], [7790, [7791]], [7792, [7793]], [7794, [7795]], [7796, [7797]], [7798, [7799]], [7800, [7801]], [7802, [7803]], [7804, [7805]], [7806, [7807]], [7808, [7809]], [7810, [7811]], [7812, [7813]], [7814, [7815]], [7816, [7817]], [7818, [7819]], [7820, [7821]], [7822, [7823]], [7824, [7825]], [7826, [7827]], [7828, [7829]], [7830, [104, 817]], [7831, [116, 776]], [7832, [119, 778]], [7833, [121, 778]], [7834, [97, 702]], [7835, [7777]], [7838, [115, 115]], [7840, [7841]], [7842, [7843]], [7844, [7845]], [7846, [7847]], [7848, [7849]], [7850, [7851]], [7852, [7853]], [7854, [7855]], [7856, [7857]], [7858, [7859]], [7860, [7861]], [7862, [7863]], [7864, [7865]], [7866, [7867]], [7868, [7869]], [7870, [7871]], [7872, [7873]], [7874, [7875]], [7876, [7877]], [7878, [7879]], [7880, [7881]], [7882, [7883]], [7884, [7885]], [7886, [7887]], [7888, [7889]], [7890, [7891]], [7892, [7893]], [7894, [7895]], [7896, [7897]], [7898, [7899]], [7900, [7901]], [7902, [7903]], [7904, [7905]], [7906, [7907]], [7908, [7909]], [7910, [7911]], [7912, [7913]], [7914, [7915]], [7916, [7917]], [7918, [7919]], [7920, [7921]], [7922, [7923]], [7924, [7925]], [7926, [7927]], [7928, [7929]], [7930, [7931]], [7932, [7933]], [7934, [7935]], [7944, [7936]], [7945, [7937]], [7946, [7938]], [7947, [7939]], [7948, [7940]], [7949, [7941]], [7950, [7942]], [7951, [7943]], [7960, [7952]], [7961, [7953]], [7962, [7954]], [7963, [7955]], [7964, [7956]], [7965, [7957]], [7976, [7968]], [7977, [7969]], [7978, [7970]], [7979, [7971]], [7980, [7972]], [7981, [7973]], [7982, [7974]], [7983, [7975]], [7992, [7984]], [7993, [7985]], [7994, [7986]], [7995, [7987]], [7996, [7988]], [7997, [7989]], [7998, [7990]], [7999, [7991]], [8008, [8e3]], [8009, [8001]], [8010, [8002]], [8011, [8003]], [8012, [8004]], [8013, [8005]], [8016, [965, 787]], [8018, [965, 787, 768]], [8020, [965, 787, 769]], [8022, [965, 787, 834]], [8025, [8017]], [8027, [8019]], [8029, [8021]], [8031, [8023]], [8040, [8032]], [8041, [8033]], [8042, [8034]], [8043, [8035]], [8044, [8036]], [8045, [8037]], [8046, [8038]], [8047, [8039]], [8064, [7936, 953]], [8065, [7937, 953]], [8066, [7938, 953]], [8067, [7939, 953]], [8068, [7940, 953]], [8069, [7941, 953]], [8070, [7942, 953]], [8071, [7943, 953]], [8072, [7936, 953]], [8073, [7937, 953]], [8074, [7938, 953]], [8075, [7939, 953]], [8076, [7940, 953]], [8077, [7941, 953]], [8078, [7942, 953]], [8079, [7943, 953]], [8080, [7968, 953]], [8081, [7969, 953]], [8082, [7970, 953]], [8083, [7971, 953]], [8084, [7972, 953]], [8085, [7973, 953]], [8086, [7974, 953]], [8087, [7975, 953]], [8088, [7968, 953]], [8089, [7969, 953]], [8090, [7970, 953]], [8091, [7971, 953]], [8092, [7972, 953]], [8093, [7973, 953]], [8094, [7974, 953]], [8095, [7975, 953]], [8096, [8032, 953]], [8097, [8033, 953]], [8098, [8034, 953]], [8099, [8035, 953]], [8100, [8036, 953]], [8101, [8037, 953]], [8102, [8038, 953]], [8103, [8039, 953]], [8104, [8032, 953]], [8105, [8033, 953]], [8106, [8034, 953]], [8107, [8035, 953]], [8108, [8036, 953]], [8109, [8037, 953]], [8110, [8038, 953]], [8111, [8039, 953]], [8114, [8048, 953]], [8115, [945, 953]], [8116, [940, 953]], [8118, [945, 834]], [8119, [945, 834, 953]], [8120, [8112]], [8121, [8113]], [8122, [8048]], [8123, [8049]], [8124, [945, 953]], [8126, [953]], [8130, [8052, 953]], [8131, [951, 953]], [8132, [942, 953]], [8134, [951, 834]], [8135, [951, 834, 953]], [8136, [8050]], [8137, [8051]], [8138, [8052]], [8139, [8053]], [8140, [951, 953]], [8146, [953, 776, 768]], [8147, [953, 776, 769]], [8150, [953, 834]], [8151, [953, 776, 834]], [8152, [8144]], [8153, [8145]], [8154, [8054]], [8155, [8055]], [8162, [965, 776, 768]], [8163, [965, 776, 769]], [8164, [961, 787]], [8166, [965, 834]], [8167, [965, 776, 834]], [8168, [8160]], [8169, [8161]], [8170, [8058]], [8171, [8059]], [8172, [8165]], [8178, [8060, 953]], [8179, [969, 953]], [8180, [974, 953]], [8182, [969, 834]], [8183, [969, 834, 953]], [8184, [8056]], [8185, [8057]], [8186, [8060]], [8187, [8061]], [8188, [969, 953]], [8486, [969]], [8490, [107]], [8491, [229]], [8498, [8526]], [8544, [8560]], [8545, [8561]], [8546, [8562]], [8547, [8563]], [8548, [8564]], [8549, [8565]], [8550, [8566]], [8551, [8567]], [8552, [8568]], [8553, [8569]], [8554, [8570]], [8555, [8571]], [8556, [8572]], [8557, [8573]], [8558, [8574]], [8559, [8575]], [8579, [8580]], [9398, [9424]], [9399, [9425]], [9400, [9426]], [9401, [9427]], [9402, [9428]], [9403, [9429]], [9404, [9430]], [9405, [9431]], [9406, [9432]], [9407, [9433]], [9408, [9434]], [9409, [9435]], [9410, [9436]], [9411, [9437]], [9412, [9438]], [9413, [9439]], [9414, [9440]], [9415, [9441]], [9416, [9442]], [9417, [9443]], [9418, [9444]], [9419, [9445]], [9420, [9446]], [9421, [9447]], [9422, [9448]], [9423, [9449]], [11264, [11312]], [11265, [11313]], [11266, [11314]], [11267, [11315]], [11268, [11316]], [11269, [11317]], [11270, [11318]], [11271, [11319]], [11272, [11320]], [11273, [11321]], [11274, [11322]], [11275, [11323]], [11276, [11324]], [11277, [11325]], [11278, [11326]], [11279, [11327]], [11280, [11328]], [11281, [11329]], [11282, [11330]], [11283, [11331]], [11284, [11332]], [11285, [11333]], [11286, [11334]], [11287, [11335]], [11288, [11336]], [11289, [11337]], [11290, [11338]], [11291, [11339]], [11292, [11340]], [11293, [11341]], [11294, [11342]], [11295, [11343]], [11296, [11344]], [11297, [11345]], [11298, [11346]], [11299, [11347]], [11300, [11348]], [11301, [11349]], [11302, [11350]], [11303, [11351]], [11304, [11352]], [11305, [11353]], [11306, [11354]], [11307, [11355]], [11308, [11356]], [11309, [11357]], [11310, [11358]], [11311, [11359]], [11360, [11361]], [11362, [619]], [11363, [7549]], [11364, [637]], [11367, [11368]], [11369, [11370]], [11371, [11372]], [11373, [593]], [11374, [625]], [11375, [592]], [11376, [594]], [11378, [11379]], [11381, [11382]], [11390, [575]], [11391, [576]], [11392, [11393]], [11394, [11395]], [11396, [11397]], [11398, [11399]], [11400, [11401]], [11402, [11403]], [11404, [11405]], [11406, [11407]], [11408, [11409]], [11410, [11411]], [11412, [11413]], [11414, [11415]], [11416, [11417]], [11418, [11419]], [11420, [11421]], [11422, [11423]], [11424, [11425]], [11426, [11427]], [11428, [11429]], [11430, [11431]], [11432, [11433]], [11434, [11435]], [11436, [11437]], [11438, [11439]], [11440, [11441]], [11442, [11443]], [11444, [11445]], [11446, [11447]], [11448, [11449]], [11450, [11451]], [11452, [11453]], [11454, [11455]], [11456, [11457]], [11458, [11459]], [11460, [11461]], [11462, [11463]], [11464, [11465]], [11466, [11467]], [11468, [11469]], [11470, [11471]], [11472, [11473]], [11474, [11475]], [11476, [11477]], [11478, [11479]], [11480, [11481]], [11482, [11483]], [11484, [11485]], [11486, [11487]], [11488, [11489]], [11490, [11491]], [11499, [11500]], [11501, [11502]], [11506, [11507]], [42560, [42561]], [42562, [42563]], [42564, [42565]], [42566, [42567]], [42568, [42569]], [42570, [42571]], [42572, [42573]], [42574, [42575]], [42576, [42577]], [42578, [42579]], [42580, [42581]], [42582, [42583]], [42584, [42585]], [42586, [42587]], [42588, [42589]], [42590, [42591]], [42592, [42593]], [42594, [42595]], [42596, [42597]], [42598, [42599]], [42600, [42601]], [42602, [42603]], [42604, [42605]], [42624, [42625]], [42626, [42627]], [42628, [42629]], [42630, [42631]], [42632, [42633]], [42634, [42635]], [42636, [42637]], [42638, [42639]], [42640, [42641]], [42642, [42643]], [42644, [42645]], [42646, [42647]], [42648, [42649]], [42650, [42651]], [42786, [42787]], [42788, [42789]], [42790, [42791]], [42792, [42793]], [42794, [42795]], [42796, [42797]], [42798, [42799]], [42802, [42803]], [42804, [42805]], [42806, [42807]], [42808, [42809]], [42810, [42811]], [42812, [42813]], [42814, [42815]], [42816, [42817]], [42818, [42819]], [42820, [42821]], [42822, [42823]], [42824, [42825]], [42826, [42827]], [42828, [42829]], [42830, [42831]], [42832, [42833]], [42834, [42835]], [42836, [42837]], [42838, [42839]], [42840, [42841]], [42842, [42843]], [42844, [42845]], [42846, [42847]], [42848, [42849]], [42850, [42851]], [42852, [42853]], [42854, [42855]], [42856, [42857]], [42858, [42859]], [42860, [42861]], [42862, [42863]], [42873, [42874]], [42875, [42876]], [42877, [7545]], [42878, [42879]], [42880, [42881]], [42882, [42883]], [42884, [42885]], [42886, [42887]], [42891, [42892]], [42893, [613]], [42896, [42897]], [42898, [42899]], [42902, [42903]], [42904, [42905]], [42906, [42907]], [42908, [42909]], [42910, [42911]], [42912, [42913]], [42914, [42915]], [42916, [42917]], [42918, [42919]], [42920, [42921]], [42922, [614]], [42923, [604]], [42924, [609]], [42925, [620]], [42926, [618]], [42928, [670]], [42929, [647]], [42930, [669]], [42931, [43859]], [42932, [42933]], [42934, [42935]], [42936, [42937]], [42938, [42939]], [42940, [42941]], [42942, [42943]], [42944, [42945]], [42946, [42947]], [42948, [42900]], [42949, [642]], [42950, [7566]], [42951, [42952]], [42953, [42954]], [42955, [612]], [42956, [42957]], [42958, [42959]], [42960, [42961]], [42962, [42963]], [42964, [42965]], [42966, [42967]], [42968, [42969]], [42970, [42971]], [42972, [411]], [42997, [42998]], [43888, [5024]], [43889, [5025]], [43890, [5026]], [43891, [5027]], [43892, [5028]], [43893, [5029]], [43894, [5030]], [43895, [5031]], [43896, [5032]], [43897, [5033]], [43898, [5034]], [43899, [5035]], [43900, [5036]], [43901, [5037]], [43902, [5038]], [43903, [5039]], [43904, [5040]], [43905, [5041]], [43906, [5042]], [43907, [5043]], [43908, [5044]], [43909, [5045]], [43910, [5046]], [43911, [5047]], [43912, [5048]], [43913, [5049]], [43914, [5050]], [43915, [5051]], [43916, [5052]], [43917, [5053]], [43918, [5054]], [43919, [5055]], [43920, [5056]], [43921, [5057]], [43922, [5058]], [43923, [5059]], [43924, [5060]], [43925, [5061]], [43926, [5062]], [43927, [5063]], [43928, [5064]], [43929, [5065]], [43930, [5066]], [43931, [5067]], [43932, [5068]], [43933, [5069]], [43934, [5070]], [43935, [5071]], [43936, [5072]], [43937, [5073]], [43938, [5074]], [43939, [5075]], [43940, [5076]], [43941, [5077]], [43942, [5078]], [43943, [5079]], [43944, [5080]], [43945, [5081]], [43946, [5082]], [43947, [5083]], [43948, [5084]], [43949, [5085]], [43950, [5086]], [43951, [5087]], [43952, [5088]], [43953, [5089]], [43954, [5090]], [43955, [5091]], [43956, [5092]], [43957, [5093]], [43958, [5094]], [43959, [5095]], [43960, [5096]], [43961, [5097]], [43962, [5098]], [43963, [5099]], [43964, [5100]], [43965, [5101]], [43966, [5102]], [43967, [5103]], [64256, [102, 102]], [64257, [102, 105]], [64258, [102, 108]], [64259, [102, 102, 105]], [64260, [102, 102, 108]], [64261, [115, 116]], [64262, [115, 116]], [64275, [1396, 1398]], [64276, [1396, 1381]], [64277, [1396, 1387]], [64278, [1406, 1398]], [64279, [1396, 1389]], [65313, [65345]], [65314, [65346]], [65315, [65347]], [65316, [65348]], [65317, [65349]], [65318, [65350]], [65319, [65351]], [65320, [65352]], [65321, [65353]], [65322, [65354]], [65323, [65355]], [65324, [65356]], [65325, [65357]], [65326, [65358]], [65327, [65359]], [65328, [65360]], [65329, [65361]], [65330, [65362]], [65331, [65363]], [65332, [65364]], [65333, [65365]], [65334, [65366]], [65335, [65367]], [65336, [65368]], [65337, [65369]], [65338, [65370]], [66560, [66600]], [66561, [66601]], [66562, [66602]], [66563, [66603]], [66564, [66604]], [66565, [66605]], [66566, [66606]], [66567, [66607]], [66568, [66608]], [66569, [66609]], [66570, [66610]], [66571, [66611]], [66572, [66612]], [66573, [66613]], [66574, [66614]], [66575, [66615]], [66576, [66616]], [66577, [66617]], [66578, [66618]], [66579, [66619]], [66580, [66620]], [66581, [66621]], [66582, [66622]], [66583, [66623]], [66584, [66624]], [66585, [66625]], [66586, [66626]], [66587, [66627]], [66588, [66628]], [66589, [66629]], [66590, [66630]], [66591, [66631]], [66592, [66632]], [66593, [66633]], [66594, [66634]], [66595, [66635]], [66596, [66636]], [66597, [66637]], [66598, [66638]], [66599, [66639]], [66736, [66776]], [66737, [66777]], [66738, [66778]], [66739, [66779]], [66740, [66780]], [66741, [66781]], [66742, [66782]], [66743, [66783]], [66744, [66784]], [66745, [66785]], [66746, [66786]], [66747, [66787]], [66748, [66788]], [66749, [66789]], [66750, [66790]], [66751, [66791]], [66752, [66792]], [66753, [66793]], [66754, [66794]], [66755, [66795]], [66756, [66796]], [66757, [66797]], [66758, [66798]], [66759, [66799]], [66760, [66800]], [66761, [66801]], [66762, [66802]], [66763, [66803]], [66764, [66804]], [66765, [66805]], [66766, [66806]], [66767, [66807]], [66768, [66808]], [66769, [66809]], [66770, [66810]], [66771, [66811]], [66928, [66967]], [66929, [66968]], [66930, [66969]], [66931, [66970]], [66932, [66971]], [66933, [66972]], [66934, [66973]], [66935, [66974]], [66936, [66975]], [66937, [66976]], [66938, [66977]], [66940, [66979]], [66941, [66980]], [66942, [66981]], [66943, [66982]], [66944, [66983]], [66945, [66984]], [66946, [66985]], [66947, [66986]], [66948, [66987]], [66949, [66988]], [66950, [66989]], [66951, [66990]], [66952, [66991]], [66953, [66992]], [66954, [66993]], [66956, [66995]], [66957, [66996]], [66958, [66997]], [66959, [66998]], [66960, [66999]], [66961, [67e3]], [66962, [67001]], [66964, [67003]], [66965, [67004]], [68736, [68800]], [68737, [68801]], [68738, [68802]], [68739, [68803]], [68740, [68804]], [68741, [68805]], [68742, [68806]], [68743, [68807]], [68744, [68808]], [68745, [68809]], [68746, [68810]], [68747, [68811]], [68748, [68812]], [68749, [68813]], [68750, [68814]], [68751, [68815]], [68752, [68816]], [68753, [68817]], [68754, [68818]], [68755, [68819]], [68756, [68820]], [68757, [68821]], [68758, [68822]], [68759, [68823]], [68760, [68824]], [68761, [68825]], [68762, [68826]], [68763, [68827]], [68764, [68828]], [68765, [68829]], [68766, [68830]], [68767, [68831]], [68768, [68832]], [68769, [68833]], [68770, [68834]], [68771, [68835]], [68772, [68836]], [68773, [68837]], [68774, [68838]], [68775, [68839]], [68776, [68840]], [68777, [68841]], [68778, [68842]], [68779, [68843]], [68780, [68844]], [68781, [68845]], [68782, [68846]], [68783, [68847]], [68784, [68848]], [68785, [68849]], [68786, [68850]], [68944, [68976]], [68945, [68977]], [68946, [68978]], [68947, [68979]], [68948, [68980]], [68949, [68981]], [68950, [68982]], [68951, [68983]], [68952, [68984]], [68953, [68985]], [68954, [68986]], [68955, [68987]], [68956, [68988]], [68957, [68989]], [68958, [68990]], [68959, [68991]], [68960, [68992]], [68961, [68993]], [68962, [68994]], [68963, [68995]], [68964, [68996]], [68965, [68997]], [71840, [71872]], [71841, [71873]], [71842, [71874]], [71843, [71875]], [71844, [71876]], [71845, [71877]], [71846, [71878]], [71847, [71879]], [71848, [71880]], [71849, [71881]], [71850, [71882]], [71851, [71883]], [71852, [71884]], [71853, [71885]], [71854, [71886]], [71855, [71887]], [71856, [71888]], [71857, [71889]], [71858, [71890]], [71859, [71891]], [71860, [71892]], [71861, [71893]], [71862, [71894]], [71863, [71895]], [71864, [71896]], [71865, [71897]], [71866, [71898]], [71867, [71899]], [71868, [71900]], [71869, [71901]], [71870, [71902]], [71871, [71903]], [93760, [93792]], [93761, [93793]], [93762, [93794]], [93763, [93795]], [93764, [93796]], [93765, [93797]], [93766, [93798]], [93767, [93799]], [93768, [93800]], [93769, [93801]], [93770, [93802]], [93771, [93803]], [93772, [93804]], [93773, [93805]], [93774, [93806]], [93775, [93807]], [93776, [93808]], [93777, [93809]], [93778, [93810]], [93779, [93811]], [93780, [93812]], [93781, [93813]], [93782, [93814]], [93783, [93815]], [93784, [93816]], [93785, [93817]], [93786, [93818]], [93787, [93819]], [93788, [93820]], [93789, [93821]], [93790, [93822]], [93791, [93823]], [93856, [93883]], [93857, [93884]], [93858, [93885]], [93859, [93886]], [93860, [93887]], [93861, [93888]], [93862, [93889]], [93863, [93890]], [93864, [93891]], [93865, [93892]], [93866, [93893]], [93867, [93894]], [93868, [93895]], [93869, [93896]], [93870, [93897]], [93871, [93898]], [93872, [93899]], [93873, [93900]], [93874, [93901]], [93875, [93902]], [93876, [93903]], [93877, [93904]], [93878, [93905]], [93879, [93906]], [93880, [93907]], [125184, [125218]], [125185, [125219]], [125186, [125220]], [125187, [125221]], [125188, [125222]], [125189, [125223]], [125190, [125224]], [125191, [125225]], [125192, [125226]], [125193, [125227]], [125194, [125228]], [125195, [125229]], [125196, [125230]], [125197, [125231]], [125198, [125232]], [125199, [125233]], [125200, [125234]], [125201, [125235]], [125202, [125236]], [125203, [125237]], [125204, [125238]], [125205, [125239]], [125206, [125240]], [125207, [125241]], [125208, [125242]], [125209, [125243]], [125210, [125244]], [125211, [125245]], [125212, [125246]], [125213, [125247]], [125214, [125248]], [125215, [125249]], [125216, [125250]], [125217, [125251]]]);
1598
+ function caseFold(input) {
1599
+ if (typeof input !== "string") {
1600
+ throw new TypeError("Input must be a string");
1601
+ }
1602
+ let result = [];
1603
+ for (const char of input) {
1604
+ const codePoint = char.codePointAt(0);
1605
+ const mapping = FOLDING_MAP.get(codePoint);
1606
+ result.push(mapping ? String.fromCodePoint(...mapping) : char);
1607
+ }
1608
+ return result.join("");
1609
+ }
1610
+
1611
+ // src/utils/canonical-path.ts
1612
+ function alternateAsciiCase(value) {
1613
+ const index = value.search(/[A-Za-z]/);
1614
+ if (index === -1) return null;
1615
+ const character = value[index];
1616
+ const alternate = character === character.toLowerCase() ? character.toUpperCase() : character.toLowerCase();
1617
+ return `${value.slice(0, index)}${alternate}${value.slice(index + 1)}`;
1618
+ }
1619
+ function probeEntryCaseSensitivity(entryPath) {
1620
+ const alternateName = alternateAsciiCase(path4.basename(entryPath));
1621
+ if (!alternateName) return void 0;
1622
+ try {
1623
+ const canonicalPath = fs.realpathSync.native(entryPath);
1624
+ const alternatePath = fs.realpathSync.native(path4.join(path4.dirname(entryPath), alternateName));
1625
+ return canonicalPath === alternatePath;
1626
+ } catch (error) {
1627
+ const code = error.code;
1628
+ if (code === "ENOENT" || code === "ENOTDIR") return false;
1629
+ return void 0;
1630
+ }
1631
+ }
1632
+ function probeEmptyWindowsDirectory(existingAncestor) {
1633
+ const probePath = path4.join(
1634
+ existingAncestor,
1635
+ `.codebase-index-case-probe-${crypto.randomBytes(8).toString("hex")}`
1636
+ );
1637
+ let created = false;
1638
+ try {
1639
+ const descriptor = fs.openSync(probePath, "wx", 384);
1640
+ created = true;
1641
+ fs.closeSync(descriptor);
1642
+ return probeEntryCaseSensitivity(probePath);
1643
+ } catch {
1644
+ return void 0;
1645
+ } finally {
1646
+ if (created) fs.unlinkSync(probePath);
1647
+ }
1648
+ }
1649
+ function detectCaseInsensitiveFileSystem(existingAncestor) {
1650
+ try {
1651
+ if (fs.statSync(existingAncestor).isDirectory()) {
1652
+ const directory = fs.opendirSync(existingAncestor);
1653
+ try {
1654
+ let entry = directory.readSync();
1655
+ while (entry) {
1656
+ if (!entry.isSymbolicLink() && alternateAsciiCase(entry.name)) {
1657
+ const result = probeEntryCaseSensitivity(path4.join(existingAncestor, entry.name));
1658
+ if (result !== void 0) return result;
1659
+ }
1660
+ entry = directory.readSync();
1661
+ }
1662
+ } finally {
1663
+ directory.closeSync();
1664
+ }
1665
+ }
1666
+ } catch {
1667
+ return void 0;
1668
+ }
1669
+ if (process.platform === "darwin") {
1670
+ return probeEntryCaseSensitivity(existingAncestor);
1671
+ }
1672
+ if (process.platform === "win32") {
1673
+ return probeEmptyWindowsDirectory(existingAncestor);
1674
+ }
1675
+ return void 0;
1676
+ }
1677
+ function foldMissingPathComponent(component) {
1678
+ return caseFold(component);
1679
+ }
1680
+ function canonicalizePathForComparison(targetPath, options = {}) {
1681
+ const resolved = path4.resolve(targetPath);
1682
+ const missingParts = [];
1683
+ let candidate = resolved;
1684
+ while (true) {
1685
+ try {
1686
+ const existingAncestor = fs.realpathSync.native(candidate);
1687
+ const isCaseInsensitive = missingParts.length > 0 ? (options.isCaseInsensitive ?? detectCaseInsensitiveFileSystem)(existingAncestor) : false;
1688
+ const suffix = isCaseInsensitive === true ? missingParts.map(foldMissingPathComponent) : missingParts;
1689
+ return path4.join(existingAncestor, ...suffix);
1690
+ } catch (error) {
1691
+ const code = error.code;
1692
+ if (code !== "ENOENT" && code !== "ENOTDIR") throw error;
1693
+ const parent = path4.dirname(candidate);
1694
+ if (parent === candidate) return resolved;
1695
+ missingParts.unshift(path4.basename(candidate));
1696
+ candidate = parent;
1697
+ }
1698
+ }
1699
+ }
1700
+
1589
1701
  // src/config/paths.ts
1590
- var OPENCODE_PROJECT_CONFIG_RELATIVE_PATH = path4.join(".opencode", "codebase-index.json");
1591
- var OPENCODE_PROJECT_INDEX_RELATIVE_PATH = path4.join(".opencode", "index");
1702
+ var OPENCODE_PROJECT_CONFIG_RELATIVE_PATH = path5.join(".opencode", "codebase-index.json");
1703
+ var OPENCODE_PROJECT_INDEX_RELATIVE_PATH = path5.join(".opencode", "index");
1592
1704
  var CODEBASE_INDEX_DIR = ".codebase-index";
1593
- var CODEBASE_PROJECT_CONFIG_RELATIVE_PATH = path4.join(CODEBASE_INDEX_DIR, "config.json");
1594
- var CODEBASE_PROJECT_INDEX_RELATIVE_PATH = path4.join(CODEBASE_INDEX_DIR, "index");
1705
+ var CODEBASE_PROJECT_CONFIG_RELATIVE_PATH = path5.join(CODEBASE_INDEX_DIR, "config.json");
1706
+ var CODEBASE_PROJECT_INDEX_RELATIVE_PATH = path5.join(CODEBASE_INDEX_DIR, "index");
1595
1707
  var CLAUDE_DIR = ".claude";
1596
- var CLAUDE_PROJECT_CONFIG_RELATIVE_PATH = path4.join(CLAUDE_DIR, "codebase-index.json");
1597
- var CLAUDE_PROJECT_INDEX_RELATIVE_PATH = path4.join(CLAUDE_DIR, "index");
1708
+ var CLAUDE_PROJECT_CONFIG_RELATIVE_PATH = path5.join(CLAUDE_DIR, "codebase-index.json");
1709
+ var CLAUDE_PROJECT_INDEX_RELATIVE_PATH = path5.join(CLAUDE_DIR, "index");
1598
1710
  function getProjectConfigRelativePath(host) {
1599
1711
  switch (host) {
1600
1712
  case "opencode":
@@ -1620,42 +1732,71 @@ function resolveWorktreeFallbackPath(projectRoot3, relativePath) {
1620
1732
  if (!mainRepoRoot) {
1621
1733
  return null;
1622
1734
  }
1623
- const fallbackPath = path4.join(mainRepoRoot, relativePath);
1735
+ const fallbackPath = path5.join(mainRepoRoot, relativePath);
1624
1736
  return (0, import_fs4.existsSync)(fallbackPath) ? fallbackPath : null;
1625
1737
  }
1626
1738
  function getHostProjectConfigRelativePath(host) {
1627
1739
  return getProjectConfigRelativePath(host);
1628
1740
  }
1629
- function getHostProjectIndexRelativePath(host) {
1630
- return getProjectIndexRelativePath(host);
1741
+ function getProjectConfigCandidatePaths(projectRoot3, host) {
1742
+ const candidates = [path5.join(projectRoot3, getProjectConfigRelativePath(host))];
1743
+ if (host !== "opencode") {
1744
+ candidates.push(path5.join(projectRoot3, OPENCODE_PROJECT_CONFIG_RELATIVE_PATH));
1745
+ }
1746
+ const mainRepoRoot = resolveWorktreeMainRepoRoot(projectRoot3);
1747
+ if (mainRepoRoot) {
1748
+ candidates.push(path5.join(mainRepoRoot, getProjectConfigRelativePath(host)));
1749
+ if (host !== "opencode") {
1750
+ candidates.push(path5.join(mainRepoRoot, OPENCODE_PROJECT_CONFIG_RELATIVE_PATH));
1751
+ }
1752
+ }
1753
+ return [...new Set(candidates)];
1754
+ }
1755
+ function isProjectIndexPathOwnedByProject(projectRoot3, indexPath, host) {
1756
+ const projectRoots = [projectRoot3];
1757
+ const mainRepoRoot = resolveWorktreeMainRepoRoot(projectRoot3);
1758
+ if (mainRepoRoot) {
1759
+ projectRoots.push(mainRepoRoot);
1760
+ }
1761
+ const ownedIndexPaths = projectRoots.flatMap((root) => {
1762
+ const indexPaths = [path5.join(root, getProjectIndexRelativePath(host))];
1763
+ if (host !== "opencode") {
1764
+ indexPaths.push(path5.join(root, OPENCODE_PROJECT_INDEX_RELATIVE_PATH));
1765
+ }
1766
+ return indexPaths;
1767
+ });
1768
+ const canonicalIndexPath = canonicalizePathForComparison(indexPath);
1769
+ return ownedIndexPaths.some(
1770
+ (ownedPath) => canonicalizePathForComparison(ownedPath) === canonicalIndexPath
1771
+ );
1631
1772
  }
1632
1773
  function hasHostProjectConfig(projectRoot3, host) {
1633
- return (0, import_fs4.existsSync)(path4.join(projectRoot3, getProjectConfigRelativePath(host)));
1774
+ return (0, import_fs4.existsSync)(path5.join(projectRoot3, getProjectConfigRelativePath(host)));
1634
1775
  }
1635
1776
  function hasHostGlobalConfig(host) {
1636
1777
  return (0, import_fs4.existsSync)(getGlobalConfigPath(host));
1637
1778
  }
1638
- function getGlobalIndexPath(host = "opencode") {
1779
+ function getGlobalIndexPath(host) {
1639
1780
  switch (host) {
1640
1781
  case "opencode":
1641
- return path4.join(os2.homedir(), ".opencode", "global-index");
1782
+ return path5.join(os2.homedir(), ".opencode", "global-index");
1642
1783
  case "claude":
1643
- return path4.join(os2.homedir(), ".claude", "global-index");
1784
+ return path5.join(os2.homedir(), ".claude", "global-index");
1644
1785
  default:
1645
- return path4.join(os2.homedir(), ".codebase-index", "global-index");
1786
+ return path5.join(os2.homedir(), ".codebase-index", "global-index");
1646
1787
  }
1647
1788
  }
1648
- function getGlobalConfigPath(host = "opencode") {
1789
+ function getGlobalConfigPath(host) {
1649
1790
  switch (host) {
1650
1791
  case "opencode":
1651
- return path4.join(os2.homedir(), ".config", "opencode", "codebase-index.json");
1792
+ return path5.join(os2.homedir(), ".config", "opencode", "codebase-index.json");
1652
1793
  case "claude":
1653
- return path4.join(os2.homedir(), ".claude", "codebase-index.json");
1794
+ return path5.join(os2.homedir(), ".claude", "codebase-index.json");
1654
1795
  default:
1655
- return path4.join(os2.homedir(), ".config", "codebase-index", "config.json");
1796
+ return path5.join(os2.homedir(), ".config", "codebase-index", "config.json");
1656
1797
  }
1657
1798
  }
1658
- function resolveGlobalConfigPath(host = "opencode") {
1799
+ function resolveGlobalConfigPath(host) {
1659
1800
  const hostConfigPath = getGlobalConfigPath(host);
1660
1801
  if ((0, import_fs4.existsSync)(hostConfigPath)) {
1661
1802
  return hostConfigPath;
@@ -1668,7 +1809,7 @@ function resolveGlobalConfigPath(host = "opencode") {
1668
1809
  }
1669
1810
  return hostConfigPath;
1670
1811
  }
1671
- function resolveGlobalIndexPath(host = "opencode") {
1812
+ function resolveGlobalIndexPath(host) {
1672
1813
  const hostIndexPath = getGlobalIndexPath(host);
1673
1814
  if ((0, import_fs4.existsSync)(hostIndexPath)) {
1674
1815
  return hostIndexPath;
@@ -1684,42 +1825,43 @@ function resolveGlobalIndexPath(host = "opencode") {
1684
1825
  }
1685
1826
  return hostIndexPath;
1686
1827
  }
1687
- function resolveProjectConfigPath(projectRoot3, host = "opencode") {
1688
- const hostConfigPath = path4.join(projectRoot3, getProjectConfigRelativePath(host));
1689
- if ((0, import_fs4.existsSync)(hostConfigPath)) {
1690
- return hostConfigPath;
1691
- }
1692
- if (host !== "opencode") {
1693
- const legacyConfigPath = path4.join(projectRoot3, OPENCODE_PROJECT_CONFIG_RELATIVE_PATH);
1694
- if ((0, import_fs4.existsSync)(legacyConfigPath)) {
1695
- return legacyConfigPath;
1696
- }
1697
- }
1698
- const hostFallback = resolveWorktreeFallbackPath(projectRoot3, getProjectConfigRelativePath(host));
1699
- if (hostFallback) {
1700
- return hostFallback;
1701
- }
1702
- if (host !== "opencode") {
1703
- const legacyFallback = resolveWorktreeFallbackPath(projectRoot3, OPENCODE_PROJECT_CONFIG_RELATIVE_PATH);
1704
- if (legacyFallback) {
1705
- return legacyFallback;
1706
- }
1707
- }
1708
- return hostConfigPath;
1828
+ function resolveProjectConfigPath(projectRoot3, host) {
1829
+ const candidates = getProjectConfigCandidatePaths(projectRoot3, host);
1830
+ return candidates.find((candidate) => (0, import_fs4.existsSync)(candidate)) ?? path5.join(projectRoot3, getProjectConfigRelativePath(host));
1709
1831
  }
1710
- function resolveWritableProjectConfigPath(projectRoot3, host = "opencode") {
1711
- return path4.join(projectRoot3, getProjectConfigRelativePath(host));
1832
+ function resolveWritableProjectConfigPath(projectRoot3, host) {
1833
+ return path5.join(projectRoot3, getProjectConfigRelativePath(host));
1712
1834
  }
1713
- function resolveProjectIndexPath(projectRoot3, scope, host = "opencode") {
1835
+ function resolveProjectIndexPath(projectRoot3, scope, host) {
1714
1836
  if (scope === "global") {
1715
1837
  return resolveGlobalIndexPath(host);
1716
1838
  }
1717
- const localIndexPath = path4.join(projectRoot3, getProjectIndexRelativePath(host));
1839
+ const localIndexPath = path5.join(projectRoot3, getProjectIndexRelativePath(host));
1840
+ const mainRepoRoot = resolveWorktreeMainRepoRoot(projectRoot3);
1841
+ if (mainRepoRoot) {
1842
+ if (hasHostProjectConfig(projectRoot3, host)) {
1843
+ return localIndexPath;
1844
+ }
1845
+ if (host !== "opencode") {
1846
+ const localLegacyConfigPath = path5.join(projectRoot3, OPENCODE_PROJECT_CONFIG_RELATIVE_PATH);
1847
+ if ((0, import_fs4.existsSync)(localLegacyConfigPath)) {
1848
+ return path5.join(projectRoot3, OPENCODE_PROJECT_INDEX_RELATIVE_PATH);
1849
+ }
1850
+ const mainHostConfigPath = path5.join(mainRepoRoot, getProjectConfigRelativePath(host));
1851
+ const mainHostIndexPath = path5.join(mainRepoRoot, getProjectIndexRelativePath(host));
1852
+ const mainLegacyConfigPath = path5.join(mainRepoRoot, OPENCODE_PROJECT_CONFIG_RELATIVE_PATH);
1853
+ const mainLegacyIndexPath = path5.join(mainRepoRoot, OPENCODE_PROJECT_INDEX_RELATIVE_PATH);
1854
+ if (!(0, import_fs4.existsSync)(mainHostConfigPath) && !(0, import_fs4.existsSync)(mainHostIndexPath) && ((0, import_fs4.existsSync)(mainLegacyConfigPath) || (0, import_fs4.existsSync)(mainLegacyIndexPath))) {
1855
+ return mainLegacyIndexPath;
1856
+ }
1857
+ }
1858
+ return path5.join(mainRepoRoot, getProjectIndexRelativePath(host));
1859
+ }
1718
1860
  if ((0, import_fs4.existsSync)(localIndexPath)) {
1719
1861
  return localIndexPath;
1720
1862
  }
1721
1863
  if (host !== "opencode") {
1722
- const legacyIndexPath = path4.join(projectRoot3, OPENCODE_PROJECT_INDEX_RELATIVE_PATH);
1864
+ const legacyIndexPath = path5.join(projectRoot3, OPENCODE_PROJECT_INDEX_RELATIVE_PATH);
1723
1865
  if ((0, import_fs4.existsSync)(legacyIndexPath) && !hasHostProjectConfig(projectRoot3, host)) {
1724
1866
  return legacyIndexPath;
1725
1867
  }
@@ -1727,9 +1869,6 @@ function resolveProjectIndexPath(projectRoot3, scope, host = "opencode") {
1727
1869
  if (hasHostProjectConfig(projectRoot3, host)) {
1728
1870
  return localIndexPath;
1729
1871
  }
1730
- if (resolveWorktreeMainRepoRoot(projectRoot3)) {
1731
- return localIndexPath;
1732
- }
1733
1872
  const hostFallback = resolveWorktreeFallbackPath(projectRoot3, getProjectIndexRelativePath(host));
1734
1873
  if (hostFallback) {
1735
1874
  return hostFallback;
@@ -1744,10 +1883,10 @@ function resolveProjectIndexPath(projectRoot3, scope, host = "opencode") {
1744
1883
  }
1745
1884
 
1746
1885
  // src/tools/knowledge-base-paths.ts
1747
- var path6 = __toESM(require("path"), 1);
1886
+ var path7 = __toESM(require("path"), 1);
1748
1887
 
1749
1888
  // src/utils/paths.ts
1750
- var path5 = __toESM(require("path"), 1);
1889
+ var path6 = __toESM(require("path"), 1);
1751
1890
  function normalizePathSeparators(value) {
1752
1891
  return value.replace(/\\/g, "/");
1753
1892
  }
@@ -1764,37 +1903,37 @@ function resolveConfigPathValue(value, baseDir) {
1764
1903
  if (!trimmed) {
1765
1904
  return trimmed;
1766
1905
  }
1767
- const absolutePath = path6.isAbsolute(trimmed) ? trimmed : path6.resolve(baseDir, trimmed);
1768
- return path6.normalize(absolutePath);
1906
+ const absolutePath = path7.isAbsolute(trimmed) ? trimmed : path7.resolve(baseDir, trimmed);
1907
+ return path7.normalize(absolutePath);
1769
1908
  }
1770
1909
  function serializeConfigPathValue(value, baseDir) {
1771
1910
  const trimmed = value.trim();
1772
1911
  if (!trimmed) {
1773
1912
  return trimmed;
1774
1913
  }
1775
- if (!path6.isAbsolute(trimmed)) {
1776
- return normalizePathSeparators(path6.normalize(trimmed));
1914
+ if (!path7.isAbsolute(trimmed)) {
1915
+ return normalizePathSeparators(path7.normalize(trimmed));
1777
1916
  }
1778
- const relativePath = path6.relative(baseDir, trimmed);
1779
- if (!relativePath || !relativePath.startsWith("..") && !path6.isAbsolute(relativePath)) {
1780
- return normalizePathSeparators(path6.normalize(relativePath || "."));
1917
+ const relativePath = path7.relative(baseDir, trimmed);
1918
+ if (!relativePath || !relativePath.startsWith("..") && !path7.isAbsolute(relativePath)) {
1919
+ return normalizePathSeparators(path7.normalize(relativePath || "."));
1781
1920
  }
1782
- return path6.normalize(trimmed);
1921
+ return path7.normalize(trimmed);
1783
1922
  }
1784
1923
  function resolveKnowledgeBasePath(value, projectRoot3) {
1785
- return path6.isAbsolute(value) ? value : path6.resolve(projectRoot3, value);
1924
+ return path7.isAbsolute(value) ? value : path7.resolve(projectRoot3, value);
1786
1925
  }
1787
1926
  function normalizeKnowledgeBasePath(value, projectRoot3) {
1788
- return path6.normalize(resolveKnowledgeBasePath(value, projectRoot3));
1927
+ return path7.normalize(resolveKnowledgeBasePath(value, projectRoot3));
1789
1928
  }
1790
1929
  function hasMatchingKnowledgeBasePath(knowledgeBases, inputPath, projectRoot3) {
1791
- const normalizedInput = path6.normalize(inputPath);
1930
+ const normalizedInput = path7.normalize(inputPath);
1792
1931
  return knowledgeBases.some((kb) => normalizeKnowledgeBasePath(kb, projectRoot3) === normalizedInput);
1793
1932
  }
1794
1933
  function findKnowledgeBasePathIndex(knowledgeBases, inputPath, projectRoot3) {
1795
- const normalizedInput = path6.normalize(inputPath);
1934
+ const normalizedInput = path7.normalize(inputPath);
1796
1935
  return knowledgeBases.findIndex(
1797
- (kb) => path6.normalize(kb) === normalizedInput || normalizeKnowledgeBasePath(kb, projectRoot3) === normalizedInput
1936
+ (kb) => path7.normalize(kb) === normalizedInput || normalizeKnowledgeBasePath(kb, projectRoot3) === normalizedInput
1798
1937
  );
1799
1938
  }
1800
1939
 
@@ -3077,13 +3216,13 @@ function formatEffectivenessMetrics(snapshot) {
3077
3216
  // src/utils/auto-index.ts
3078
3217
  var import_fs7 = require("fs");
3079
3218
  var os4 = __toESM(require("os"), 1);
3080
- var path9 = __toESM(require("path"), 1);
3219
+ var path10 = __toESM(require("path"), 1);
3081
3220
 
3082
3221
  // src/indexer/index-lock.ts
3083
3222
  var import_crypto = require("crypto");
3084
3223
  var import_fs5 = require("fs");
3085
3224
  var os3 = __toESM(require("os"), 1);
3086
- var path7 = __toESM(require("path"), 1);
3225
+ var path8 = __toESM(require("path"), 1);
3087
3226
  var OWNER_FILE_NAME = "owner.json";
3088
3227
  var RECLAIM_DIRECTORY_NAME = "reclaiming";
3089
3228
  var RECOVERY_MARKER_PREFIX = "indexing.lock.recovery.";
@@ -3140,7 +3279,7 @@ function parseReclaimOwner(value) {
3140
3279
  }
3141
3280
  function readJsonDirectory(directoryPath, parser) {
3142
3281
  try {
3143
- return parser(JSON.parse((0, import_fs5.readFileSync)(path7.join(directoryPath, OWNER_FILE_NAME), "utf-8")));
3282
+ return parser(JSON.parse((0, import_fs5.readFileSync)(path8.join(directoryPath, OWNER_FILE_NAME), "utf-8")));
3144
3283
  } catch {
3145
3284
  return null;
3146
3285
  }
@@ -3197,7 +3336,7 @@ function publishJsonDirectory(finalPath, value) {
3197
3336
  throw error;
3198
3337
  }
3199
3338
  try {
3200
- (0, import_fs5.writeFileSync)(path7.join(candidatePath, OWNER_FILE_NAME), JSON.stringify(value), {
3339
+ (0, import_fs5.writeFileSync)(path8.join(candidatePath, OWNER_FILE_NAME), JSON.stringify(value), {
3201
3340
  encoding: "utf-8",
3202
3341
  flag: "wx",
3203
3342
  mode: 384
@@ -3228,7 +3367,7 @@ function createOwner(operation) {
3228
3367
  };
3229
3368
  }
3230
3369
  function recoveryMarkerPath(indexPath, owner) {
3231
- return path7.join(indexPath, `${RECOVERY_MARKER_PREFIX}${owner.token}`);
3370
+ return path8.join(indexPath, `${RECOVERY_MARKER_PREFIX}${owner.token}`);
3232
3371
  }
3233
3372
  function publishRecoveryMarker(indexPath, owner) {
3234
3373
  const markerPath = recoveryMarkerPath(indexPath, owner);
@@ -3247,7 +3386,7 @@ function getPendingRecoveries(indexPath) {
3247
3386
  return UUID_PATTERN.test(name.slice(RECOVERY_MARKER_PREFIX.length));
3248
3387
  }).sort();
3249
3388
  for (const markerName of markerNames) {
3250
- const markerPath = path7.join(indexPath, markerName);
3389
+ const markerPath = path8.join(indexPath, markerName);
3251
3390
  const markerToken = markerName.slice(RECOVERY_MARKER_PREFIX.length);
3252
3391
  let markerStats;
3253
3392
  try {
@@ -3279,11 +3418,11 @@ function cleanupDeadPublicationCandidates(indexPath) {
3279
3418
  const pid = Number(match[1]);
3280
3419
  if (!Number.isInteger(pid) || pid <= 0) continue;
3281
3420
  if (getOwnerLiveness({ pid, hostname: os3.hostname() }) !== "dead") continue;
3282
- (0, import_fs5.rmSync)(path7.join(indexPath, entry), { recursive: true, force: true });
3421
+ (0, import_fs5.rmSync)(path8.join(indexPath, entry), { recursive: true, force: true });
3283
3422
  }
3284
3423
  }
3285
3424
  function removeDeadReclaimMarker(lockPath, expectedOwner) {
3286
- const markerPath = path7.join(lockPath, RECLAIM_DIRECTORY_NAME);
3425
+ const markerPath = path8.join(lockPath, RECLAIM_DIRECTORY_NAME);
3287
3426
  const marker = readReclaimOwner(markerPath);
3288
3427
  if (!marker || marker.expectedOwnerToken !== expectedOwner.token || getOwnerLiveness(marker) !== "dead") {
3289
3428
  return false;
@@ -3311,7 +3450,7 @@ function removeDeadReclaimMarker(lockPath, expectedOwner) {
3311
3450
  return true;
3312
3451
  }
3313
3452
  function reclaimDeadOwner(indexPath, lockPath, expectedOwner) {
3314
- const reclaimPath = path7.join(lockPath, RECLAIM_DIRECTORY_NAME);
3453
+ const reclaimPath = path8.join(lockPath, RECLAIM_DIRECTORY_NAME);
3315
3454
  const reclaimOwner = {
3316
3455
  pid: process.pid,
3317
3456
  hostname: os3.hostname(),
@@ -3369,7 +3508,7 @@ function isTransientIndexLockContention(error) {
3369
3508
  function acquireIndexLock(indexPath, operation) {
3370
3509
  (0, import_fs5.mkdirSync)(indexPath, { recursive: true });
3371
3510
  const canonicalIndexPath = import_fs5.realpathSync.native(indexPath);
3372
- const lockPath = path7.join(canonicalIndexPath, "indexing.lock");
3511
+ const lockPath = path8.join(canonicalIndexPath, "indexing.lock");
3373
3512
  cleanupDeadPublicationCandidates(canonicalIndexPath);
3374
3513
  for (let attempt = 0; attempt < 6; attempt += 1) {
3375
3514
  const owner = createOwner(operation);
@@ -3455,7 +3594,7 @@ function recoverLeaseArtifacts(indexPath, owner, backupTargets) {
3455
3594
  const temporaryOwnerMarker = `.tmp.${owner.pid}.${owner.token}.`;
3456
3595
  for (const entry of (0, import_fs5.readdirSync)(indexPath)) {
3457
3596
  if (!entry.includes(temporaryOwnerMarker)) continue;
3458
- (0, import_fs5.rmSync)(path7.join(indexPath, entry), { recursive: true, force: true });
3597
+ (0, import_fs5.rmSync)(path8.join(indexPath, entry), { recursive: true, force: true });
3459
3598
  }
3460
3599
  }
3461
3600
  function completeLeaseRecovery(lease) {
@@ -3473,7 +3612,7 @@ function completeLeaseRecovery(lease) {
3473
3612
  // src/utils/files.ts
3474
3613
  var import_ignore = __toESM(require_ignore(), 1);
3475
3614
  var import_fs6 = require("fs");
3476
- var path8 = __toESM(require("path"), 1);
3615
+ var path9 = __toESM(require("path"), 1);
3477
3616
  var PROJECT_MARKERS = [
3478
3617
  ".git",
3479
3618
  "package.json",
@@ -3491,7 +3630,7 @@ var PROJECT_MARKERS = [
3491
3630
  ];
3492
3631
  function hasProjectMarker(projectRoot3) {
3493
3632
  for (const marker of PROJECT_MARKERS) {
3494
- if ((0, import_fs6.existsSync)(path8.join(projectRoot3, marker))) {
3633
+ if ((0, import_fs6.existsSync)(path9.join(projectRoot3, marker))) {
3495
3634
  return true;
3496
3635
  }
3497
3636
  }
@@ -3518,7 +3657,7 @@ function createIgnoreFilter(projectRoot3) {
3518
3657
  "**/*build*/**"
3519
3658
  ];
3520
3659
  ig.add(defaultIgnores);
3521
- const gitignorePath = path8.join(projectRoot3, ".gitignore");
3660
+ const gitignorePath = path9.join(projectRoot3, ".gitignore");
3522
3661
  if ((0, import_fs6.existsSync)(gitignorePath)) {
3523
3662
  const gitignoreContent = (0, import_fs6.readFileSync)(gitignorePath, "utf-8");
3524
3663
  ig.add(gitignoreContent);
@@ -3545,8 +3684,8 @@ async function* walkDirectory(dir, projectRoot3, includePatterns, excludePattern
3545
3684
  const filesInDir = [];
3546
3685
  const subdirs = [];
3547
3686
  for (const entry of entries) {
3548
- const fullPath = path8.join(dir, entry.name);
3549
- const relativePath = path8.relative(projectRoot3, fullPath);
3687
+ const fullPath = path9.join(dir, entry.name);
3688
+ const relativePath = path9.relative(projectRoot3, fullPath);
3550
3689
  if (isHiddenPathSegment(entry.name)) {
3551
3690
  if (entry.isDirectory()) {
3552
3691
  skipped.push({ path: relativePath, reason: "excluded" });
@@ -3595,7 +3734,7 @@ async function* walkDirectory(dir, projectRoot3, includePatterns, excludePattern
3595
3734
  yield f;
3596
3735
  }
3597
3736
  for (let i = options.maxFilesPerDirectory; i < filesInDir.length; i++) {
3598
- skipped.push({ path: path8.relative(projectRoot3, filesInDir[i].path), reason: "excluded" });
3737
+ skipped.push({ path: path9.relative(projectRoot3, filesInDir[i].path), reason: "excluded" });
3599
3738
  }
3600
3739
  const canRecurse = options.maxDepth === -1 || currentDepth < options.maxDepth;
3601
3740
  if (canRecurse) {
@@ -3635,8 +3774,8 @@ async function collectFiles(projectRoot3, includePatterns, excludePatterns, maxF
3635
3774
  if (additionalRoots && additionalRoots.length > 0) {
3636
3775
  const normalizedRoots = /* @__PURE__ */ new Set();
3637
3776
  for (const kbRoot of additionalRoots) {
3638
- const resolved = path8.normalize(
3639
- path8.isAbsolute(kbRoot) ? kbRoot : path8.resolve(projectRoot3, kbRoot)
3777
+ const resolved = path9.normalize(
3778
+ path9.isAbsolute(kbRoot) ? kbRoot : path9.resolve(projectRoot3, kbRoot)
3640
3779
  );
3641
3780
  normalizedRoots.add(resolved);
3642
3781
  }
@@ -3780,7 +3919,7 @@ function now() {
3780
3919
  return (/* @__PURE__ */ new Date()).toISOString();
3781
3920
  }
3782
3921
  function canonicalizePath(targetPath) {
3783
- const resolved = path9.resolve(targetPath);
3922
+ const resolved = path10.resolve(targetPath);
3784
3923
  if ((0, import_fs7.existsSync)(resolved)) {
3785
3924
  try {
3786
3925
  return import_fs7.realpathSync.native(resolved);
@@ -3788,9 +3927,9 @@ function canonicalizePath(targetPath) {
3788
3927
  return resolved;
3789
3928
  }
3790
3929
  }
3791
- const parent = path9.dirname(resolved);
3930
+ const parent = path10.dirname(resolved);
3792
3931
  if (parent === resolved) return resolved;
3793
- return path9.join(canonicalizePath(parent), path9.basename(resolved));
3932
+ return path10.join(canonicalizePath(parent), path10.basename(resolved));
3794
3933
  }
3795
3934
  function isHomeDirectory(projectRoot3) {
3796
3935
  return canonicalizePath(projectRoot3) === canonicalizePath(os4.homedir());
@@ -4317,14 +4456,14 @@ function runCoordinatedIndex(projectRoot3, host, force, onProgress) {
4317
4456
  source: "manual"
4318
4457
  }) ?? null;
4319
4458
  }
4320
- function getAutoIndexStatus(projectRoot3, host = "opencode") {
4459
+ function getAutoIndexStatus(projectRoot3, host) {
4321
4460
  return getCoordinator(projectRoot3, host)?.snapshot() ?? {
4322
4461
  enabled: false,
4323
4462
  state: "idle",
4324
4463
  updatedAt: now()
4325
4464
  };
4326
4465
  }
4327
- async function waitForAutoIndexForRetrieval(projectRoot3, host = "opencode") {
4466
+ async function waitForAutoIndexForRetrieval(projectRoot3, host) {
4328
4467
  const coordinator = getCoordinator(projectRoot3, host);
4329
4468
  if (!coordinator) return { ready: true };
4330
4469
  const initial = coordinator.snapshot();
@@ -4371,7 +4510,7 @@ async function waitForAutoIndexForRetrieval(projectRoot3, host = "opencode") {
4371
4510
  text: `Automatic indexing is ${status.state}. Retry shortly or call index_status for progress. You can also run index_codebase explicitly.`
4372
4511
  };
4373
4512
  }
4374
- async function stopAutoIndex(projectRoot3, host = "opencode") {
4513
+ async function stopAutoIndex(projectRoot3, host) {
4375
4514
  await getCoordinator(projectRoot3, host)?.stop();
4376
4515
  }
4377
4516
  async function hasReadableCurrentIndex(coordinator) {
@@ -4385,17 +4524,17 @@ async function hasReadableCurrentIndex(coordinator) {
4385
4524
 
4386
4525
  // src/tools/config-state.ts
4387
4526
  var import_fs9 = require("fs");
4388
- var path12 = __toESM(require("path"), 1);
4527
+ var path13 = __toESM(require("path"), 1);
4389
4528
 
4390
4529
  // src/config/merger.ts
4391
4530
  var import_fs8 = require("fs");
4392
- var path11 = __toESM(require("path"), 1);
4531
+ var path12 = __toESM(require("path"), 1);
4393
4532
 
4394
4533
  // src/config/rebase.ts
4395
- var path10 = __toESM(require("path"), 1);
4534
+ var path11 = __toESM(require("path"), 1);
4396
4535
  function isWithinRoot(rootDir, targetPath) {
4397
- const relativePath = path10.relative(rootDir, targetPath);
4398
- return relativePath === "" || !relativePath.startsWith("..") && !path10.isAbsolute(relativePath);
4536
+ const relativePath = path11.relative(rootDir, targetPath);
4537
+ return relativePath === "" || !relativePath.startsWith("..") && !path11.isAbsolute(relativePath);
4399
4538
  }
4400
4539
  function resolveInheritedKnowledgeBaseEntries(values, sourceRoot, targetRoot) {
4401
4540
  if (!Array.isArray(values)) {
@@ -4406,17 +4545,17 @@ function resolveInheritedKnowledgeBaseEntries(values, sourceRoot, targetRoot) {
4406
4545
  if (!trimmed) {
4407
4546
  return trimmed;
4408
4547
  }
4409
- if (path10.isAbsolute(trimmed)) {
4548
+ if (path11.isAbsolute(trimmed)) {
4410
4549
  if (isWithinRoot(sourceRoot, trimmed)) {
4411
- return normalizePathSeparators(path10.normalize(path10.relative(sourceRoot, trimmed) || "."));
4550
+ return normalizePathSeparators(path11.normalize(path11.relative(sourceRoot, trimmed) || "."));
4412
4551
  }
4413
- return path10.normalize(trimmed);
4552
+ return path11.normalize(trimmed);
4414
4553
  }
4415
- const resolvedFromSource = path10.resolve(sourceRoot, trimmed);
4554
+ const resolvedFromSource = path11.resolve(sourceRoot, trimmed);
4416
4555
  if (isWithinRoot(sourceRoot, resolvedFromSource)) {
4417
- return normalizePathSeparators(path10.normalize(trimmed));
4556
+ return normalizePathSeparators(path11.normalize(trimmed));
4418
4557
  }
4419
- return normalizePathSeparators(path10.normalize(path10.relative(targetRoot, resolvedFromSource)));
4558
+ return normalizePathSeparators(path11.normalize(path11.relative(targetRoot, resolvedFromSource)));
4420
4559
  }).filter(Boolean);
4421
4560
  }
4422
4561
 
@@ -4454,8 +4593,8 @@ function mergeUniqueStringArray(values) {
4454
4593
  return [...new Set(values.map((value) => String(value).trim()))];
4455
4594
  }
4456
4595
  function normalizeKnowledgeBasePath2(value) {
4457
- let normalized = path11.normalize(String(value).trim());
4458
- const root = path11.parse(normalized).root;
4596
+ let normalized = path12.normalize(String(value).trim());
4597
+ const root = path12.parse(normalized).root;
4459
4598
  while (normalized.length > root.length && /[\\/]$/.test(normalized)) {
4460
4599
  normalized = normalized.slice(0, -1);
4461
4600
  }
@@ -4503,14 +4642,14 @@ function loadJsonFile(filePath) {
4503
4642
  throw new Error(`Failed to load config file ${filePath}: ${message}`);
4504
4643
  }
4505
4644
  }
4506
- function loadProjectConfigLayer(projectRoot3, host = "opencode") {
4645
+ function loadProjectConfigLayer(projectRoot3, host) {
4507
4646
  const projectConfigPath = resolveProjectConfigPath(projectRoot3, host);
4508
4647
  const projectConfig = loadJsonFile(projectConfigPath);
4509
4648
  if (!projectConfig) {
4510
4649
  return {};
4511
4650
  }
4512
4651
  const normalizedConfig = { ...projectConfig };
4513
- const projectConfigBaseDir = path11.dirname(path11.dirname(projectConfigPath));
4652
+ const projectConfigBaseDir = path12.dirname(path12.dirname(projectConfigPath));
4514
4653
  if (Array.isArray(normalizedConfig.knowledgeBases)) {
4515
4654
  normalizedConfig.knowledgeBases = resolveInheritedKnowledgeBaseEntries(
4516
4655
  normalizedConfig.knowledgeBases,
@@ -4520,7 +4659,7 @@ function loadProjectConfigLayer(projectRoot3, host = "opencode") {
4520
4659
  }
4521
4660
  return normalizedConfig;
4522
4661
  }
4523
- function loadMergedConfig(projectRoot3, host = "opencode") {
4662
+ function loadMergedConfig(projectRoot3, host) {
4524
4663
  const globalConfigPath = resolveGlobalConfigPath(host);
4525
4664
  const projectConfigPath = resolveProjectConfigPath(projectRoot3, host);
4526
4665
  let globalConfig = null;
@@ -4589,19 +4728,19 @@ function toConfigRecord(rawConfig) {
4589
4728
  }
4590
4729
  return { ...rawConfig };
4591
4730
  }
4592
- function getConfigPath(projectRoot3, host = "opencode") {
4731
+ function getConfigPath(projectRoot3, host) {
4593
4732
  return resolveWritableProjectConfigPath(projectRoot3, host);
4594
4733
  }
4595
- function loadRuntimeConfig(projectRoot3, host = "opencode") {
4734
+ function loadRuntimeConfig(projectRoot3, host) {
4596
4735
  return normalizeKnowledgeBasePaths(toConfigRecord(loadMergedConfig(projectRoot3, host)), projectRoot3);
4597
4736
  }
4598
- function loadEditableConfig(projectRoot3, host = "opencode") {
4737
+ function loadEditableConfig(projectRoot3, host) {
4599
4738
  return normalizeKnowledgeBasePaths(toConfigRecord(loadProjectConfigLayer(projectRoot3, host)), projectRoot3);
4600
4739
  }
4601
- function saveConfig(projectRoot3, config, host = "opencode") {
4740
+ function saveConfig(projectRoot3, config, host) {
4602
4741
  const configPath = getConfigPath(projectRoot3, host);
4603
- const configDir = path12.dirname(configPath);
4604
- const configBaseDir = path12.dirname(configDir);
4742
+ const configDir = path13.dirname(configPath);
4743
+ const configBaseDir = path13.dirname(configDir);
4605
4744
  if (!(0, import_fs9.existsSync)(configDir)) {
4606
4745
  (0, import_fs9.mkdirSync)(configDir, { recursive: true });
4607
4746
  }
@@ -6753,43 +6892,81 @@ function extractParamNames(params) {
6753
6892
 
6754
6893
  // src/native/binding.ts
6755
6894
  var os5 = __toESM(require("os"), 1);
6756
- var path13 = __toESM(require("path"), 1);
6895
+ var path14 = __toESM(require("path"), 1);
6757
6896
  var module2 = __toESM(require("module"), 1);
6758
6897
  var import_node_url = require("url");
6898
+
6899
+ // src/identity-catalog.json
6900
+ var identity_catalog_default = {
6901
+ product: {
6902
+ current: {
6903
+ productName: "opencode-codebase-index",
6904
+ packageName: "opencode-codebase-index",
6905
+ repository: "https://github.com/Helweg/opencode-codebase-index",
6906
+ mcpBinary: "opencode-codebase-index-mcp",
6907
+ mcpServerName: "opencode-codebase-index"
6908
+ },
6909
+ future: {
6910
+ productName: "open-codebase-index",
6911
+ packageName: "open-codebase-index",
6912
+ repository: "https://github.com/Helweg/open-codebase-index",
6913
+ mcpBinary: "open-codebase-index-mcp",
6914
+ mcpServerName: "open-codebase-index"
6915
+ }
6916
+ },
6917
+ native: {
6918
+ binaryName: "codebase-index-native"
6919
+ }
6920
+ };
6921
+
6922
+ // src/identity-catalog.ts
6923
+ var IDENTITY_CATALOG = identity_catalog_default;
6924
+ var CURRENT_PRODUCT = IDENTITY_CATALOG.product.current;
6925
+ var FUTURE_PRODUCT = IDENTITY_CATALOG.product.future;
6926
+ var MCP_SERVER_CURRENT_NAME = CURRENT_PRODUCT.mcpServerName;
6927
+ var MCP_BINARY_CURRENT_NAME = CURRENT_PRODUCT.mcpBinary;
6928
+ var STABLE_NATIVE_BINARY_NAME = IDENTITY_CATALOG.native.binaryName;
6929
+
6930
+ // src/native/binding.ts
6759
6931
  var import_meta = {};
6760
- function getNativeBinding() {
6761
- const platform2 = os5.platform();
6762
- const arch2 = os5.arch();
6763
- let bindingName;
6932
+ function getNativeBindingFilename(platform2 = os5.platform(), arch2 = os5.arch()) {
6764
6933
  if (platform2 === "darwin" && arch2 === "arm64") {
6765
- bindingName = "codebase-index-native.darwin-arm64.node";
6766
- } else if (platform2 === "darwin" && arch2 === "x64") {
6767
- bindingName = "codebase-index-native.darwin-x64.node";
6768
- } else if (platform2 === "linux" && arch2 === "x64") {
6769
- bindingName = "codebase-index-native.linux-x64-gnu.node";
6770
- } else if (platform2 === "linux" && arch2 === "arm64") {
6771
- bindingName = "codebase-index-native.linux-arm64-gnu.node";
6772
- } else if (platform2 === "win32" && arch2 === "x64") {
6773
- bindingName = "codebase-index-native.win32-x64-msvc.node";
6774
- } else {
6775
- throw new Error(`Unsupported platform: ${platform2}-${arch2}`);
6934
+ return `${STABLE_NATIVE_BINARY_NAME}.darwin-arm64.node`;
6776
6935
  }
6936
+ if (platform2 === "darwin" && arch2 === "x64") {
6937
+ return `${STABLE_NATIVE_BINARY_NAME}.darwin-x64.node`;
6938
+ }
6939
+ if (platform2 === "linux" && arch2 === "x64") {
6940
+ return `${STABLE_NATIVE_BINARY_NAME}.linux-x64-gnu.node`;
6941
+ }
6942
+ if (platform2 === "linux" && arch2 === "arm64") {
6943
+ return `${STABLE_NATIVE_BINARY_NAME}.linux-arm64-gnu.node`;
6944
+ }
6945
+ if (platform2 === "win32" && arch2 === "x64") {
6946
+ return `${STABLE_NATIVE_BINARY_NAME}.win32-x64-msvc.node`;
6947
+ }
6948
+ throw new Error(`Unsupported platform: ${platform2}-${arch2}`);
6949
+ }
6950
+ function resolveNativeBindingPath(packageRoot, platform2 = os5.platform(), arch2 = os5.arch()) {
6951
+ return path14.join(packageRoot, "native", getNativeBindingFilename(platform2, arch2));
6952
+ }
6953
+ function getNativeBinding() {
6777
6954
  let currentDir;
6778
6955
  let requireTarget;
6779
6956
  if (typeof import_meta !== "undefined" && import_meta.url) {
6780
- currentDir = path13.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
6957
+ currentDir = path14.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
6781
6958
  requireTarget = import_meta.url;
6782
6959
  } else if (typeof __dirname !== "undefined") {
6783
6960
  currentDir = __dirname;
6784
6961
  requireTarget = __filename;
6785
6962
  } else {
6786
6963
  currentDir = process.cwd();
6787
- requireTarget = path13.join(currentDir, "index.js");
6964
+ requireTarget = path14.join(currentDir, "index.js");
6788
6965
  }
6789
6966
  const normalizedDir = currentDir.replace(/\\/g, "/");
6790
- const isDevMode = normalizedDir.includes("/src/native") || currentDir.includes(path13.join("src", "native"));
6791
- const packageRoot = isDevMode ? path13.resolve(currentDir, "../..") : path13.resolve(currentDir, "..");
6792
- const nativePath = path13.join(packageRoot, "native", bindingName);
6967
+ const isDevMode = normalizedDir.includes("/src/native") || currentDir.includes(path14.join("src", "native"));
6968
+ const packageRoot = isDevMode ? path14.resolve(currentDir, "../..") : path14.resolve(currentDir, "..");
6969
+ const nativePath = resolveNativeBindingPath(packageRoot);
6793
6970
  const require2 = module2.createRequire(requireTarget);
6794
6971
  return require2(nativePath);
6795
6972
  }
@@ -7349,116 +7526,6 @@ var import_fs10 = require("fs");
7349
7526
  var os6 = __toESM(require("os"), 1);
7350
7527
  var path15 = __toESM(require("path"), 1);
7351
7528
 
7352
- // src/utils/canonical-path.ts
7353
- var crypto = __toESM(require("crypto"), 1);
7354
- var fs = __toESM(require("fs"), 1);
7355
- var path14 = __toESM(require("path"), 1);
7356
-
7357
- // node_modules/unicode-case-folding/index.js
7358
- var FOLDING_MAP = /* @__PURE__ */ new Map([[65, [97]], [66, [98]], [67, [99]], [68, [100]], [69, [101]], [70, [102]], [71, [103]], [72, [104]], [73, [105]], [74, [106]], [75, [107]], [76, [108]], [77, [109]], [78, [110]], [79, [111]], [80, [112]], [81, [113]], [82, [114]], [83, [115]], [84, [116]], [85, [117]], [86, [118]], [87, [119]], [88, [120]], [89, [121]], [90, [122]], [181, [956]], [192, [224]], [193, [225]], [194, [226]], [195, [227]], [196, [228]], [197, [229]], [198, [230]], [199, [231]], [200, [232]], [201, [233]], [202, [234]], [203, [235]], [204, [236]], [205, [237]], [206, [238]], [207, [239]], [208, [240]], [209, [241]], [210, [242]], [211, [243]], [212, [244]], [213, [245]], [214, [246]], [216, [248]], [217, [249]], [218, [250]], [219, [251]], [220, [252]], [221, [253]], [222, [254]], [223, [115, 115]], [256, [257]], [258, [259]], [260, [261]], [262, [263]], [264, [265]], [266, [267]], [268, [269]], [270, [271]], [272, [273]], [274, [275]], [276, [277]], [278, [279]], [280, [281]], [282, [283]], [284, [285]], [286, [287]], [288, [289]], [290, [291]], [292, [293]], [294, [295]], [296, [297]], [298, [299]], [300, [301]], [302, [303]], [304, [105, 775]], [306, [307]], [308, [309]], [310, [311]], [313, [314]], [315, [316]], [317, [318]], [319, [320]], [321, [322]], [323, [324]], [325, [326]], [327, [328]], [329, [700, 110]], [330, [331]], [332, [333]], [334, [335]], [336, [337]], [338, [339]], [340, [341]], [342, [343]], [344, [345]], [346, [347]], [348, [349]], [350, [351]], [352, [353]], [354, [355]], [356, [357]], [358, [359]], [360, [361]], [362, [363]], [364, [365]], [366, [367]], [368, [369]], [370, [371]], [372, [373]], [374, [375]], [376, [255]], [377, [378]], [379, [380]], [381, [382]], [383, [115]], [385, [595]], [386, [387]], [388, [389]], [390, [596]], [391, [392]], [393, [598]], [394, [599]], [395, [396]], [398, [477]], [399, [601]], [400, [603]], [401, [402]], [403, [608]], [404, [611]], [406, [617]], [407, [616]], [408, [409]], [412, [623]], [413, [626]], [415, [629]], [416, [417]], [418, [419]], [420, [421]], [422, [640]], [423, [424]], [425, [643]], [428, [429]], [430, [648]], [431, [432]], [433, [650]], [434, [651]], [435, [436]], [437, [438]], [439, [658]], [440, [441]], [444, [445]], [452, [454]], [453, [454]], [455, [457]], [456, [457]], [458, [460]], [459, [460]], [461, [462]], [463, [464]], [465, [466]], [467, [468]], [469, [470]], [471, [472]], [473, [474]], [475, [476]], [478, [479]], [480, [481]], [482, [483]], [484, [485]], [486, [487]], [488, [489]], [490, [491]], [492, [493]], [494, [495]], [496, [106, 780]], [497, [499]], [498, [499]], [500, [501]], [502, [405]], [503, [447]], [504, [505]], [506, [507]], [508, [509]], [510, [511]], [512, [513]], [514, [515]], [516, [517]], [518, [519]], [520, [521]], [522, [523]], [524, [525]], [526, [527]], [528, [529]], [530, [531]], [532, [533]], [534, [535]], [536, [537]], [538, [539]], [540, [541]], [542, [543]], [544, [414]], [546, [547]], [548, [549]], [550, [551]], [552, [553]], [554, [555]], [556, [557]], [558, [559]], [560, [561]], [562, [563]], [570, [11365]], [571, [572]], [573, [410]], [574, [11366]], [577, [578]], [579, [384]], [580, [649]], [581, [652]], [582, [583]], [584, [585]], [586, [587]], [588, [589]], [590, [591]], [837, [953]], [880, [881]], [882, [883]], [886, [887]], [895, [1011]], [902, [940]], [904, [941]], [905, [942]], [906, [943]], [908, [972]], [910, [973]], [911, [974]], [912, [953, 776, 769]], [913, [945]], [914, [946]], [915, [947]], [916, [948]], [917, [949]], [918, [950]], [919, [951]], [920, [952]], [921, [953]], [922, [954]], [923, [955]], [924, [956]], [925, [957]], [926, [958]], [927, [959]], [928, [960]], [929, [961]], [931, [963]], [932, [964]], [933, [965]], [934, [966]], [935, [967]], [936, [968]], [937, [969]], [938, [970]], [939, [971]], [944, [965, 776, 769]], [962, [963]], [975, [983]], [976, [946]], [977, [952]], [981, [966]], [982, [960]], [984, [985]], [986, [987]], [988, [989]], [990, [991]], [992, [993]], [994, [995]], [996, [997]], [998, [999]], [1e3, [1001]], [1002, [1003]], [1004, [1005]], [1006, [1007]], [1008, [954]], [1009, [961]], [1012, [952]], [1013, [949]], [1015, [1016]], [1017, [1010]], [1018, [1019]], [1021, [891]], [1022, [892]], [1023, [893]], [1024, [1104]], [1025, [1105]], [1026, [1106]], [1027, [1107]], [1028, [1108]], [1029, [1109]], [1030, [1110]], [1031, [1111]], [1032, [1112]], [1033, [1113]], [1034, [1114]], [1035, [1115]], [1036, [1116]], [1037, [1117]], [1038, [1118]], [1039, [1119]], [1040, [1072]], [1041, [1073]], [1042, [1074]], [1043, [1075]], [1044, [1076]], [1045, [1077]], [1046, [1078]], [1047, [1079]], [1048, [1080]], [1049, [1081]], [1050, [1082]], [1051, [1083]], [1052, [1084]], [1053, [1085]], [1054, [1086]], [1055, [1087]], [1056, [1088]], [1057, [1089]], [1058, [1090]], [1059, [1091]], [1060, [1092]], [1061, [1093]], [1062, [1094]], [1063, [1095]], [1064, [1096]], [1065, [1097]], [1066, [1098]], [1067, [1099]], [1068, [1100]], [1069, [1101]], [1070, [1102]], [1071, [1103]], [1120, [1121]], [1122, [1123]], [1124, [1125]], [1126, [1127]], [1128, [1129]], [1130, [1131]], [1132, [1133]], [1134, [1135]], [1136, [1137]], [1138, [1139]], [1140, [1141]], [1142, [1143]], [1144, [1145]], [1146, [1147]], [1148, [1149]], [1150, [1151]], [1152, [1153]], [1162, [1163]], [1164, [1165]], [1166, [1167]], [1168, [1169]], [1170, [1171]], [1172, [1173]], [1174, [1175]], [1176, [1177]], [1178, [1179]], [1180, [1181]], [1182, [1183]], [1184, [1185]], [1186, [1187]], [1188, [1189]], [1190, [1191]], [1192, [1193]], [1194, [1195]], [1196, [1197]], [1198, [1199]], [1200, [1201]], [1202, [1203]], [1204, [1205]], [1206, [1207]], [1208, [1209]], [1210, [1211]], [1212, [1213]], [1214, [1215]], [1216, [1231]], [1217, [1218]], [1219, [1220]], [1221, [1222]], [1223, [1224]], [1225, [1226]], [1227, [1228]], [1229, [1230]], [1232, [1233]], [1234, [1235]], [1236, [1237]], [1238, [1239]], [1240, [1241]], [1242, [1243]], [1244, [1245]], [1246, [1247]], [1248, [1249]], [1250, [1251]], [1252, [1253]], [1254, [1255]], [1256, [1257]], [1258, [1259]], [1260, [1261]], [1262, [1263]], [1264, [1265]], [1266, [1267]], [1268, [1269]], [1270, [1271]], [1272, [1273]], [1274, [1275]], [1276, [1277]], [1278, [1279]], [1280, [1281]], [1282, [1283]], [1284, [1285]], [1286, [1287]], [1288, [1289]], [1290, [1291]], [1292, [1293]], [1294, [1295]], [1296, [1297]], [1298, [1299]], [1300, [1301]], [1302, [1303]], [1304, [1305]], [1306, [1307]], [1308, [1309]], [1310, [1311]], [1312, [1313]], [1314, [1315]], [1316, [1317]], [1318, [1319]], [1320, [1321]], [1322, [1323]], [1324, [1325]], [1326, [1327]], [1329, [1377]], [1330, [1378]], [1331, [1379]], [1332, [1380]], [1333, [1381]], [1334, [1382]], [1335, [1383]], [1336, [1384]], [1337, [1385]], [1338, [1386]], [1339, [1387]], [1340, [1388]], [1341, [1389]], [1342, [1390]], [1343, [1391]], [1344, [1392]], [1345, [1393]], [1346, [1394]], [1347, [1395]], [1348, [1396]], [1349, [1397]], [1350, [1398]], [1351, [1399]], [1352, [1400]], [1353, [1401]], [1354, [1402]], [1355, [1403]], [1356, [1404]], [1357, [1405]], [1358, [1406]], [1359, [1407]], [1360, [1408]], [1361, [1409]], [1362, [1410]], [1363, [1411]], [1364, [1412]], [1365, [1413]], [1366, [1414]], [1415, [1381, 1410]], [4256, [11520]], [4257, [11521]], [4258, [11522]], [4259, [11523]], [4260, [11524]], [4261, [11525]], [4262, [11526]], [4263, [11527]], [4264, [11528]], [4265, [11529]], [4266, [11530]], [4267, [11531]], [4268, [11532]], [4269, [11533]], [4270, [11534]], [4271, [11535]], [4272, [11536]], [4273, [11537]], [4274, [11538]], [4275, [11539]], [4276, [11540]], [4277, [11541]], [4278, [11542]], [4279, [11543]], [4280, [11544]], [4281, [11545]], [4282, [11546]], [4283, [11547]], [4284, [11548]], [4285, [11549]], [4286, [11550]], [4287, [11551]], [4288, [11552]], [4289, [11553]], [4290, [11554]], [4291, [11555]], [4292, [11556]], [4293, [11557]], [4295, [11559]], [4301, [11565]], [5112, [5104]], [5113, [5105]], [5114, [5106]], [5115, [5107]], [5116, [5108]], [5117, [5109]], [7296, [1074]], [7297, [1076]], [7298, [1086]], [7299, [1089]], [7300, [1090]], [7301, [1090]], [7302, [1098]], [7303, [1123]], [7304, [42571]], [7305, [7306]], [7312, [4304]], [7313, [4305]], [7314, [4306]], [7315, [4307]], [7316, [4308]], [7317, [4309]], [7318, [4310]], [7319, [4311]], [7320, [4312]], [7321, [4313]], [7322, [4314]], [7323, [4315]], [7324, [4316]], [7325, [4317]], [7326, [4318]], [7327, [4319]], [7328, [4320]], [7329, [4321]], [7330, [4322]], [7331, [4323]], [7332, [4324]], [7333, [4325]], [7334, [4326]], [7335, [4327]], [7336, [4328]], [7337, [4329]], [7338, [4330]], [7339, [4331]], [7340, [4332]], [7341, [4333]], [7342, [4334]], [7343, [4335]], [7344, [4336]], [7345, [4337]], [7346, [4338]], [7347, [4339]], [7348, [4340]], [7349, [4341]], [7350, [4342]], [7351, [4343]], [7352, [4344]], [7353, [4345]], [7354, [4346]], [7357, [4349]], [7358, [4350]], [7359, [4351]], [7680, [7681]], [7682, [7683]], [7684, [7685]], [7686, [7687]], [7688, [7689]], [7690, [7691]], [7692, [7693]], [7694, [7695]], [7696, [7697]], [7698, [7699]], [7700, [7701]], [7702, [7703]], [7704, [7705]], [7706, [7707]], [7708, [7709]], [7710, [7711]], [7712, [7713]], [7714, [7715]], [7716, [7717]], [7718, [7719]], [7720, [7721]], [7722, [7723]], [7724, [7725]], [7726, [7727]], [7728, [7729]], [7730, [7731]], [7732, [7733]], [7734, [7735]], [7736, [7737]], [7738, [7739]], [7740, [7741]], [7742, [7743]], [7744, [7745]], [7746, [7747]], [7748, [7749]], [7750, [7751]], [7752, [7753]], [7754, [7755]], [7756, [7757]], [7758, [7759]], [7760, [7761]], [7762, [7763]], [7764, [7765]], [7766, [7767]], [7768, [7769]], [7770, [7771]], [7772, [7773]], [7774, [7775]], [7776, [7777]], [7778, [7779]], [7780, [7781]], [7782, [7783]], [7784, [7785]], [7786, [7787]], [7788, [7789]], [7790, [7791]], [7792, [7793]], [7794, [7795]], [7796, [7797]], [7798, [7799]], [7800, [7801]], [7802, [7803]], [7804, [7805]], [7806, [7807]], [7808, [7809]], [7810, [7811]], [7812, [7813]], [7814, [7815]], [7816, [7817]], [7818, [7819]], [7820, [7821]], [7822, [7823]], [7824, [7825]], [7826, [7827]], [7828, [7829]], [7830, [104, 817]], [7831, [116, 776]], [7832, [119, 778]], [7833, [121, 778]], [7834, [97, 702]], [7835, [7777]], [7838, [115, 115]], [7840, [7841]], [7842, [7843]], [7844, [7845]], [7846, [7847]], [7848, [7849]], [7850, [7851]], [7852, [7853]], [7854, [7855]], [7856, [7857]], [7858, [7859]], [7860, [7861]], [7862, [7863]], [7864, [7865]], [7866, [7867]], [7868, [7869]], [7870, [7871]], [7872, [7873]], [7874, [7875]], [7876, [7877]], [7878, [7879]], [7880, [7881]], [7882, [7883]], [7884, [7885]], [7886, [7887]], [7888, [7889]], [7890, [7891]], [7892, [7893]], [7894, [7895]], [7896, [7897]], [7898, [7899]], [7900, [7901]], [7902, [7903]], [7904, [7905]], [7906, [7907]], [7908, [7909]], [7910, [7911]], [7912, [7913]], [7914, [7915]], [7916, [7917]], [7918, [7919]], [7920, [7921]], [7922, [7923]], [7924, [7925]], [7926, [7927]], [7928, [7929]], [7930, [7931]], [7932, [7933]], [7934, [7935]], [7944, [7936]], [7945, [7937]], [7946, [7938]], [7947, [7939]], [7948, [7940]], [7949, [7941]], [7950, [7942]], [7951, [7943]], [7960, [7952]], [7961, [7953]], [7962, [7954]], [7963, [7955]], [7964, [7956]], [7965, [7957]], [7976, [7968]], [7977, [7969]], [7978, [7970]], [7979, [7971]], [7980, [7972]], [7981, [7973]], [7982, [7974]], [7983, [7975]], [7992, [7984]], [7993, [7985]], [7994, [7986]], [7995, [7987]], [7996, [7988]], [7997, [7989]], [7998, [7990]], [7999, [7991]], [8008, [8e3]], [8009, [8001]], [8010, [8002]], [8011, [8003]], [8012, [8004]], [8013, [8005]], [8016, [965, 787]], [8018, [965, 787, 768]], [8020, [965, 787, 769]], [8022, [965, 787, 834]], [8025, [8017]], [8027, [8019]], [8029, [8021]], [8031, [8023]], [8040, [8032]], [8041, [8033]], [8042, [8034]], [8043, [8035]], [8044, [8036]], [8045, [8037]], [8046, [8038]], [8047, [8039]], [8064, [7936, 953]], [8065, [7937, 953]], [8066, [7938, 953]], [8067, [7939, 953]], [8068, [7940, 953]], [8069, [7941, 953]], [8070, [7942, 953]], [8071, [7943, 953]], [8072, [7936, 953]], [8073, [7937, 953]], [8074, [7938, 953]], [8075, [7939, 953]], [8076, [7940, 953]], [8077, [7941, 953]], [8078, [7942, 953]], [8079, [7943, 953]], [8080, [7968, 953]], [8081, [7969, 953]], [8082, [7970, 953]], [8083, [7971, 953]], [8084, [7972, 953]], [8085, [7973, 953]], [8086, [7974, 953]], [8087, [7975, 953]], [8088, [7968, 953]], [8089, [7969, 953]], [8090, [7970, 953]], [8091, [7971, 953]], [8092, [7972, 953]], [8093, [7973, 953]], [8094, [7974, 953]], [8095, [7975, 953]], [8096, [8032, 953]], [8097, [8033, 953]], [8098, [8034, 953]], [8099, [8035, 953]], [8100, [8036, 953]], [8101, [8037, 953]], [8102, [8038, 953]], [8103, [8039, 953]], [8104, [8032, 953]], [8105, [8033, 953]], [8106, [8034, 953]], [8107, [8035, 953]], [8108, [8036, 953]], [8109, [8037, 953]], [8110, [8038, 953]], [8111, [8039, 953]], [8114, [8048, 953]], [8115, [945, 953]], [8116, [940, 953]], [8118, [945, 834]], [8119, [945, 834, 953]], [8120, [8112]], [8121, [8113]], [8122, [8048]], [8123, [8049]], [8124, [945, 953]], [8126, [953]], [8130, [8052, 953]], [8131, [951, 953]], [8132, [942, 953]], [8134, [951, 834]], [8135, [951, 834, 953]], [8136, [8050]], [8137, [8051]], [8138, [8052]], [8139, [8053]], [8140, [951, 953]], [8146, [953, 776, 768]], [8147, [953, 776, 769]], [8150, [953, 834]], [8151, [953, 776, 834]], [8152, [8144]], [8153, [8145]], [8154, [8054]], [8155, [8055]], [8162, [965, 776, 768]], [8163, [965, 776, 769]], [8164, [961, 787]], [8166, [965, 834]], [8167, [965, 776, 834]], [8168, [8160]], [8169, [8161]], [8170, [8058]], [8171, [8059]], [8172, [8165]], [8178, [8060, 953]], [8179, [969, 953]], [8180, [974, 953]], [8182, [969, 834]], [8183, [969, 834, 953]], [8184, [8056]], [8185, [8057]], [8186, [8060]], [8187, [8061]], [8188, [969, 953]], [8486, [969]], [8490, [107]], [8491, [229]], [8498, [8526]], [8544, [8560]], [8545, [8561]], [8546, [8562]], [8547, [8563]], [8548, [8564]], [8549, [8565]], [8550, [8566]], [8551, [8567]], [8552, [8568]], [8553, [8569]], [8554, [8570]], [8555, [8571]], [8556, [8572]], [8557, [8573]], [8558, [8574]], [8559, [8575]], [8579, [8580]], [9398, [9424]], [9399, [9425]], [9400, [9426]], [9401, [9427]], [9402, [9428]], [9403, [9429]], [9404, [9430]], [9405, [9431]], [9406, [9432]], [9407, [9433]], [9408, [9434]], [9409, [9435]], [9410, [9436]], [9411, [9437]], [9412, [9438]], [9413, [9439]], [9414, [9440]], [9415, [9441]], [9416, [9442]], [9417, [9443]], [9418, [9444]], [9419, [9445]], [9420, [9446]], [9421, [9447]], [9422, [9448]], [9423, [9449]], [11264, [11312]], [11265, [11313]], [11266, [11314]], [11267, [11315]], [11268, [11316]], [11269, [11317]], [11270, [11318]], [11271, [11319]], [11272, [11320]], [11273, [11321]], [11274, [11322]], [11275, [11323]], [11276, [11324]], [11277, [11325]], [11278, [11326]], [11279, [11327]], [11280, [11328]], [11281, [11329]], [11282, [11330]], [11283, [11331]], [11284, [11332]], [11285, [11333]], [11286, [11334]], [11287, [11335]], [11288, [11336]], [11289, [11337]], [11290, [11338]], [11291, [11339]], [11292, [11340]], [11293, [11341]], [11294, [11342]], [11295, [11343]], [11296, [11344]], [11297, [11345]], [11298, [11346]], [11299, [11347]], [11300, [11348]], [11301, [11349]], [11302, [11350]], [11303, [11351]], [11304, [11352]], [11305, [11353]], [11306, [11354]], [11307, [11355]], [11308, [11356]], [11309, [11357]], [11310, [11358]], [11311, [11359]], [11360, [11361]], [11362, [619]], [11363, [7549]], [11364, [637]], [11367, [11368]], [11369, [11370]], [11371, [11372]], [11373, [593]], [11374, [625]], [11375, [592]], [11376, [594]], [11378, [11379]], [11381, [11382]], [11390, [575]], [11391, [576]], [11392, [11393]], [11394, [11395]], [11396, [11397]], [11398, [11399]], [11400, [11401]], [11402, [11403]], [11404, [11405]], [11406, [11407]], [11408, [11409]], [11410, [11411]], [11412, [11413]], [11414, [11415]], [11416, [11417]], [11418, [11419]], [11420, [11421]], [11422, [11423]], [11424, [11425]], [11426, [11427]], [11428, [11429]], [11430, [11431]], [11432, [11433]], [11434, [11435]], [11436, [11437]], [11438, [11439]], [11440, [11441]], [11442, [11443]], [11444, [11445]], [11446, [11447]], [11448, [11449]], [11450, [11451]], [11452, [11453]], [11454, [11455]], [11456, [11457]], [11458, [11459]], [11460, [11461]], [11462, [11463]], [11464, [11465]], [11466, [11467]], [11468, [11469]], [11470, [11471]], [11472, [11473]], [11474, [11475]], [11476, [11477]], [11478, [11479]], [11480, [11481]], [11482, [11483]], [11484, [11485]], [11486, [11487]], [11488, [11489]], [11490, [11491]], [11499, [11500]], [11501, [11502]], [11506, [11507]], [42560, [42561]], [42562, [42563]], [42564, [42565]], [42566, [42567]], [42568, [42569]], [42570, [42571]], [42572, [42573]], [42574, [42575]], [42576, [42577]], [42578, [42579]], [42580, [42581]], [42582, [42583]], [42584, [42585]], [42586, [42587]], [42588, [42589]], [42590, [42591]], [42592, [42593]], [42594, [42595]], [42596, [42597]], [42598, [42599]], [42600, [42601]], [42602, [42603]], [42604, [42605]], [42624, [42625]], [42626, [42627]], [42628, [42629]], [42630, [42631]], [42632, [42633]], [42634, [42635]], [42636, [42637]], [42638, [42639]], [42640, [42641]], [42642, [42643]], [42644, [42645]], [42646, [42647]], [42648, [42649]], [42650, [42651]], [42786, [42787]], [42788, [42789]], [42790, [42791]], [42792, [42793]], [42794, [42795]], [42796, [42797]], [42798, [42799]], [42802, [42803]], [42804, [42805]], [42806, [42807]], [42808, [42809]], [42810, [42811]], [42812, [42813]], [42814, [42815]], [42816, [42817]], [42818, [42819]], [42820, [42821]], [42822, [42823]], [42824, [42825]], [42826, [42827]], [42828, [42829]], [42830, [42831]], [42832, [42833]], [42834, [42835]], [42836, [42837]], [42838, [42839]], [42840, [42841]], [42842, [42843]], [42844, [42845]], [42846, [42847]], [42848, [42849]], [42850, [42851]], [42852, [42853]], [42854, [42855]], [42856, [42857]], [42858, [42859]], [42860, [42861]], [42862, [42863]], [42873, [42874]], [42875, [42876]], [42877, [7545]], [42878, [42879]], [42880, [42881]], [42882, [42883]], [42884, [42885]], [42886, [42887]], [42891, [42892]], [42893, [613]], [42896, [42897]], [42898, [42899]], [42902, [42903]], [42904, [42905]], [42906, [42907]], [42908, [42909]], [42910, [42911]], [42912, [42913]], [42914, [42915]], [42916, [42917]], [42918, [42919]], [42920, [42921]], [42922, [614]], [42923, [604]], [42924, [609]], [42925, [620]], [42926, [618]], [42928, [670]], [42929, [647]], [42930, [669]], [42931, [43859]], [42932, [42933]], [42934, [42935]], [42936, [42937]], [42938, [42939]], [42940, [42941]], [42942, [42943]], [42944, [42945]], [42946, [42947]], [42948, [42900]], [42949, [642]], [42950, [7566]], [42951, [42952]], [42953, [42954]], [42955, [612]], [42956, [42957]], [42958, [42959]], [42960, [42961]], [42962, [42963]], [42964, [42965]], [42966, [42967]], [42968, [42969]], [42970, [42971]], [42972, [411]], [42997, [42998]], [43888, [5024]], [43889, [5025]], [43890, [5026]], [43891, [5027]], [43892, [5028]], [43893, [5029]], [43894, [5030]], [43895, [5031]], [43896, [5032]], [43897, [5033]], [43898, [5034]], [43899, [5035]], [43900, [5036]], [43901, [5037]], [43902, [5038]], [43903, [5039]], [43904, [5040]], [43905, [5041]], [43906, [5042]], [43907, [5043]], [43908, [5044]], [43909, [5045]], [43910, [5046]], [43911, [5047]], [43912, [5048]], [43913, [5049]], [43914, [5050]], [43915, [5051]], [43916, [5052]], [43917, [5053]], [43918, [5054]], [43919, [5055]], [43920, [5056]], [43921, [5057]], [43922, [5058]], [43923, [5059]], [43924, [5060]], [43925, [5061]], [43926, [5062]], [43927, [5063]], [43928, [5064]], [43929, [5065]], [43930, [5066]], [43931, [5067]], [43932, [5068]], [43933, [5069]], [43934, [5070]], [43935, [5071]], [43936, [5072]], [43937, [5073]], [43938, [5074]], [43939, [5075]], [43940, [5076]], [43941, [5077]], [43942, [5078]], [43943, [5079]], [43944, [5080]], [43945, [5081]], [43946, [5082]], [43947, [5083]], [43948, [5084]], [43949, [5085]], [43950, [5086]], [43951, [5087]], [43952, [5088]], [43953, [5089]], [43954, [5090]], [43955, [5091]], [43956, [5092]], [43957, [5093]], [43958, [5094]], [43959, [5095]], [43960, [5096]], [43961, [5097]], [43962, [5098]], [43963, [5099]], [43964, [5100]], [43965, [5101]], [43966, [5102]], [43967, [5103]], [64256, [102, 102]], [64257, [102, 105]], [64258, [102, 108]], [64259, [102, 102, 105]], [64260, [102, 102, 108]], [64261, [115, 116]], [64262, [115, 116]], [64275, [1396, 1398]], [64276, [1396, 1381]], [64277, [1396, 1387]], [64278, [1406, 1398]], [64279, [1396, 1389]], [65313, [65345]], [65314, [65346]], [65315, [65347]], [65316, [65348]], [65317, [65349]], [65318, [65350]], [65319, [65351]], [65320, [65352]], [65321, [65353]], [65322, [65354]], [65323, [65355]], [65324, [65356]], [65325, [65357]], [65326, [65358]], [65327, [65359]], [65328, [65360]], [65329, [65361]], [65330, [65362]], [65331, [65363]], [65332, [65364]], [65333, [65365]], [65334, [65366]], [65335, [65367]], [65336, [65368]], [65337, [65369]], [65338, [65370]], [66560, [66600]], [66561, [66601]], [66562, [66602]], [66563, [66603]], [66564, [66604]], [66565, [66605]], [66566, [66606]], [66567, [66607]], [66568, [66608]], [66569, [66609]], [66570, [66610]], [66571, [66611]], [66572, [66612]], [66573, [66613]], [66574, [66614]], [66575, [66615]], [66576, [66616]], [66577, [66617]], [66578, [66618]], [66579, [66619]], [66580, [66620]], [66581, [66621]], [66582, [66622]], [66583, [66623]], [66584, [66624]], [66585, [66625]], [66586, [66626]], [66587, [66627]], [66588, [66628]], [66589, [66629]], [66590, [66630]], [66591, [66631]], [66592, [66632]], [66593, [66633]], [66594, [66634]], [66595, [66635]], [66596, [66636]], [66597, [66637]], [66598, [66638]], [66599, [66639]], [66736, [66776]], [66737, [66777]], [66738, [66778]], [66739, [66779]], [66740, [66780]], [66741, [66781]], [66742, [66782]], [66743, [66783]], [66744, [66784]], [66745, [66785]], [66746, [66786]], [66747, [66787]], [66748, [66788]], [66749, [66789]], [66750, [66790]], [66751, [66791]], [66752, [66792]], [66753, [66793]], [66754, [66794]], [66755, [66795]], [66756, [66796]], [66757, [66797]], [66758, [66798]], [66759, [66799]], [66760, [66800]], [66761, [66801]], [66762, [66802]], [66763, [66803]], [66764, [66804]], [66765, [66805]], [66766, [66806]], [66767, [66807]], [66768, [66808]], [66769, [66809]], [66770, [66810]], [66771, [66811]], [66928, [66967]], [66929, [66968]], [66930, [66969]], [66931, [66970]], [66932, [66971]], [66933, [66972]], [66934, [66973]], [66935, [66974]], [66936, [66975]], [66937, [66976]], [66938, [66977]], [66940, [66979]], [66941, [66980]], [66942, [66981]], [66943, [66982]], [66944, [66983]], [66945, [66984]], [66946, [66985]], [66947, [66986]], [66948, [66987]], [66949, [66988]], [66950, [66989]], [66951, [66990]], [66952, [66991]], [66953, [66992]], [66954, [66993]], [66956, [66995]], [66957, [66996]], [66958, [66997]], [66959, [66998]], [66960, [66999]], [66961, [67e3]], [66962, [67001]], [66964, [67003]], [66965, [67004]], [68736, [68800]], [68737, [68801]], [68738, [68802]], [68739, [68803]], [68740, [68804]], [68741, [68805]], [68742, [68806]], [68743, [68807]], [68744, [68808]], [68745, [68809]], [68746, [68810]], [68747, [68811]], [68748, [68812]], [68749, [68813]], [68750, [68814]], [68751, [68815]], [68752, [68816]], [68753, [68817]], [68754, [68818]], [68755, [68819]], [68756, [68820]], [68757, [68821]], [68758, [68822]], [68759, [68823]], [68760, [68824]], [68761, [68825]], [68762, [68826]], [68763, [68827]], [68764, [68828]], [68765, [68829]], [68766, [68830]], [68767, [68831]], [68768, [68832]], [68769, [68833]], [68770, [68834]], [68771, [68835]], [68772, [68836]], [68773, [68837]], [68774, [68838]], [68775, [68839]], [68776, [68840]], [68777, [68841]], [68778, [68842]], [68779, [68843]], [68780, [68844]], [68781, [68845]], [68782, [68846]], [68783, [68847]], [68784, [68848]], [68785, [68849]], [68786, [68850]], [68944, [68976]], [68945, [68977]], [68946, [68978]], [68947, [68979]], [68948, [68980]], [68949, [68981]], [68950, [68982]], [68951, [68983]], [68952, [68984]], [68953, [68985]], [68954, [68986]], [68955, [68987]], [68956, [68988]], [68957, [68989]], [68958, [68990]], [68959, [68991]], [68960, [68992]], [68961, [68993]], [68962, [68994]], [68963, [68995]], [68964, [68996]], [68965, [68997]], [71840, [71872]], [71841, [71873]], [71842, [71874]], [71843, [71875]], [71844, [71876]], [71845, [71877]], [71846, [71878]], [71847, [71879]], [71848, [71880]], [71849, [71881]], [71850, [71882]], [71851, [71883]], [71852, [71884]], [71853, [71885]], [71854, [71886]], [71855, [71887]], [71856, [71888]], [71857, [71889]], [71858, [71890]], [71859, [71891]], [71860, [71892]], [71861, [71893]], [71862, [71894]], [71863, [71895]], [71864, [71896]], [71865, [71897]], [71866, [71898]], [71867, [71899]], [71868, [71900]], [71869, [71901]], [71870, [71902]], [71871, [71903]], [93760, [93792]], [93761, [93793]], [93762, [93794]], [93763, [93795]], [93764, [93796]], [93765, [93797]], [93766, [93798]], [93767, [93799]], [93768, [93800]], [93769, [93801]], [93770, [93802]], [93771, [93803]], [93772, [93804]], [93773, [93805]], [93774, [93806]], [93775, [93807]], [93776, [93808]], [93777, [93809]], [93778, [93810]], [93779, [93811]], [93780, [93812]], [93781, [93813]], [93782, [93814]], [93783, [93815]], [93784, [93816]], [93785, [93817]], [93786, [93818]], [93787, [93819]], [93788, [93820]], [93789, [93821]], [93790, [93822]], [93791, [93823]], [93856, [93883]], [93857, [93884]], [93858, [93885]], [93859, [93886]], [93860, [93887]], [93861, [93888]], [93862, [93889]], [93863, [93890]], [93864, [93891]], [93865, [93892]], [93866, [93893]], [93867, [93894]], [93868, [93895]], [93869, [93896]], [93870, [93897]], [93871, [93898]], [93872, [93899]], [93873, [93900]], [93874, [93901]], [93875, [93902]], [93876, [93903]], [93877, [93904]], [93878, [93905]], [93879, [93906]], [93880, [93907]], [125184, [125218]], [125185, [125219]], [125186, [125220]], [125187, [125221]], [125188, [125222]], [125189, [125223]], [125190, [125224]], [125191, [125225]], [125192, [125226]], [125193, [125227]], [125194, [125228]], [125195, [125229]], [125196, [125230]], [125197, [125231]], [125198, [125232]], [125199, [125233]], [125200, [125234]], [125201, [125235]], [125202, [125236]], [125203, [125237]], [125204, [125238]], [125205, [125239]], [125206, [125240]], [125207, [125241]], [125208, [125242]], [125209, [125243]], [125210, [125244]], [125211, [125245]], [125212, [125246]], [125213, [125247]], [125214, [125248]], [125215, [125249]], [125216, [125250]], [125217, [125251]]]);
7359
- function caseFold(input) {
7360
- if (typeof input !== "string") {
7361
- throw new TypeError("Input must be a string");
7362
- }
7363
- let result = [];
7364
- for (const char of input) {
7365
- const codePoint = char.codePointAt(0);
7366
- const mapping = FOLDING_MAP.get(codePoint);
7367
- result.push(mapping ? String.fromCodePoint(...mapping) : char);
7368
- }
7369
- return result.join("");
7370
- }
7371
-
7372
- // src/utils/canonical-path.ts
7373
- function alternateAsciiCase(value) {
7374
- const index = value.search(/[A-Za-z]/);
7375
- if (index === -1) return null;
7376
- const character = value[index];
7377
- const alternate = character === character.toLowerCase() ? character.toUpperCase() : character.toLowerCase();
7378
- return `${value.slice(0, index)}${alternate}${value.slice(index + 1)}`;
7379
- }
7380
- function probeEntryCaseSensitivity(entryPath) {
7381
- const alternateName = alternateAsciiCase(path14.basename(entryPath));
7382
- if (!alternateName) return void 0;
7383
- try {
7384
- const canonicalPath = fs.realpathSync.native(entryPath);
7385
- const alternatePath = fs.realpathSync.native(path14.join(path14.dirname(entryPath), alternateName));
7386
- return canonicalPath === alternatePath;
7387
- } catch (error) {
7388
- const code = error.code;
7389
- if (code === "ENOENT" || code === "ENOTDIR") return false;
7390
- return void 0;
7391
- }
7392
- }
7393
- function probeEmptyWindowsDirectory(existingAncestor) {
7394
- const probePath = path14.join(
7395
- existingAncestor,
7396
- `.codebase-index-case-probe-${crypto.randomBytes(8).toString("hex")}`
7397
- );
7398
- let created = false;
7399
- try {
7400
- const descriptor = fs.openSync(probePath, "wx", 384);
7401
- created = true;
7402
- fs.closeSync(descriptor);
7403
- return probeEntryCaseSensitivity(probePath);
7404
- } catch {
7405
- return void 0;
7406
- } finally {
7407
- if (created) fs.unlinkSync(probePath);
7408
- }
7409
- }
7410
- function detectCaseInsensitiveFileSystem(existingAncestor) {
7411
- try {
7412
- if (fs.statSync(existingAncestor).isDirectory()) {
7413
- const directory = fs.opendirSync(existingAncestor);
7414
- try {
7415
- let entry = directory.readSync();
7416
- while (entry) {
7417
- if (!entry.isSymbolicLink() && alternateAsciiCase(entry.name)) {
7418
- const result = probeEntryCaseSensitivity(path14.join(existingAncestor, entry.name));
7419
- if (result !== void 0) return result;
7420
- }
7421
- entry = directory.readSync();
7422
- }
7423
- } finally {
7424
- directory.closeSync();
7425
- }
7426
- }
7427
- } catch {
7428
- return void 0;
7429
- }
7430
- if (process.platform === "darwin") {
7431
- return probeEntryCaseSensitivity(existingAncestor);
7432
- }
7433
- if (process.platform === "win32") {
7434
- return probeEmptyWindowsDirectory(existingAncestor);
7435
- }
7436
- return void 0;
7437
- }
7438
- function foldMissingPathComponent(component) {
7439
- return caseFold(component);
7440
- }
7441
- function canonicalizePathForComparison(targetPath, options = {}) {
7442
- const resolved = path14.resolve(targetPath);
7443
- const missingParts = [];
7444
- let candidate = resolved;
7445
- while (true) {
7446
- try {
7447
- const existingAncestor = fs.realpathSync.native(candidate);
7448
- const isCaseInsensitive = missingParts.length > 0 ? (options.isCaseInsensitive ?? detectCaseInsensitiveFileSystem)(existingAncestor) : false;
7449
- const suffix = isCaseInsensitive === true ? missingParts.map(foldMissingPathComponent) : missingParts;
7450
- return path14.join(existingAncestor, ...suffix);
7451
- } catch (error) {
7452
- const code = error.code;
7453
- if (code !== "ENOENT" && code !== "ENOTDIR") throw error;
7454
- const parent = path14.dirname(candidate);
7455
- if (parent === candidate) return resolved;
7456
- missingParts.unshift(path14.basename(candidate));
7457
- candidate = parent;
7458
- }
7459
- }
7460
- }
7461
-
7462
7529
  // src/git/branch-resolution.ts
7463
7530
  var import_child_process = require("child_process");
7464
7531
  var import_crypto2 = require("crypto");
@@ -9092,6 +9159,8 @@ function hasBlameMetadata(metadata) {
9092
9159
  return blameFromMetadata(metadata) !== void 0;
9093
9160
  }
9094
9161
  var INDEX_METADATA_VERSION = "1";
9162
+ var PROJECT_PATH_STORAGE_VERSION = "2";
9163
+ var GLOBAL_PATH_STORAGE_VERSION = "1";
9095
9164
  var EMBEDDING_STRATEGY_VERSION = "2";
9096
9165
  var SWIFT_PARSER_VERSION = "1";
9097
9166
  var METAL_PARSER_VERSION = "1";
@@ -9422,18 +9491,20 @@ function selectIndexableChunks(chunks, limit, semanticOnly) {
9422
9491
  const indexableChunks = semanticOnly ? chunks.filter((chunk) => chunk.chunkType !== "other") : chunks;
9423
9492
  return selectChunksWithFileCoverage(indexableChunks, limit);
9424
9493
  }
9425
- function matchesHardSearchFilters(candidate, options) {
9494
+ function matchesHardSearchFilters(candidate, options, projectRoot3) {
9426
9495
  if (options?.fileType) {
9427
9496
  const ext = candidate.metadata.filePath.split(".").pop()?.toLowerCase();
9428
9497
  const requestedExtension = options.fileType.trim().toLowerCase().replace(/^\./, "");
9429
9498
  if (ext !== requestedExtension) return false;
9430
9499
  }
9431
9500
  if (options?.directory) {
9432
- const normalizedPath = candidate.metadata.filePath.replace(/\\/g, "/");
9433
- const normalizedDir = options.directory.trim().replace(/\\/g, "/").replace(/^\.\//, "").replace(/\/$/, "");
9434
- const isAbsoluteDirectory = normalizedDir.startsWith("/");
9435
- const matchesDirectory = isAbsoluteDirectory ? normalizedPath === normalizedDir || normalizedPath.startsWith(`${normalizedDir}/`) : normalizedPath === normalizedDir || normalizedPath.startsWith(`${normalizedDir}/`) || normalizedPath.includes(`/${normalizedDir}/`) || normalizedPath.endsWith(`/${normalizedDir}`);
9436
- if (!matchesDirectory) return false;
9501
+ const candidatePath = canonicalizePathForComparison(
9502
+ path18.resolve(projectRoot3, candidate.metadata.filePath.replace(/\\/g, path18.sep))
9503
+ );
9504
+ const directoryPath = canonicalizePathForComparison(
9505
+ path18.resolve(projectRoot3, options.directory.trim().replace(/\\/g, path18.sep))
9506
+ );
9507
+ if (!isPathWithinRoot2(candidatePath, directoryPath)) return false;
9437
9508
  }
9438
9509
  if (options?.chunkType && candidate.metadata.chunkType !== options.chunkType) {
9439
9510
  return false;
@@ -9455,8 +9526,8 @@ function matchesHardSearchFilters(candidate, options) {
9455
9526
  }
9456
9527
  return true;
9457
9528
  }
9458
- function matchesSearchFilters(candidate, options, minScore) {
9459
- return candidate.score >= minScore && matchesHardSearchFilters(candidate, options);
9529
+ function matchesSearchFilters(candidate, options, minScore, projectRoot3) {
9530
+ return candidate.score >= minScore && matchesHardSearchFilters(candidate, options, projectRoot3);
9460
9531
  }
9461
9532
  function unionCandidates(semanticCandidates, keywordCandidates) {
9462
9533
  const byId = /* @__PURE__ */ new Map();
@@ -9507,7 +9578,7 @@ var Indexer = class _Indexer {
9507
9578
  readerArtifactFingerprint = null;
9508
9579
  writerArtifactFingerprint = null;
9509
9580
  readerArtifactRetryAfter = /* @__PURE__ */ new Map();
9510
- constructor(projectRoot3, config, host = "opencode", runtimeOptions = {}) {
9581
+ constructor(projectRoot3, config, host, runtimeOptions = {}) {
9511
9582
  this.projectRoot = projectRoot3;
9512
9583
  this.projectIdentityHash = hashContent(this.getCanonicalPath(projectRoot3)).slice(0, 16);
9513
9584
  this.materializedProjectRoot = runtimeOptions.materializedProjectRoot ?? projectRoot3;
@@ -9520,37 +9591,90 @@ var Indexer = class _Indexer {
9520
9591
  this.indexPathOverride = runtimeOptions.indexPath;
9521
9592
  this.config = config;
9522
9593
  this.host = host;
9594
+ if (isGitRepo(this.materializedProjectRoot)) {
9595
+ this.currentBranch = this.branchNameOverride ?? getBranchOrDefault(this.materializedProjectRoot);
9596
+ this.baseBranch = getBaseBranch(this.materializedProjectRoot);
9597
+ } else {
9598
+ this.currentBranch = "default";
9599
+ this.baseBranch = "default";
9600
+ }
9523
9601
  this.indexPath = this.getIndexPath();
9524
- this.fileHashCachePath = this.getRuntimeArtifactPath("file-hashes.json");
9525
- this.failedBatchesPath = this.getRuntimeArtifactPath("failed-batches.json");
9602
+ this.refreshRuntimeArtifactPaths();
9526
9603
  this.logger = initializeLogger(config.debug);
9527
9604
  }
9528
9605
  getIndexPath() {
9529
9606
  return this.indexPathOverride ?? resolveProjectIndexPath(this.projectRoot, this.config.scope, this.host);
9530
9607
  }
9531
9608
  toCanonicalFilePath(filePath) {
9609
+ if (!path18.isAbsolute(filePath)) {
9610
+ return this.resolveStoredFilePath(filePath, this.projectRoot);
9611
+ }
9532
9612
  if (path18.resolve(this.materializedProjectRoot) === path18.resolve(this.projectRoot) || !isPathWithinRoot2(filePath, this.materializedProjectRoot)) {
9533
9613
  return filePath;
9534
9614
  }
9535
9615
  return path18.resolve(this.projectRoot, path18.relative(this.materializedProjectRoot, filePath));
9536
9616
  }
9537
- toMaterializedFilePath(filePath) {
9538
- if (path18.resolve(this.materializedProjectRoot) === path18.resolve(this.projectRoot) || !isPathWithinRoot2(filePath, this.projectRoot)) {
9617
+ toStoredFilePath(filePath) {
9618
+ const canonicalFilePath = this.toCanonicalFilePath(filePath);
9619
+ if (this.config.scope !== "project" || !isPathWithinRoot2(canonicalFilePath, this.projectRoot)) {
9620
+ return canonicalFilePath;
9621
+ }
9622
+ return path18.relative(this.projectRoot, canonicalFilePath).split(path18.sep).join("/");
9623
+ }
9624
+ resolveStoredFilePath(filePath, rootPath = this.projectRoot) {
9625
+ if (path18.isAbsolute(filePath)) {
9539
9626
  return filePath;
9540
9627
  }
9541
- return path18.resolve(this.materializedProjectRoot, path18.relative(this.projectRoot, filePath));
9628
+ const resolvedPath = path18.resolve(rootPath, ...filePath.split("/"));
9629
+ if (!isPathWithinRoot2(resolvedPath, rootPath)) {
9630
+ throw new Error(`Stored project path escapes project root: ${JSON.stringify(filePath)}`);
9631
+ }
9632
+ return resolvedPath;
9633
+ }
9634
+ getCanonicalStoredFilePath(filePath) {
9635
+ return this.getCanonicalPath(this.resolveStoredFilePath(filePath));
9636
+ }
9637
+ resolveFilePathRecord(record) {
9638
+ return {
9639
+ ...record,
9640
+ filePath: this.resolveStoredFilePath(record.filePath)
9641
+ };
9642
+ }
9643
+ resolveCallEdgeFilePath(edge) {
9644
+ if (!edge.fromSymbolFilePath) return edge;
9645
+ return {
9646
+ ...edge,
9647
+ fromSymbolFilePath: this.resolveStoredFilePath(edge.fromSymbolFilePath)
9648
+ };
9649
+ }
9650
+ toMaterializedFilePath(filePath) {
9651
+ const storedFilePath = this.toStoredFilePath(filePath);
9652
+ if (path18.isAbsolute(storedFilePath)) {
9653
+ return storedFilePath;
9654
+ }
9655
+ return this.resolveStoredFilePath(storedFilePath, this.materializedProjectRoot);
9542
9656
  }
9543
9657
  getPreparedBranchNamespace() {
9544
9658
  if (!this.branchNameOverride && !this.catalogIdentityOverride) return null;
9545
9659
  return hashContent(this.getBranchCatalogKey()).slice(0, 16);
9546
9660
  }
9661
+ getRuntimeArtifactNamespace() {
9662
+ if (this.config.scope !== "project" || this.getBranchCatalogIdentity() === "default") {
9663
+ return this.getPreparedBranchNamespace();
9664
+ }
9665
+ return hashContent(this.getBranchCatalogKey()).slice(0, 16);
9666
+ }
9547
9667
  getRuntimeArtifactPath(fileName) {
9548
- const namespace = this.getPreparedBranchNamespace();
9668
+ const namespace = this.getRuntimeArtifactNamespace();
9549
9669
  if (!namespace) return path18.join(this.indexPath, fileName);
9550
9670
  const extension = path18.extname(fileName);
9551
9671
  const baseName = fileName.slice(0, fileName.length - extension.length);
9552
9672
  return path18.join(this.indexPath, `${baseName}.${namespace}${extension}`);
9553
9673
  }
9674
+ refreshRuntimeArtifactPaths() {
9675
+ this.fileHashCachePath = this.getRuntimeArtifactPath("file-hashes.json");
9676
+ this.failedBatchesPath = this.getRuntimeArtifactPath("failed-batches.json");
9677
+ }
9554
9678
  getPreparedChunkId(chunkId) {
9555
9679
  const namespace = this.getPreparedBranchNamespace();
9556
9680
  return namespace ? `${chunkId}_${namespace}` : chunkId;
@@ -9576,19 +9700,8 @@ var Indexer = class _Indexer {
9576
9700
  return path18.resolve(targetPath);
9577
9701
  }
9578
9702
  }
9579
- isLocalProjectIndexPath() {
9580
- const localProjectIndexPaths = [path18.join(this.projectRoot, getHostProjectIndexRelativePath(this.host))];
9581
- if (this.host !== "opencode") {
9582
- localProjectIndexPaths.push(path18.join(this.projectRoot, getHostProjectIndexRelativePath("opencode")));
9583
- }
9584
- return localProjectIndexPaths.some((localPath) => {
9585
- if (!(0, import_fs12.existsSync)(localPath) || !(0, import_fs12.existsSync)(this.indexPath)) {
9586
- return path18.resolve(this.indexPath) === path18.resolve(localPath);
9587
- }
9588
- const indexStats = (0, import_fs12.statSync)(this.indexPath);
9589
- const localStats = (0, import_fs12.statSync)(localPath);
9590
- return indexStats.dev === localStats.dev && indexStats.ino === localStats.ino;
9591
- });
9703
+ isProjectOwnedIndexPath() {
9704
+ return isProjectIndexPathOwnedByProject(this.projectRoot, this.indexPath, this.host);
9592
9705
  }
9593
9706
  resetLoadedIndexState(retireDatabase = false) {
9594
9707
  if (this.database) {
@@ -9623,10 +9736,10 @@ var Indexer = class _Indexer {
9623
9736
  this.readerArtifactRetryAfter.clear();
9624
9737
  }
9625
9738
  async withIndexMutationLease(operation, callback) {
9739
+ this.refreshBranchInfo();
9626
9740
  const lease = acquireIndexLock(this.indexPath, operation);
9627
9741
  this.indexPath = lease.canonicalIndexPath;
9628
- this.fileHashCachePath = this.getRuntimeArtifactPath("file-hashes.json");
9629
- this.failedBatchesPath = this.getRuntimeArtifactPath("failed-batches.json");
9742
+ this.refreshRuntimeArtifactPaths();
9630
9743
  this.activeIndexLease = lease;
9631
9744
  let result;
9632
9745
  let callbackError;
@@ -9798,29 +9911,24 @@ var Indexer = class _Indexer {
9798
9911
  getProjectForceReembedMetadataKey() {
9799
9912
  return `index.forceReembed.${this.projectIdentityHash}`;
9800
9913
  }
9801
- getCallGraphResolutionMetadataKey() {
9802
- if (this.config.scope !== "global") {
9803
- return "index.callGraphResolutionVersion";
9804
- }
9805
- return `index.callGraphResolutionVersion.${this.projectIdentityHash}`;
9914
+ getBranchMigrationMetadataKey(prefix, catalogIdentity = this.getBranchCatalogIdentity()) {
9915
+ const branchKey = this.getBranchCatalogKeyFor(catalogIdentity);
9916
+ return `${prefix}.${hashContent(branchKey).slice(0, 24)}`;
9806
9917
  }
9807
- getSwiftParserVersionMetadataKey() {
9808
- const key = "index.parser.swiftVersion";
9809
- if (this.config.scope !== "global") {
9810
- return key;
9811
- }
9812
- return `${key}.${this.projectIdentityHash}`;
9918
+ getCallGraphResolutionMetadataKey(catalogIdentity = this.getBranchCatalogIdentity()) {
9919
+ return this.getBranchMigrationMetadataKey("index.callGraphResolutionVersion", catalogIdentity);
9813
9920
  }
9814
- getMetalParserVersionMetadataKey() {
9815
- const key = "index.parser.metalVersion";
9816
- if (this.config.scope !== "global") {
9817
- return key;
9818
- }
9819
- return `${key}.${this.projectIdentityHash}`;
9921
+ getSwiftParserVersionMetadataKey(catalogIdentity = this.getBranchCatalogIdentity()) {
9922
+ return this.getBranchMigrationMetadataKey("index.parser.swiftVersion", catalogIdentity);
9923
+ }
9924
+ getMetalParserVersionMetadataKey(catalogIdentity = this.getBranchCatalogIdentity()) {
9925
+ return this.getBranchMigrationMetadataKey("index.parser.metalVersion", catalogIdentity);
9820
9926
  }
9821
9927
  getSymbolExtractorVersionMetadataKey(catalogIdentity = this.getBranchCatalogIdentity()) {
9822
- const branchKey = this.getBranchCatalogKeyFor(catalogIdentity);
9823
- return `index.symbolExtractorVersion.${hashContent(branchKey).slice(0, 24)}`;
9928
+ return this.getBranchMigrationMetadataKey("index.symbolExtractorVersion", catalogIdentity);
9929
+ }
9930
+ areBranchMigrationVersionsCurrent(database, catalogIdentity = this.getBranchCatalogIdentity()) {
9931
+ return database.getMetadata(this.getCallGraphResolutionMetadataKey(catalogIdentity)) === CALL_GRAPH_RESOLUTION_VERSION && database.getMetadata(this.getSwiftParserVersionMetadataKey(catalogIdentity)) === SWIFT_PARSER_VERSION && database.getMetadata(this.getMetalParserVersionMetadataKey(catalogIdentity)) === METAL_PARSER_VERSION && database.getMetadata(this.getSymbolExtractorVersionMetadataKey(catalogIdentity)) === SYMBOL_EXTRACTOR_VERSION;
9824
9932
  }
9825
9933
  hasProjectForceReembedPending() {
9826
9934
  return this.config.scope === "global" && this.database?.getMetadata(this.getProjectForceReembedMetadataKey()) === "true";
@@ -9955,13 +10063,14 @@ var Indexer = class _Indexer {
9955
10063
  return Array.from(keys);
9956
10064
  }
9957
10065
  isFileInCurrentScope(filePath, roots) {
9958
- if (roots.some((root) => isPathWithinRoot2(filePath, root))) return true;
9959
- const canonicalFilePath = this.getCanonicalPath(filePath);
10066
+ const canonicalFilePath = this.getCanonicalStoredFilePath(filePath);
9960
10067
  return roots.some((root) => isPathWithinRoot2(canonicalFilePath, root));
9961
10068
  }
9962
10069
  isFileInProjectRoot(filePath) {
9963
- if (isPathWithinRoot2(filePath, this.projectRoot)) return true;
9964
- return isPathWithinRoot2(this.getCanonicalPath(filePath), this.getCanonicalPath(this.projectRoot));
10070
+ return isPathWithinRoot2(
10071
+ this.getCanonicalStoredFilePath(filePath),
10072
+ this.getCanonicalPath(this.projectRoot)
10073
+ );
9965
10074
  }
9966
10075
  clearScopedFileHashCache(roots) {
9967
10076
  for (const filePath of Array.from(this.fileHashCache.keys())) {
@@ -10362,7 +10471,10 @@ var Indexer = class _Indexer {
10362
10471
  const intent = isLikelyImplementationPath2(candidate.metadata.filePath) ? "implementation" : "doc_or_test";
10363
10472
  parts.push(`intent_hint: ${intent}`);
10364
10473
  try {
10365
- const fileContent = await import_fs12.promises.readFile(candidate.metadata.filePath, "utf-8");
10474
+ const fileContent = await import_fs12.promises.readFile(
10475
+ this.toMaterializedFilePath(candidate.metadata.filePath),
10476
+ "utf-8"
10477
+ );
10366
10478
  const lines = fileContent.split("\n");
10367
10479
  const snippetStartLine = Math.max(1, candidate.metadata.startLine);
10368
10480
  const snippetEndLine = Math.min(lines.length, candidate.metadata.endLine);
@@ -10431,7 +10543,7 @@ var Indexer = class _Indexer {
10431
10543
  if (this.config.scope === "global") {
10432
10544
  return "Shared vector index could not be read. Restore or repair the complete fingerprinted shared vector artifacts; automatic reset is disabled for global scope.";
10433
10545
  }
10434
- if (!this.isLocalProjectIndexPath()) {
10546
+ if (!this.isProjectOwnedIndexPath()) {
10435
10547
  return "Vector index could not be read from an inherited project index. Restore or fingerprint it from the checkout that owns the index; do not remove or rebuild it from this worktree.";
10436
10548
  }
10437
10549
  return "Vector index could not be read. Run index_codebase after the active writer finishes to fingerprint a structurally valid legacy pair, or remove this checkout's local index directory and run index_codebase to rebuild it.";
@@ -10440,7 +10552,7 @@ var Indexer = class _Indexer {
10440
10552
  if (this.config.scope === "global") {
10441
10553
  return "Shared keyword index could not be read; semantic search remains available. Restore or repair the shared keyword artifact; automatic reset is disabled for global scope.";
10442
10554
  }
10443
- if (!this.isLocalProjectIndexPath()) {
10555
+ if (!this.isProjectOwnedIndexPath()) {
10444
10556
  return "Keyword index could not be read from an inherited project index; semantic search remains available. Restore or repair it from the checkout that owns the index; do not rebuild it from this worktree.";
10445
10557
  }
10446
10558
  return "Keyword index could not be read; semantic search remains available. Restore a readable published keyword index, or run index_codebase with force=true after the active writer finishes.";
@@ -10449,10 +10561,10 @@ var Indexer = class _Indexer {
10449
10561
  if (this.config.scope === "global") {
10450
10562
  return "Shared index database could not be read. Restore or repair the shared SQLite database; automatic reset is disabled for global scope.";
10451
10563
  }
10452
- if (!this.isLocalProjectIndexPath()) {
10564
+ if (!this.isProjectOwnedIndexPath()) {
10453
10565
  return "Index database could not be read from an inherited project index. Restore or repair it from the checkout that owns the index; do not migrate or rebuild it from this worktree.";
10454
10566
  }
10455
- return "Index database could not be read. Run index_codebase after the active writer finishes to repair or migrate it under the writer lease.";
10567
+ return "Index database could not be read. Run index_codebase with force=true to rebuild a legacy absolute-path schema, or repair the database after the active writer finishes.";
10456
10568
  }
10457
10569
  getReaderFileFingerprint(filePath, identityOnly = false) {
10458
10570
  try {
@@ -10632,7 +10744,7 @@ var Indexer = class _Indexer {
10632
10744
  const readerArtifactFingerprint = mode === "reader" ? this.captureReaderArtifactFingerprint() : null;
10633
10745
  if (mode === "writer") {
10634
10746
  await import_fs12.promises.mkdir(this.indexPath, { recursive: true });
10635
- if (recoveredOwners.length > 0 && this.config.scope === "project" && !this.isLocalProjectIndexPath()) {
10747
+ if (recoveredOwners.length > 0 && this.config.scope === "project" && !this.isProjectOwnedIndexPath()) {
10636
10748
  throw new Error(
10637
10749
  "Interrupted indexing recovery is unsafe while using an inherited worktree index. Run index_codebase with force=true to create a local project index boundary."
10638
10750
  );
@@ -10733,6 +10845,7 @@ var Indexer = class _Indexer {
10733
10845
  this.baseBranch = "default";
10734
10846
  this.logger.branch("debug", "Not a git repository, using default branch");
10735
10847
  }
10848
+ this.refreshRuntimeArtifactPaths();
10736
10849
  if (mode === "writer" && recoveredOwners.length > 0) {
10737
10850
  await this.recoverFromInterruptedIndexingUnlocked(recoveredOwners);
10738
10851
  }
@@ -10888,6 +11001,14 @@ var Indexer = class _Indexer {
10888
11001
  }
10889
11002
  return `Detected a corrupted local SQLite index at ${dbPath} and reset the local index. Run index_codebase to rebuild search data.`;
10890
11003
  }
11004
+ async removeProjectRuntimeStateArtifacts() {
11005
+ if (!(0, import_fs12.existsSync)(this.indexPath)) return;
11006
+ const names = await import_fs12.promises.readdir(this.indexPath);
11007
+ const runtimeStatePattern = /^(?:file-hashes|failed-batches)(?:\.[a-f0-9]{16})?\.json$/;
11008
+ await Promise.all(
11009
+ names.filter((name) => runtimeStatePattern.test(name)).map((name) => import_fs12.promises.rm(path18.join(this.indexPath, name), { force: true }))
11010
+ );
11011
+ }
10891
11012
  async resetLocalIndexArtifacts() {
10892
11013
  this.store = null;
10893
11014
  this.invertedIndex = null;
@@ -10907,11 +11028,10 @@ var Indexer = class _Indexer {
10907
11028
  path18.join(this.indexPath, "vectors"),
10908
11029
  path18.join(this.indexPath, "vectors.usearch"),
10909
11030
  path18.join(this.indexPath, "vectors.meta.json"),
10910
- path18.join(this.indexPath, "inverted-index.json"),
10911
- path18.join(this.indexPath, "file-hashes.json"),
10912
- path18.join(this.indexPath, "failed-batches.json")
11031
+ path18.join(this.indexPath, "inverted-index.json")
10913
11032
  ];
10914
11033
  await Promise.all(resetPaths.map((targetPath) => import_fs12.promises.rm(targetPath, { recursive: true, force: true })));
11034
+ await this.removeProjectRuntimeStateArtifacts();
10915
11035
  await import_fs12.promises.mkdir(this.indexPath, { recursive: true });
10916
11036
  }
10917
11037
  async tryResetCorruptedIndex(stage, error) {
@@ -10961,12 +11081,20 @@ var Indexer = class _Indexer {
10961
11081
  }
10962
11082
  this.database.addChunksToBranchBatch(this.getBranchCatalogKey(), chunkIds);
10963
11083
  }
11084
+ getExpectedPathStorageVersion() {
11085
+ return this.config.scope === "project" ? PROJECT_PATH_STORAGE_VERSION : GLOBAL_PATH_STORAGE_VERSION;
11086
+ }
11087
+ hasStoredIndexData() {
11088
+ const stats = this.database?.getStats();
11089
+ return (this.store?.count() ?? 0) > 0 || (stats?.chunkCount ?? 0) > 0 || (stats?.symbolCount ?? 0) > 0 || this.fileHashCache.size > 0;
11090
+ }
10964
11091
  loadIndexMetadata() {
10965
11092
  if (!this.database) return null;
10966
11093
  const version = this.database.getMetadata("index.version");
10967
11094
  if (!version) return null;
10968
11095
  return {
10969
11096
  indexVersion: version,
11097
+ pathStorageVersion: this.database.getMetadata("index.pathStorageVersion") ?? GLOBAL_PATH_STORAGE_VERSION,
10970
11098
  embeddingProvider: this.database.getMetadata("index.embeddingProvider") ?? "",
10971
11099
  embeddingModel: this.database.getMetadata("index.embeddingModel") ?? "",
10972
11100
  embeddingDimensions: parseInt(this.database.getMetadata("index.embeddingDimensions") ?? "0", 10),
@@ -10981,6 +11109,7 @@ var Indexer = class _Indexer {
10981
11109
  const existingCreatedAt = this.database.getMetadata("index.createdAt");
10982
11110
  const completeProjectEmbeddingStrategyReset = !this.hasProjectForceReembedPending();
10983
11111
  this.database.setMetadata("index.version", INDEX_METADATA_VERSION);
11112
+ this.database.setMetadata("index.pathStorageVersion", this.getExpectedPathStorageVersion());
10984
11113
  this.database.setMetadata("index.embeddingProvider", provider.provider);
10985
11114
  this.database.setMetadata("index.embeddingModel", provider.modelInfo.model);
10986
11115
  this.database.setMetadata("index.embeddingDimensions", provider.modelInfo.dimensions.toString());
@@ -11003,6 +11132,16 @@ var Indexer = class _Indexer {
11003
11132
  }
11004
11133
  validateIndexCompatibility(provider) {
11005
11134
  const storedMetadata = this.loadIndexMetadata();
11135
+ const storedPathStorageVersion = this.database?.getMetadata("index.pathStorageVersion") ?? GLOBAL_PATH_STORAGE_VERSION;
11136
+ const expectedPathStorageVersion = this.getExpectedPathStorageVersion();
11137
+ if (this.hasStoredIndexData() && storedPathStorageVersion !== expectedPathStorageVersion) {
11138
+ return {
11139
+ compatible: false,
11140
+ code: "PATH_STORAGE_MISMATCH" /* PATH_STORAGE_MISMATCH */,
11141
+ reason: `Path storage format mismatch: index uses v${storedPathStorageVersion} checkout-absolute paths, but this project requires portable v${expectedPathStorageVersion} paths. Run index_codebase with force=true to rebuild the shared project index once.`,
11142
+ storedMetadata: storedMetadata ?? void 0
11143
+ };
11144
+ }
11006
11145
  if (!storedMetadata) {
11007
11146
  return { compatible: true };
11008
11147
  }
@@ -11054,6 +11193,7 @@ var Indexer = class _Indexer {
11054
11193
  return this.indexCompatibility;
11055
11194
  }
11056
11195
  async ensureInitialized() {
11196
+ this.refreshBranchInfo();
11057
11197
  let initializedReader = false;
11058
11198
  while (true) {
11059
11199
  if (this.initializationPromise) {
@@ -11161,8 +11301,8 @@ var Indexer = class _Indexer {
11161
11301
  }
11162
11302
  const branchKey = this.getBranchCatalogKey();
11163
11303
  const alreadyIndexed = database.getBranchChunkIds(branchKey).length > 0 && database.getBranchSymbolIds(branchKey).length > 0;
11164
- const symbolsCurrent = database.getMetadata(this.getSymbolExtractorVersionMetadataKey()) === SYMBOL_EXTRACTOR_VERSION;
11165
- if (alreadyIndexed && symbolsCurrent && this.getStoredBranchCommit(database) === normalizedCommit) {
11304
+ const migrationsCurrent = this.areBranchMigrationVersionsCurrent(database);
11305
+ if (alreadyIndexed && migrationsCurrent && this.getStoredBranchCommit(database) === normalizedCommit) {
11166
11306
  return { prepared: false };
11167
11307
  }
11168
11308
  const stats = await this.indexUnlocked(onProgress, [], true);
@@ -11256,21 +11396,21 @@ var Indexer = class _Indexer {
11256
11396
  const currentFileHashes = /* @__PURE__ */ new Map();
11257
11397
  const needsCallGraphResolutionMigration = database.getMetadata(this.getCallGraphResolutionMetadataKey()) !== CALL_GRAPH_RESOLUTION_VERSION;
11258
11398
  for (const f of files) {
11259
- const canonicalPath = this.toCanonicalFilePath(f.path);
11399
+ const storedPath = this.toStoredFilePath(f.path);
11260
11400
  const currentHash = hashFile(f.path);
11261
- currentFileHashes.set(canonicalPath, currentHash);
11262
- const cachedHashMatches = this.fileHashCache.get(canonicalPath) === currentHash;
11263
- const needsCallGraphRefresh = cachedHashMatches && needsCallGraphResolutionMigration && database.getChunksByFile(canonicalPath).some(
11401
+ currentFileHashes.set(storedPath, currentHash);
11402
+ const cachedHashMatches = this.fileHashCache.get(storedPath) === currentHash;
11403
+ const needsCallGraphRefresh = cachedHashMatches && needsCallGraphResolutionMigration && database.getChunksByFile(storedPath).some(
11264
11404
  (chunk) => chunk.language === "php" || chunk.language === "c" || chunk.language === "cpp"
11265
11405
  );
11266
- const requiresSwiftParserUpgrade = reparseCachedSwiftFiles && path18.extname(canonicalPath).toLowerCase() === ".swift";
11267
- const requiresMetalParserUpgrade = reparseCachedMetalFiles && path18.extname(canonicalPath).toLowerCase() === ".metal";
11406
+ const requiresSwiftParserUpgrade = reparseCachedSwiftFiles && path18.extname(storedPath).toLowerCase() === ".swift";
11407
+ const requiresMetalParserUpgrade = reparseCachedMetalFiles && path18.extname(storedPath).toLowerCase() === ".metal";
11268
11408
  if (cachedHashMatches && !needsCallGraphRefresh && !requiresSwiftParserUpgrade && !requiresMetalParserUpgrade && !refreshCachedSymbols) {
11269
- unchangedFilePaths.add(canonicalPath);
11409
+ unchangedFilePaths.add(storedPath);
11270
11410
  this.logger.recordCacheHit();
11271
11411
  } else {
11272
11412
  const content = await import_fs12.promises.readFile(f.path, "utf-8");
11273
- changedFiles.push({ path: canonicalPath, content, hash: currentHash });
11413
+ changedFiles.push({ path: storedPath, content, hash: currentHash });
11274
11414
  this.logger.recordCacheMiss();
11275
11415
  }
11276
11416
  }
@@ -11375,8 +11515,7 @@ var Indexer = class _Indexer {
11375
11515
  for (const parsed of parsedFiles) {
11376
11516
  currentFilePaths.add(parsed.path);
11377
11517
  if (parsed.chunks.length === 0) {
11378
- const relativePath = path18.relative(this.projectRoot, parsed.path);
11379
- stats.parseFailures.push(relativePath);
11518
+ stats.parseFailures.push(path18.isAbsolute(parsed.path) ? path18.relative(this.projectRoot, parsed.path) : parsed.path);
11380
11519
  }
11381
11520
  let chunksToProcess = parsed.chunks;
11382
11521
  if (this.config.indexing.fallbackToTextOnMaxChunks && chunksToProcess.length > this.config.indexing.maxChunksPerFile) {
@@ -12017,6 +12156,43 @@ var Indexer = class _Indexer {
12017
12156
  const union = a.size + b.size - intersection;
12018
12157
  return intersection / union;
12019
12158
  }
12159
+ getBranchPrefilterState(database, branchChunkIds) {
12160
+ const hasInitializedBranchCatalog = branchChunkIds !== null && database.getAllBranches().length > 0;
12161
+ return {
12162
+ hasInitializedBranchCatalog,
12163
+ shouldPrefilterByBranch: branchChunkIds !== null && (this.config.scope === "global" || hasInitializedBranchCatalog)
12164
+ };
12165
+ }
12166
+ searchCandidatesWithBranchPrefilter(initialLimit, totalCount, branchChunkIds, shouldPrefilterByBranch, search, getChunkId) {
12167
+ const normalizedLimit = Math.max(0, Math.floor(initialLimit));
12168
+ if (normalizedLimit === 0) return [];
12169
+ if (!shouldPrefilterByBranch || !branchChunkIds) {
12170
+ return search(normalizedLimit);
12171
+ }
12172
+ const targetCount = Math.min(normalizedLimit, branchChunkIds.size);
12173
+ if (targetCount === 0 || totalCount === 0) return [];
12174
+ let requestedLimit = Math.min(normalizedLimit, totalCount);
12175
+ while (true) {
12176
+ const results = search(requestedLimit);
12177
+ const branchResults = results.filter((candidate) => branchChunkIds.has(getChunkId(candidate)));
12178
+ if (branchResults.length >= targetCount || results.length < requestedLimit || requestedLimit >= totalCount) {
12179
+ return branchResults;
12180
+ }
12181
+ const nextLimit = Math.min(totalCount, Math.max(requestedLimit + 1, requestedLimit * 2));
12182
+ if (nextLimit === requestedLimit) return branchResults;
12183
+ requestedLimit = nextLimit;
12184
+ }
12185
+ }
12186
+ searchSemanticCandidates(store, embedding, initialLimit, branchChunkIds, shouldPrefilterByBranch) {
12187
+ return this.searchCandidatesWithBranchPrefilter(
12188
+ initialLimit,
12189
+ store.count(),
12190
+ branchChunkIds,
12191
+ shouldPrefilterByBranch,
12192
+ (requestedLimit) => store.search(embedding, requestedLimit),
12193
+ (candidate) => candidate.id
12194
+ );
12195
+ }
12020
12196
  async search(query, limit, options) {
12021
12197
  const { store, provider, invertedIndex, database, readIssues, compatibility } = await this.ensureInitialized();
12022
12198
  this.requireReadableComponents(readIssues, "vectors", "database");
@@ -12061,12 +12237,7 @@ var Indexer = class _Indexer {
12061
12237
  });
12062
12238
  }
12063
12239
  const embeddingMs = import_perf_hooks.performance.now() - embeddingStartTime;
12064
- const vectorStartTime = import_perf_hooks.performance.now();
12065
- const semanticResults = embedding ? store.search(embedding, maxResults * 4) : [];
12066
- const vectorMs = import_perf_hooks.performance.now() - vectorStartTime;
12067
- const keywordStartTime = import_perf_hooks.performance.now();
12068
- const keywordResults = await this.keywordSearch(query, maxResults * 4, store, invertedIndex);
12069
- const keywordMs = import_perf_hooks.performance.now() - keywordStartTime;
12240
+ const prefilterStartTime = import_perf_hooks.performance.now();
12070
12241
  let branchChunkIds = null;
12071
12242
  let branchSymbolIds = null;
12072
12243
  if (filterByBranch && (this.config.scope === "global" || this.currentBranch !== "default")) {
@@ -12074,35 +12245,38 @@ var Indexer = class _Indexer {
12074
12245
  branchChunkIds = new Set(branchCatalogKeys.flatMap((branchKey) => database.getBranchChunkIds(branchKey)));
12075
12246
  branchSymbolIds = new Set(branchCatalogKeys.flatMap((branchKey) => database.getBranchSymbolIds(branchKey)));
12076
12247
  }
12077
- const prefilterStartTime = import_perf_hooks.performance.now();
12078
- const shouldPrefilterByBranch = branchChunkIds !== null && (this.config.scope === "global" || branchChunkIds.size > 0);
12079
- const allowBranchPrefilterFallback = this.config.scope !== "global";
12080
- const prefilteredSemantic = shouldPrefilterByBranch && branchChunkIds ? semanticResults.filter((r) => branchChunkIds.has(r.id)) : semanticResults;
12081
- const prefilteredKeyword = shouldPrefilterByBranch && branchChunkIds ? keywordResults.filter((r) => branchChunkIds.has(r.id)) : keywordResults;
12082
- const semanticCandidates = allowBranchPrefilterFallback && shouldPrefilterByBranch && semanticResults.length > 0 && prefilteredSemantic.length === 0 ? semanticResults : prefilteredSemantic;
12083
- const keywordCandidates = allowBranchPrefilterFallback && shouldPrefilterByBranch && keywordResults.length > 0 && prefilteredKeyword.length === 0 ? keywordResults : prefilteredKeyword;
12248
+ const { hasInitializedBranchCatalog, shouldPrefilterByBranch } = this.getBranchPrefilterState(database, branchChunkIds);
12249
+ const prefilterMs = import_perf_hooks.performance.now() - prefilterStartTime;
12250
+ const vectorStartTime = import_perf_hooks.performance.now();
12251
+ const semanticCandidates = embedding ? this.searchSemanticCandidates(
12252
+ store,
12253
+ embedding,
12254
+ maxResults * 4,
12255
+ branchChunkIds,
12256
+ shouldPrefilterByBranch
12257
+ ) : [];
12258
+ const vectorMs = import_perf_hooks.performance.now() - vectorStartTime;
12259
+ const keywordStartTime = import_perf_hooks.performance.now();
12260
+ const keywordCandidates = await this.keywordSearch(
12261
+ query,
12262
+ maxResults * 4,
12263
+ store,
12264
+ invertedIndex,
12265
+ branchChunkIds,
12266
+ shouldPrefilterByBranch
12267
+ );
12268
+ const keywordMs = import_perf_hooks.performance.now() - keywordStartTime;
12084
12269
  const scopedSemanticCandidates = semanticCandidates.filter(
12085
- (candidate) => matchesHardSearchFilters(candidate, options)
12270
+ (candidate) => matchesHardSearchFilters(candidate, options, this.projectRoot)
12086
12271
  );
12087
12272
  const scopedKeywordCandidates = keywordCandidates.filter(
12088
- (candidate) => matchesHardSearchFilters(candidate, options)
12273
+ (candidate) => matchesHardSearchFilters(candidate, options, this.projectRoot)
12089
12274
  );
12090
- const prefilterMs = import_perf_hooks.performance.now() - prefilterStartTime;
12091
- if (this.config.scope !== "global" && branchChunkIds && branchChunkIds.size === 0) {
12275
+ if (this.config.scope !== "global" && branchChunkIds && !hasInitializedBranchCatalog) {
12092
12276
  this.logger.search("warn", "Branch prefilter skipped because branch catalog is empty", {
12093
12277
  branch: this.currentBranch
12094
12278
  });
12095
12279
  }
12096
- if (allowBranchPrefilterFallback && shouldPrefilterByBranch && semanticResults.length > 0 && prefilteredSemantic.length === 0) {
12097
- this.logger.search("warn", "Branch prefilter produced no semantic overlap, using unfiltered semantic candidates", {
12098
- branch: this.currentBranch
12099
- });
12100
- }
12101
- if (allowBranchPrefilterFallback && shouldPrefilterByBranch && keywordResults.length > 0 && prefilteredKeyword.length === 0) {
12102
- this.logger.search("warn", "Branch prefilter produced no keyword overlap, using unfiltered keyword candidates", {
12103
- branch: this.currentBranch
12104
- });
12105
- }
12106
12280
  const fusionStartTime = import_perf_hooks.performance.now();
12107
12281
  const rankingHybridWeight = embedding === void 0 && fusionStrategy === "weighted" ? 1 : effectiveHybridWeight;
12108
12282
  const combined = rankHybridResults(query, scopedSemanticCandidates, scopedKeywordCandidates, {
@@ -12153,12 +12327,14 @@ var Indexer = class _Indexer {
12153
12327
  const primaryLane = mergeTieredResults(prePrimaryLane, symbolLane, maxResults * 4);
12154
12328
  const tiered = mergeTieredResults(primaryLane, rescued, maxResults * 4);
12155
12329
  const hasCodeHints = extractCodeTermHints(query).length > 0 || identifierHints.length > 0;
12156
- const baseFiltered = tiered.filter((r) => matchesSearchFilters(r, options, this.config.search.minScore));
12330
+ const baseFiltered = tiered.filter(
12331
+ (r) => matchesSearchFilters(r, options, this.config.search.minScore, this.projectRoot)
12332
+ );
12157
12333
  const implementationOnly = baseFiltered.filter(
12158
12334
  (r) => isLikelyImplementationPath2(r.metadata.filePath) && isImplementationChunkType(r.metadata.chunkType)
12159
12335
  );
12160
12336
  const filtered = (sourceIntent && hasCodeHints && implementationOnly.length > 0 ? implementationOnly : baseFiltered).slice(0, maxResults);
12161
- const identifierFallback = !options?.definitionIntent && filtered.length === 0 && identifierHints.length > 0 ? buildSymbolDefinitionLane(query, database, branchChunkIds, branchSymbolIds, maxResults, union, true).filter((r) => matchesSearchFilters(r, options, this.config.search.minScore)).slice(0, maxResults) : [];
12337
+ const identifierFallback = !options?.definitionIntent && filtered.length === 0 && identifierHints.length > 0 ? buildSymbolDefinitionLane(query, database, branchChunkIds, branchSymbolIds, maxResults, union, true).filter((r) => matchesSearchFilters(r, options, this.config.search.minScore, this.projectRoot)).slice(0, maxResults) : [];
12162
12338
  const finalResults = filtered.length > 0 ? filtered : identifierFallback;
12163
12339
  const totalSearchMs = import_perf_hooks.performance.now() - searchStartTime;
12164
12340
  this.logger.recordSearch(totalSearchMs, {
@@ -12183,10 +12359,11 @@ var Indexer = class _Indexer {
12183
12359
  let content = "";
12184
12360
  let contextStartLine = r.metadata.startLine;
12185
12361
  let contextEndLine = r.metadata.endLine;
12362
+ const resolvedFilePath = this.resolveStoredFilePath(r.metadata.filePath);
12186
12363
  if (!metadataOnly && this.config.search.includeContext) {
12187
12364
  try {
12188
12365
  const fileContent = await import_fs12.promises.readFile(
12189
- r.metadata.filePath,
12366
+ resolvedFilePath,
12190
12367
  "utf-8"
12191
12368
  );
12192
12369
  const lines = fileContent.split("\n");
@@ -12199,7 +12376,7 @@ var Indexer = class _Indexer {
12199
12376
  }
12200
12377
  }
12201
12378
  return {
12202
- filePath: r.metadata.filePath,
12379
+ filePath: resolvedFilePath,
12203
12380
  startLine: contextStartLine,
12204
12381
  endLine: contextEndLine,
12205
12382
  content,
@@ -12211,8 +12388,18 @@ var Indexer = class _Indexer {
12211
12388
  })
12212
12389
  );
12213
12390
  }
12214
- async keywordSearch(query, limit, store, invertedIndex) {
12215
- const scores = invertedIndex.search(query);
12391
+ async keywordSearch(query, limit, store, invertedIndex, branchChunkIds = null, shouldPrefilterByBranch = false) {
12392
+ const normalizedLimit = Math.max(0, Math.floor(limit));
12393
+ if (normalizedLimit === 0) return [];
12394
+ const scoreEntries = this.searchCandidatesWithBranchPrefilter(
12395
+ normalizedLimit,
12396
+ invertedIndex.getDocumentCount(),
12397
+ branchChunkIds,
12398
+ shouldPrefilterByBranch,
12399
+ (requestedLimit) => Array.from(invertedIndex.search(query, requestedLimit)),
12400
+ ([chunkId]) => chunkId
12401
+ );
12402
+ const scores = new Map(scoreEntries);
12216
12403
  if (scores.size === 0) {
12217
12404
  return [];
12218
12405
  }
@@ -12226,7 +12413,7 @@ var Indexer = class _Indexer {
12226
12413
  }
12227
12414
  }
12228
12415
  results.sort((a, b) => b.score - a.score);
12229
- return results.slice(0, limit);
12416
+ return results.slice(0, normalizedLimit);
12230
12417
  }
12231
12418
  async getStatus() {
12232
12419
  const { store, configuredProviderInfo, database, readIssues, compatibility } = await this.ensureInitialized();
@@ -12293,7 +12480,7 @@ var Indexer = class _Indexer {
12293
12480
  );
12294
12481
  const currentFileHashes = /* @__PURE__ */ new Map();
12295
12482
  for (const file of files) {
12296
- currentFileHashes.set(this.toCanonicalFilePath(file.path), hashFile(file.path));
12483
+ currentFileHashes.set(this.toStoredFilePath(file.path), hashFile(file.path));
12297
12484
  }
12298
12485
  const scopedRoots = this.config.scope === "global" ? this.getScopedRoots() : null;
12299
12486
  const cachedFileHashes = scopedRoots ? new Map(Array.from(this.fileHashCache).filter(([filePath]) => this.isFileInCurrentScope(filePath, scopedRoots))) : this.fileHashCache;
@@ -12305,17 +12492,7 @@ var Indexer = class _Indexer {
12305
12492
  return { readable: true, current: false, reason: "files-changed" };
12306
12493
  }
12307
12494
  }
12308
- const hasSwiftFiles = Array.from(currentFileHashes.keys()).some(
12309
- (filePath) => path18.extname(filePath).toLowerCase() === ".swift"
12310
- );
12311
- const hasMetalFiles = Array.from(currentFileHashes.keys()).some(
12312
- (filePath) => path18.extname(filePath).toLowerCase() === ".metal"
12313
- );
12314
- const hasCallGraphMigrationFiles = Array.from(currentFileHashes.keys()).some((filePath) => {
12315
- const extension = path18.extname(filePath).toLowerCase();
12316
- return extension === ".php" || extension === ".c" || extension === ".cc" || extension === ".cpp" || extension === ".cxx";
12317
- });
12318
- if (hasSwiftFiles && database.getMetadata(this.getSwiftParserVersionMetadataKey()) !== SWIFT_PARSER_VERSION || hasMetalFiles && database.getMetadata(this.getMetalParserVersionMetadataKey()) !== METAL_PARSER_VERSION || database.getMetadata(this.getSymbolExtractorVersionMetadataKey()) !== SYMBOL_EXTRACTOR_VERSION || hasCallGraphMigrationFiles && database.getMetadata(this.getCallGraphResolutionMetadataKey()) !== CALL_GRAPH_RESOLUTION_VERSION) {
12495
+ if (!this.areBranchMigrationVersionsCurrent(database)) {
12319
12496
  return { readable: true, current: false, reason: "migration-required" };
12320
12497
  }
12321
12498
  if (isGitRepo(this.materializedProjectRoot)) {
@@ -12375,6 +12552,7 @@ var Indexer = class _Indexer {
12375
12552
  this.deleteBranchCommitMetadata(database, clearedBranchKeys2);
12376
12553
  this.saveFailedBatches([]);
12377
12554
  database.deleteMetadata("index.version");
12555
+ database.deleteMetadata("index.pathStorageVersion");
12378
12556
  database.deleteMetadata("index.embeddingProvider");
12379
12557
  database.deleteMetadata("index.embeddingModel");
12380
12558
  database.deleteMetadata("index.embeddingDimensions");
@@ -12393,7 +12571,7 @@ var Indexer = class _Indexer {
12393
12571
  this.indexCompatibility = compatibility;
12394
12572
  return;
12395
12573
  }
12396
- if (!this.isLocalProjectIndexPath()) {
12574
+ if (!this.isProjectOwnedIndexPath()) {
12397
12575
  throw new Error(
12398
12576
  "Project-scoped force rebuild is unsafe while using an inherited worktree index. Create a local project config boundary before clearing the index."
12399
12577
  );
@@ -12404,11 +12582,11 @@ var Indexer = class _Indexer {
12404
12582
  invertedIndex.clear();
12405
12583
  this.saveInvertedIndex(invertedIndex);
12406
12584
  this.fileHashCache.clear();
12407
- this.saveFileHashCache();
12585
+ await this.removeProjectRuntimeStateArtifacts();
12408
12586
  database.clearAllIndexedData();
12409
12587
  this.deleteBranchCommitMetadata(database, clearedBranchKeys);
12410
- this.saveFailedBatches([]);
12411
12588
  database.deleteMetadata("index.version");
12589
+ database.deleteMetadata("index.pathStorageVersion");
12412
12590
  database.deleteMetadata("index.embeddingProvider");
12413
12591
  database.deleteMetadata("index.embeddingModel");
12414
12592
  database.deleteMetadata("index.embeddingDimensions");
@@ -12436,32 +12614,46 @@ var Indexer = class _Indexer {
12436
12614
  existing.push(key);
12437
12615
  filePathsToChunkKeys.set(metadata.filePath, existing);
12438
12616
  }
12439
- const removedFilePaths = [];
12440
- const removedChunkKeys = [];
12617
+ const missingStoredFilePaths = [];
12618
+ const missingChunkKeys = [];
12441
12619
  const chunkKeysByRemovedFile = /* @__PURE__ */ new Map();
12442
12620
  for (const [filePath, chunkKeys] of filePathsToChunkKeys) {
12443
- if (!(0, import_fs12.existsSync)(filePath)) {
12621
+ if (!(0, import_fs12.existsSync)(this.toMaterializedFilePath(filePath))) {
12444
12622
  chunkKeysByRemovedFile.set(filePath, chunkKeys);
12445
12623
  for (const key of chunkKeys) {
12446
- removedChunkKeys.push(key);
12624
+ missingChunkKeys.push(key);
12447
12625
  }
12448
- removedFilePaths.push(filePath);
12626
+ missingStoredFilePaths.push(filePath);
12449
12627
  }
12450
12628
  }
12629
+ const branchCatalogKeys = this.getBranchCatalogKeys();
12630
+ for (const branchKey of branchCatalogKeys) {
12631
+ database.deleteBranchChunksForBranch(branchKey, missingChunkKeys);
12632
+ }
12633
+ const referencedChunkKeys = new Set(database.getReferencedChunkIds(missingChunkKeys));
12634
+ const removedChunkKeys = missingChunkKeys.filter((key) => !referencedChunkKeys.has(key));
12451
12635
  if (removedChunkKeys.length > 0) {
12452
12636
  this.rebuildVectorStoreExcludingChunkIds(store, database, removedChunkKeys);
12453
12637
  for (const key of removedChunkKeys) {
12454
12638
  invertedIndex.removeChunk(key);
12455
12639
  }
12640
+ database.deleteChunksByIds(removedChunkKeys);
12456
12641
  }
12457
- for (const filePath of removedFilePaths) {
12458
- const fileChunkKeys = chunkKeysByRemovedFile.get(filePath) ?? [];
12459
- if (fileChunkKeys.length > 0) {
12460
- database.deleteChunksByIds(fileChunkKeys);
12461
- }
12462
- database.deleteCallEdgesByFile(filePath);
12463
- database.deleteSymbolsByFile(filePath);
12464
- }
12642
+ const missingSymbolIds = Array.from(new Set(
12643
+ missingStoredFilePaths.flatMap(
12644
+ (filePath) => database.getSymbolsByFile(filePath).map((symbol) => symbol.id)
12645
+ )
12646
+ ));
12647
+ for (const branchKey of branchCatalogKeys) {
12648
+ database.deleteBranchSymbolsForBranch(branchKey, missingSymbolIds);
12649
+ }
12650
+ const referencedSymbolIds = new Set(database.getReferencedSymbolIds(missingSymbolIds));
12651
+ const removedSymbolIds = missingSymbolIds.filter((symbolId) => !referencedSymbolIds.has(symbolId));
12652
+ database.clearCallEdgeTargetsForSymbols(removedSymbolIds);
12653
+ const removedChunkKeySet = new Set(removedChunkKeys);
12654
+ const removedStoredFilePaths = missingStoredFilePaths.filter(
12655
+ (filePath) => (chunkKeysByRemovedFile.get(filePath) ?? []).some((key) => removedChunkKeySet.has(key))
12656
+ );
12465
12657
  const removedCount = removedChunkKeys.length;
12466
12658
  if (removedCount > 0) {
12467
12659
  store.save();
@@ -12497,9 +12689,16 @@ var Indexer = class _Indexer {
12497
12689
  removedStale: removedCount,
12498
12690
  orphanEmbeddings: gcOrphanEmbeddings,
12499
12691
  orphanChunks: gcOrphanChunks,
12500
- removedFiles: removedFilePaths.length
12692
+ removedFiles: removedStoredFilePaths.length
12501
12693
  });
12502
- return { removed: removedCount, filePaths: removedFilePaths, gcOrphanEmbeddings, gcOrphanChunks, gcOrphanSymbols, gcOrphanCallEdges };
12694
+ return {
12695
+ removed: removedCount,
12696
+ filePaths: removedStoredFilePaths.map((filePath) => this.resolveStoredFilePath(filePath)),
12697
+ gcOrphanEmbeddings,
12698
+ gcOrphanChunks,
12699
+ gcOrphanSymbols,
12700
+ gcOrphanCallEdges
12701
+ };
12503
12702
  }
12504
12703
  async retryFailedBatches() {
12505
12704
  return this.withIndexMutationLease("retry-failed-batches", async (recoveredOwners) => {
@@ -12694,9 +12893,18 @@ var Indexer = class _Indexer {
12694
12893
  return this.baseBranch;
12695
12894
  }
12696
12895
  refreshBranchInfo() {
12896
+ const previousBranch = this.currentBranch;
12697
12897
  if (isGitRepo(this.materializedProjectRoot)) {
12698
12898
  this.currentBranch = this.branchNameOverride ?? getBranchOrDefault(this.materializedProjectRoot);
12699
12899
  this.baseBranch = getBaseBranch(this.materializedProjectRoot);
12900
+ } else {
12901
+ this.currentBranch = "default";
12902
+ this.baseBranch = "default";
12903
+ }
12904
+ if (this.currentBranch !== previousBranch) {
12905
+ this.refreshRuntimeArtifactPaths();
12906
+ this.fileHashCache.clear();
12907
+ this.loadFileHashCache();
12700
12908
  }
12701
12909
  }
12702
12910
  async getDatabaseStats() {
@@ -12721,6 +12929,7 @@ var Indexer = class _Indexer {
12721
12929
  return [];
12722
12930
  }
12723
12931
  const filterByBranch = options?.filterByBranch ?? true;
12932
+ const excludedStoredFile = options?.excludeFile ? this.toStoredFilePath(options.excludeFile) : void 0;
12724
12933
  this.logger.search("debug", "Starting find similar", {
12725
12934
  codeLength: code.length,
12726
12935
  limit,
@@ -12730,31 +12939,29 @@ var Indexer = class _Indexer {
12730
12939
  const { embedding, tokensUsed } = await provider.embedDocument(code);
12731
12940
  const embeddingMs = import_perf_hooks.performance.now() - embeddingStartTime;
12732
12941
  this.logger.recordEmbeddingApiCall(tokensUsed);
12733
- const vectorStartTime = import_perf_hooks.performance.now();
12734
- const semanticResults = store.search(embedding, limit * 2);
12735
- const vectorMs = import_perf_hooks.performance.now() - vectorStartTime;
12942
+ const prefilterStartTime = import_perf_hooks.performance.now();
12736
12943
  let branchChunkIds = null;
12737
12944
  if (filterByBranch && (this.config.scope === "global" || this.currentBranch !== "default")) {
12738
12945
  branchChunkIds = new Set(
12739
12946
  this.getBranchCatalogKeys().flatMap((branchKey) => database.getBranchChunkIds(branchKey))
12740
12947
  );
12741
12948
  }
12742
- const prefilterStartTime = import_perf_hooks.performance.now();
12743
- const shouldPrefilterByBranch = branchChunkIds !== null && (this.config.scope === "global" || branchChunkIds.size > 0);
12744
- const allowBranchPrefilterFallback = this.config.scope !== "global";
12745
- const prefilteredSemantic = shouldPrefilterByBranch && branchChunkIds ? semanticResults.filter((r) => branchChunkIds.has(r.id)) : semanticResults;
12746
- const semanticCandidates = allowBranchPrefilterFallback && shouldPrefilterByBranch && semanticResults.length > 0 && prefilteredSemantic.length === 0 ? semanticResults : prefilteredSemantic;
12949
+ const { hasInitializedBranchCatalog, shouldPrefilterByBranch } = this.getBranchPrefilterState(database, branchChunkIds);
12747
12950
  const prefilterMs = import_perf_hooks.performance.now() - prefilterStartTime;
12748
- if (this.config.scope !== "global" && branchChunkIds && branchChunkIds.size === 0) {
12951
+ const vectorStartTime = import_perf_hooks.performance.now();
12952
+ const semanticCandidates = this.searchSemanticCandidates(
12953
+ store,
12954
+ embedding,
12955
+ limit * 2,
12956
+ branchChunkIds,
12957
+ shouldPrefilterByBranch
12958
+ );
12959
+ const vectorMs = import_perf_hooks.performance.now() - vectorStartTime;
12960
+ if (this.config.scope !== "global" && branchChunkIds && !hasInitializedBranchCatalog) {
12749
12961
  this.logger.search("warn", "Branch prefilter skipped because branch catalog is empty", {
12750
12962
  branch: this.currentBranch
12751
12963
  });
12752
12964
  }
12753
- if (allowBranchPrefilterFallback && shouldPrefilterByBranch && semanticResults.length > 0 && prefilteredSemantic.length === 0) {
12754
- this.logger.search("warn", "Branch prefilter produced no semantic overlap, using unfiltered semantic candidates", {
12755
- branch: this.currentBranch
12756
- });
12757
- }
12758
12965
  const rerankTopN = this.config.search.rerankTopN;
12759
12966
  const ranked = rankSemanticOnlyResults(code, semanticCandidates, {
12760
12967
  rerankTopN,
@@ -12763,21 +12970,10 @@ var Indexer = class _Indexer {
12763
12970
  });
12764
12971
  const filtered = ranked.filter((r) => {
12765
12972
  if (r.score < this.config.search.minScore) return false;
12766
- if (options?.excludeFile) {
12767
- if (r.metadata.filePath === options.excludeFile) return false;
12768
- }
12769
- if (options?.fileType) {
12770
- const ext = r.metadata.filePath.split(".").pop()?.toLowerCase();
12771
- if (ext !== options.fileType.toLowerCase().replace(/^\./, "")) return false;
12772
- }
12773
- if (options?.directory) {
12774
- const normalizedDir = options.directory.replace(/^\/|\/$/g, "");
12775
- if (!r.metadata.filePath.includes(`/${normalizedDir}/`) && !r.metadata.filePath.includes(`${normalizedDir}/`)) return false;
12973
+ if (excludedStoredFile) {
12974
+ if (r.metadata.filePath === excludedStoredFile) return false;
12776
12975
  }
12777
- if (options?.chunkType) {
12778
- if (r.metadata.chunkType !== options.chunkType) return false;
12779
- }
12780
- return true;
12976
+ return matchesHardSearchFilters(r, options, this.projectRoot);
12781
12977
  }).slice(0, limit);
12782
12978
  const totalSearchMs = import_perf_hooks.performance.now() - searchStartTime;
12783
12979
  this.logger.recordSearch(totalSearchMs, {
@@ -12797,10 +12993,11 @@ var Indexer = class _Indexer {
12797
12993
  return Promise.all(
12798
12994
  filtered.map(async (r) => {
12799
12995
  let content = "";
12996
+ const resolvedFilePath = this.resolveStoredFilePath(r.metadata.filePath);
12800
12997
  if (this.config.search.includeContext) {
12801
12998
  try {
12802
12999
  const fileContent = await import_fs12.promises.readFile(
12803
- r.metadata.filePath,
13000
+ resolvedFilePath,
12804
13001
  "utf-8"
12805
13002
  );
12806
13003
  const lines = fileContent.split("\n");
@@ -12810,7 +13007,7 @@ var Indexer = class _Indexer {
12810
13007
  }
12811
13008
  }
12812
13009
  return {
12813
- filePath: r.metadata.filePath,
13010
+ filePath: resolvedFilePath,
12814
13011
  startLine: r.metadata.startLine,
12815
13012
  endLine: r.metadata.endLine,
12816
13013
  content,
@@ -12831,7 +13028,7 @@ var Indexer = class _Indexer {
12831
13028
  for (const edge of database.getCallersWithContext(targetName, branchKey, callTypeFilter)) {
12832
13029
  if (!seen.has(edge.id)) {
12833
13030
  seen.add(edge.id);
12834
- results.push(edge);
13031
+ results.push(this.resolveCallEdgeFilePath(edge));
12835
13032
  }
12836
13033
  }
12837
13034
  }
@@ -12850,7 +13047,7 @@ var Indexer = class _Indexer {
12850
13047
  const safelyMatchesUnresolvedSymbol = includeUnresolved && !edge.toSymbolId;
12851
13048
  if (!matchesResolvedSymbol && !safelyMatchesUnresolvedSymbol || seen.has(edge.id)) continue;
12852
13049
  seen.add(edge.id);
12853
- results.push(edge);
13050
+ results.push(this.resolveCallEdgeFilePath(edge));
12854
13051
  }
12855
13052
  }
12856
13053
  return results;
@@ -12864,7 +13061,7 @@ var Indexer = class _Indexer {
12864
13061
  for (const edge of database.getCallees(symbolId, branchKey, callTypeFilter)) {
12865
13062
  if (!seen.has(edge.id)) {
12866
13063
  seen.add(edge.id);
12867
- results.push(edge);
13064
+ results.push(this.resolveCallEdgeFilePath(edge));
12868
13065
  }
12869
13066
  }
12870
13067
  }
@@ -12880,7 +13077,7 @@ var Indexer = class _Indexer {
12880
13077
  shortest = path20;
12881
13078
  }
12882
13079
  }
12883
- return shortest;
13080
+ return shortest.map((hop) => this.resolveFilePathRecord(hop));
12884
13081
  }
12885
13082
  async findCallPathBySymbolIds(fromSymbolId, toSymbolId, maxDepth = 10) {
12886
13083
  const { database, readIssues } = await this.ensureInitialized();
@@ -12946,7 +13143,7 @@ var Indexer = class _Indexer {
12946
13143
  shortest = path20;
12947
13144
  }
12948
13145
  }
12949
- return shortest;
13146
+ return shortest.map((hop) => this.resolveFilePathRecord(hop));
12950
13147
  }
12951
13148
  async getCallGraphSymbols() {
12952
13149
  const { database, readIssues } = await this.ensureInitialized();
@@ -12954,7 +13151,7 @@ var Indexer = class _Indexer {
12954
13151
  const symbols = /* @__PURE__ */ new Map();
12955
13152
  for (const branchKey of this.getBranchCatalogKeys()) {
12956
13153
  for (const symbol of database.getSymbolsForBranch(branchKey)) {
12957
- symbols.set(symbol.id, symbol);
13154
+ symbols.set(symbol.id, this.resolveFilePathRecord(symbol));
12958
13155
  }
12959
13156
  }
12960
13157
  return [...symbols.values()];
@@ -12963,31 +13160,32 @@ var Indexer = class _Indexer {
12963
13160
  const { database, readIssues } = await this.ensureInitialized();
12964
13161
  this.requireReadableComponents(readIssues, "database");
12965
13162
  const resolvedBranch = branch ?? this.getBranchCatalogKey();
12966
- return database.getSymbolsForBranch(resolvedBranch);
13163
+ return database.getSymbolsForBranch(resolvedBranch).map((symbol) => this.resolveFilePathRecord(symbol));
12967
13164
  }
12968
13165
  async getSymbolsForFiles(filePaths, branch) {
12969
13166
  const { database, readIssues } = await this.ensureInitialized();
12970
13167
  this.requireReadableComponents(readIssues, "database");
12971
13168
  const resolvedBranch = branch ?? this.getBranchCatalogKey();
12972
- return database.getSymbolsForFiles(filePaths, resolvedBranch);
13169
+ const storedFilePaths = filePaths.map((filePath) => this.toStoredFilePath(filePath));
13170
+ return database.getSymbolsForFiles(storedFilePaths, resolvedBranch).map((symbol) => this.resolveFilePathRecord(symbol));
12973
13171
  }
12974
13172
  async getTransitiveReachability(rootSymbolIds, direction, maxDepth) {
12975
13173
  const { database, readIssues } = await this.ensureInitialized();
12976
13174
  this.requireReadableComponents(readIssues, "database");
12977
13175
  const branch = this.getBranchCatalogKey();
12978
- return database.getTransitiveReachability(rootSymbolIds, branch, direction, maxDepth);
13176
+ return database.getTransitiveReachability(rootSymbolIds, branch, direction, maxDepth).map((entry) => this.resolveFilePathRecord(entry));
12979
13177
  }
12980
13178
  async detectCommunities(branch, symbolIds) {
12981
13179
  const { database, readIssues } = await this.ensureInitialized();
12982
13180
  this.requireReadableComponents(readIssues, "database");
12983
13181
  const resolvedBranch = branch ?? this.getBranchCatalogKey();
12984
- return database.detectCommunities(resolvedBranch, symbolIds);
13182
+ return database.detectCommunities(resolvedBranch, symbolIds).map((entry) => this.resolveFilePathRecord(entry));
12985
13183
  }
12986
13184
  async computeCentrality(branch) {
12987
13185
  const { database, readIssues } = await this.ensureInitialized();
12988
13186
  this.requireReadableComponents(readIssues, "database");
12989
13187
  const resolvedBranch = branch ?? this.getBranchCatalogKey();
12990
- return database.computeCentrality(resolvedBranch);
13188
+ return database.computeCentrality(resolvedBranch).map((entry) => this.resolveFilePathRecord(entry));
12991
13189
  }
12992
13190
  async getPrImpact(opts, onPreparationProgress) {
12993
13191
  const initialState = await this.ensureInitialized();
@@ -13023,10 +13221,8 @@ var Indexer = class _Indexer {
13023
13221
  const requestedRef = opts.pr !== void 0 ? expectedCommit : headRefName ?? resolvedBranch;
13024
13222
  const storedCommit = this.getStoredBranchCommit(database, catalogIdentity);
13025
13223
  const catalogIdentityMatches = storedCommit === expectedCommit;
13026
- const symbolsCurrent = database.getMetadata(
13027
- this.getSymbolExtractorVersionMetadataKey(catalogIdentity)
13028
- ) === SYMBOL_EXTRACTOR_VERSION;
13029
- if (branchSymbols.length === 0 || !catalogIdentityMatches || !symbolsCurrent) {
13224
+ const migrationsCurrent = this.areBranchMigrationVersionsCurrent(database, catalogIdentity);
13225
+ if (branchSymbols.length === 0 || !catalogIdentityMatches || !migrationsCurrent) {
13030
13226
  if (!resolvedBranch || resolvedBranch === "default") {
13031
13227
  throw new Error("Run index_codebase first to build the call graph and symbol index for this project.");
13032
13228
  }
@@ -13082,8 +13278,9 @@ var Indexer = class _Indexer {
13082
13278
  );
13083
13279
  }
13084
13280
  }
13085
- const absoluteChangedFiles = changedFiles.map((f) => path18.resolve(this.projectRoot, f));
13086
- const directSymbols = database.getSymbolsForFiles(absoluteChangedFiles, branchKey);
13281
+ const toStoredChangedFiles = (filePaths) => filePaths.map((filePath) => this.toStoredFilePath(path18.resolve(this.projectRoot, filePath)));
13282
+ const storedChangedFiles = toStoredChangedFiles(changedFiles);
13283
+ const directSymbols = database.getSymbolsForFiles(storedChangedFiles, branchKey);
13087
13284
  const directIds = directSymbols.map((s) => s.id);
13088
13285
  const direction = opts.direction ?? "both";
13089
13286
  const maxDepth = opts.maxDepth ?? 5;
@@ -13125,7 +13322,7 @@ var Indexer = class _Indexer {
13125
13322
  id: c.symbolId,
13126
13323
  name: c.symbolName,
13127
13324
  callerCount: c.callerCount,
13128
- filePath: c.filePath
13325
+ filePath: this.resolveStoredFilePath(c.filePath)
13129
13326
  }));
13130
13327
  const totalAffected = allAffectedIds.length;
13131
13328
  let riskLevel;
@@ -13165,9 +13362,9 @@ var Indexer = class _Indexer {
13165
13362
  projectRoot: this.projectRoot,
13166
13363
  baseBranch: this.baseBranch
13167
13364
  });
13168
- const otherAbsolute = otherChanged.files.map((f) => path18.resolve(this.projectRoot, f));
13365
+ const otherStored = toStoredChangedFiles(otherChanged.files);
13169
13366
  const prBranchKey = this.getBranchCatalogKeyFor(otherChanged.catalogIdentity);
13170
- const otherSymbols = database.getSymbolsForFiles(otherAbsolute, prBranchKey);
13367
+ const otherSymbols = database.getSymbolsForFiles(otherStored, prBranchKey);
13171
13368
  const otherLabels = /* @__PURE__ */ new Set();
13172
13369
  for (const sym of otherSymbols) {
13173
13370
  const label = symbolToCommunity.get(structuralKey(sym.filePath, sym.name));
@@ -13198,12 +13395,12 @@ var Indexer = class _Indexer {
13198
13395
  id: s.id,
13199
13396
  name: s.name,
13200
13397
  kind: s.kind,
13201
- filePath: s.filePath
13398
+ filePath: this.resolveStoredFilePath(s.filePath)
13202
13399
  })),
13203
13400
  transitiveCallers: transitiveCallers.map((c) => ({
13204
13401
  id: c.symbolId,
13205
13402
  name: c.symbolName,
13206
- filePath: c.filePath,
13403
+ filePath: this.resolveStoredFilePath(c.filePath),
13207
13404
  depth: c.depth
13208
13405
  })),
13209
13406
  totalAffected,
@@ -13233,7 +13430,7 @@ var Indexer = class _Indexer {
13233
13430
  const absoluteDirectoryFilter = directory ? path18.resolve(this.projectRoot, directory) : void 0;
13234
13431
  for (const filePath of filePaths) {
13235
13432
  if (directory) {
13236
- const absoluteFilePath = path18.resolve(filePath);
13433
+ const absoluteFilePath = this.resolveStoredFilePath(filePath);
13237
13434
  const matchesRelative = filePath === directory || filePath.startsWith(directory + "/");
13238
13435
  const matchesProjectRelative = absoluteDirectoryFilter !== void 0 && (absoluteFilePath === absoluteDirectoryFilter || absoluteFilePath.startsWith(absoluteDirectoryFilter + path18.sep));
13239
13436
  if (!matchesRelative && !matchesProjectRelative) {
@@ -13242,14 +13439,14 @@ var Indexer = class _Indexer {
13242
13439
  }
13243
13440
  for (const sym of database.getSymbolsByFile(filePath)) {
13244
13441
  if (symbolIdSet.has(sym.id) && !seenSymbols.has(sym.id)) {
13245
- seenSymbols.set(sym.id, sym);
13442
+ seenSymbols.set(sym.id, this.resolveFilePathRecord(sym));
13246
13443
  }
13247
13444
  }
13248
13445
  }
13249
13446
  for (const symbolId of seenSymbols.keys()) {
13250
13447
  for (const edge of database.getCallees(symbolId, branchKey)) {
13251
13448
  if (!seenEdges.has(edge.id)) {
13252
- seenEdges.set(edge.id, edge);
13449
+ seenEdges.set(edge.id, this.resolveCallEdgeFilePath(edge));
13253
13450
  }
13254
13451
  }
13255
13452
  }
@@ -13356,7 +13553,7 @@ function getOrCreateIndexer(projectRoot3, host) {
13356
13553
  configureAutoIndex(projectRoot3, host, config, () => getOrCreateIndexer(projectRoot3, host));
13357
13554
  return indexer;
13358
13555
  }
13359
- function getIndexerForProject(projectRoot3, host = "opencode") {
13556
+ function getIndexerForProject(projectRoot3, host) {
13360
13557
  const root = getProjectRoot(projectRoot3, host);
13361
13558
  return getOrCreateIndexer(root, host);
13362
13559
  }
@@ -13364,7 +13561,7 @@ function recordToolEffectiveness(projectRoot3, host, event) {
13364
13561
  if (!isToolEffectivenessEnabled(projectRoot3, host)) return;
13365
13562
  safelyRecordToolEffectiveness(event);
13366
13563
  }
13367
- function refreshIndexerForDirectory(projectRoot3, host = "opencode", config = parseConfig(loadRuntimeConfig(projectRoot3, host))) {
13564
+ function refreshIndexerForDirectory(projectRoot3, host, config = parseConfig(loadRuntimeConfig(projectRoot3, host))) {
13368
13565
  const key = getIndexerCacheKey(projectRoot3, host);
13369
13566
  configCache.set(key, config);
13370
13567
  indexerCache.set(key, new Indexer(projectRoot3, config, host));
@@ -14474,8 +14671,86 @@ async function resolveCodebaseContext(projectRoot3, host, input) {
14474
14671
  }
14475
14672
  }
14476
14673
 
14477
- // src/pi-call-graph.ts
14674
+ // src/adapters/pi/call-graph.ts
14478
14675
  var import_typebox = require("typebox");
14676
+
14677
+ // src/tools/tool-names.ts
14678
+ var TOOL_NAME = {
14679
+ CODEBASE_CONTEXT: "codebase_context",
14680
+ CODEBASE_SEARCH: "codebase_search",
14681
+ CODEBASE_PEEK: "codebase_peek",
14682
+ FIND_SIMILAR: "find_similar",
14683
+ IMPLEMENTATION_LOOKUP: "implementation_lookup",
14684
+ INDEX_CODEBASE: "index_codebase",
14685
+ INDEX_STATUS: "index_status",
14686
+ INDEX_HEALTH_CHECK: "index_health_check",
14687
+ INDEX_METRICS: "index_metrics",
14688
+ INDEX_LOGS: "index_logs",
14689
+ CALL_GRAPH: "call_graph",
14690
+ CALL_GRAPH_PATH: "call_graph_path",
14691
+ PR_IMPACT: "pr_impact",
14692
+ ADD_KNOWLEDGE_BASE: "add_knowledge_base",
14693
+ LIST_KNOWLEDGE_BASES: "list_knowledge_bases",
14694
+ REMOVE_KNOWLEDGE_BASE: "remove_knowledge_base",
14695
+ PI_KNOWLEDGE_BASE_ADD: "knowledge_base_add",
14696
+ PI_KNOWLEDGE_BASE_LIST: "knowledge_base_list",
14697
+ PI_KNOWLEDGE_BASE_REMOVE: "knowledge_base_remove",
14698
+ INDEX_VISUALIZE: "index_visualize"
14699
+ };
14700
+ var PORTABLE_TOOL_NAMES = [
14701
+ TOOL_NAME.CODEBASE_CONTEXT,
14702
+ TOOL_NAME.CODEBASE_SEARCH,
14703
+ TOOL_NAME.CODEBASE_PEEK,
14704
+ TOOL_NAME.INDEX_CODEBASE,
14705
+ TOOL_NAME.INDEX_STATUS,
14706
+ TOOL_NAME.INDEX_HEALTH_CHECK,
14707
+ TOOL_NAME.INDEX_METRICS,
14708
+ TOOL_NAME.INDEX_LOGS,
14709
+ TOOL_NAME.FIND_SIMILAR,
14710
+ TOOL_NAME.IMPLEMENTATION_LOOKUP,
14711
+ TOOL_NAME.CALL_GRAPH,
14712
+ TOOL_NAME.CALL_GRAPH_PATH,
14713
+ TOOL_NAME.PR_IMPACT
14714
+ ];
14715
+ var OPENCODE_TOOL_NAMES = [
14716
+ TOOL_NAME.CODEBASE_CONTEXT,
14717
+ TOOL_NAME.CODEBASE_SEARCH,
14718
+ TOOL_NAME.CODEBASE_PEEK,
14719
+ TOOL_NAME.INDEX_CODEBASE,
14720
+ TOOL_NAME.INDEX_STATUS,
14721
+ TOOL_NAME.INDEX_HEALTH_CHECK,
14722
+ TOOL_NAME.INDEX_METRICS,
14723
+ TOOL_NAME.INDEX_LOGS,
14724
+ TOOL_NAME.FIND_SIMILAR,
14725
+ TOOL_NAME.CALL_GRAPH,
14726
+ TOOL_NAME.CALL_GRAPH_PATH,
14727
+ TOOL_NAME.IMPLEMENTATION_LOOKUP,
14728
+ TOOL_NAME.ADD_KNOWLEDGE_BASE,
14729
+ TOOL_NAME.LIST_KNOWLEDGE_BASES,
14730
+ TOOL_NAME.REMOVE_KNOWLEDGE_BASE,
14731
+ TOOL_NAME.PR_IMPACT,
14732
+ TOOL_NAME.INDEX_VISUALIZE
14733
+ ];
14734
+ var PI_TOOL_NAMES = [
14735
+ TOOL_NAME.CODEBASE_CONTEXT,
14736
+ TOOL_NAME.CODEBASE_SEARCH,
14737
+ TOOL_NAME.CODEBASE_PEEK,
14738
+ TOOL_NAME.FIND_SIMILAR,
14739
+ TOOL_NAME.IMPLEMENTATION_LOOKUP,
14740
+ TOOL_NAME.INDEX_CODEBASE,
14741
+ TOOL_NAME.INDEX_STATUS,
14742
+ TOOL_NAME.INDEX_HEALTH_CHECK,
14743
+ TOOL_NAME.INDEX_METRICS,
14744
+ TOOL_NAME.INDEX_LOGS,
14745
+ TOOL_NAME.CALL_GRAPH,
14746
+ TOOL_NAME.CALL_GRAPH_PATH,
14747
+ TOOL_NAME.PR_IMPACT,
14748
+ TOOL_NAME.PI_KNOWLEDGE_BASE_LIST,
14749
+ TOOL_NAME.PI_KNOWLEDGE_BASE_ADD,
14750
+ TOOL_NAME.PI_KNOWLEDGE_BASE_REMOVE
14751
+ ];
14752
+
14753
+ // src/adapters/pi/call-graph.ts
14479
14754
  var HOST = "pi";
14480
14755
  var RelationshipType = import_typebox.Type.Union([
14481
14756
  import_typebox.Type.Literal("Call"),
@@ -14493,7 +14768,7 @@ function projectRoot(ctx) {
14493
14768
  }
14494
14769
  function registerPiCallGraphTools(pi) {
14495
14770
  pi.registerTool({
14496
- name: "call_graph",
14771
+ name: TOOL_NAME.CALL_GRAPH,
14497
14772
  label: "Call Graph",
14498
14773
  description: "Find callers or callees by function or method name. Unique names resolve automatically; use filePath when duplicate names are reported.",
14499
14774
  parameters: import_typebox.Type.Object({
@@ -14509,7 +14784,7 @@ function registerPiCallGraphTools(pi) {
14509
14784
  }
14510
14785
  });
14511
14786
  pi.registerTool({
14512
- name: "call_graph_path",
14787
+ name: TOOL_NAME.CALL_GRAPH_PATH,
14513
14788
  label: "Call Graph Path",
14514
14789
  description: "Find a call path between two named functions or methods. Use fromFilePath or toFilePath when duplicate endpoints are reported.",
14515
14790
  parameters: import_typebox.Type.Object({
@@ -14534,7 +14809,7 @@ function registerPiCallGraphTools(pi) {
14534
14809
  });
14535
14810
  }
14536
14811
 
14537
- // src/pi-extension.ts
14812
+ // src/adapters/pi/extension.ts
14538
14813
  var HOST2 = "pi";
14539
14814
  var ChunkType = import_typebox2.Type.Union([
14540
14815
  import_typebox2.Type.Literal("function"),
@@ -14553,7 +14828,7 @@ function projectRoot2(ctx) {
14553
14828
  }
14554
14829
  function codebaseIndexPiExtension(pi) {
14555
14830
  pi.registerTool({
14556
- name: "codebase_context",
14831
+ name: TOOL_NAME.CODEBASE_CONTEXT,
14557
14832
  label: "Codebase Context",
14558
14833
  description: "PREFERRED FIRST TOOL for any repository question. Returns a deduplicated, file-diverse evidence pack within tokenBudget. Check index_status when freshness is unknown, then use this tool for low-token location discovery and dependency flow. Use fromFilePath/toFilePath only when duplicate path endpoints are reported.",
14559
14834
  parameters: import_typebox2.Type.Object({
@@ -14587,7 +14862,7 @@ function codebaseIndexPiExtension(pi) {
14587
14862
  }
14588
14863
  });
14589
14864
  pi.registerTool({
14590
- name: "codebase_search",
14865
+ name: TOOL_NAME.CODEBASE_SEARCH,
14591
14866
  label: "Codebase Search",
14592
14867
  description: "Use this after codebase_context when you need semantic content, not just locations. Describe behavior, not syntax.",
14593
14868
  parameters: import_typebox2.Type.Object({
@@ -14612,7 +14887,7 @@ function codebaseIndexPiExtension(pi) {
14612
14887
  }
14613
14888
  });
14614
14889
  pi.registerTool({
14615
- name: "codebase_peek",
14890
+ name: TOOL_NAME.CODEBASE_PEEK,
14616
14891
  label: "Codebase Peek",
14617
14892
  description: "LOW-TOKEN location-first retrieval. Prefer codebase_context first, then use this for cheap conceptual lookup.",
14618
14893
  parameters: import_typebox2.Type.Object({
@@ -14636,7 +14911,7 @@ function codebaseIndexPiExtension(pi) {
14636
14911
  }
14637
14912
  });
14638
14913
  pi.registerTool({
14639
- name: "find_similar",
14914
+ name: TOOL_NAME.FIND_SIMILAR,
14640
14915
  label: "Find Similar Code",
14641
14916
  description: "Find code similar to a snippet for duplicate detection, pattern discovery, and refactor planning.",
14642
14917
  parameters: import_typebox2.Type.Object({
@@ -14653,7 +14928,7 @@ function codebaseIndexPiExtension(pi) {
14653
14928
  }
14654
14929
  });
14655
14930
  pi.registerTool({
14656
- name: "implementation_lookup",
14931
+ name: TOOL_NAME.IMPLEMENTATION_LOOKUP,
14657
14932
  label: "Implementation Lookup",
14658
14933
  description: "Find likely symbol definitions or implementations after codebase_context identifies a symbol.",
14659
14934
  parameters: import_typebox2.Type.Object({
@@ -14668,7 +14943,7 @@ function codebaseIndexPiExtension(pi) {
14668
14943
  }
14669
14944
  });
14670
14945
  pi.registerTool({
14671
- name: "index_codebase",
14946
+ name: TOOL_NAME.INDEX_CODEBASE,
14672
14947
  label: "Index Codebase",
14673
14948
  description: "Build or refresh the semantic codebase index. Run index_status when freshness is unknown.",
14674
14949
  parameters: import_typebox2.Type.Object({
@@ -14685,7 +14960,7 @@ function codebaseIndexPiExtension(pi) {
14685
14960
  }
14686
14961
  });
14687
14962
  pi.registerTool({
14688
- name: "index_status",
14963
+ name: TOOL_NAME.INDEX_STATUS,
14689
14964
  label: "Index Status",
14690
14965
  description: "Check index health and current status.",
14691
14966
  parameters: import_typebox2.Type.Object({}),
@@ -14695,7 +14970,7 @@ function codebaseIndexPiExtension(pi) {
14695
14970
  }
14696
14971
  });
14697
14972
  pi.registerTool({
14698
- name: "index_health_check",
14973
+ name: TOOL_NAME.INDEX_HEALTH_CHECK,
14699
14974
  label: "Index Health Check",
14700
14975
  description: "Garbage collect orphaned embeddings/chunks and report index health status.",
14701
14976
  parameters: import_typebox2.Type.Object({}),
@@ -14706,7 +14981,7 @@ function codebaseIndexPiExtension(pi) {
14706
14981
  }
14707
14982
  });
14708
14983
  pi.registerTool({
14709
- name: "index_metrics",
14984
+ name: TOOL_NAME.INDEX_METRICS,
14710
14985
  label: "Index Metrics",
14711
14986
  description: "Return operational metrics and opt-in memory-only privacy-safe effectiveness counters.",
14712
14987
  parameters: import_typebox2.Type.Object({
@@ -14718,7 +14993,7 @@ function codebaseIndexPiExtension(pi) {
14718
14993
  }
14719
14994
  });
14720
14995
  pi.registerTool({
14721
- name: "index_logs",
14996
+ name: TOOL_NAME.INDEX_LOGS,
14722
14997
  label: "Index Logs",
14723
14998
  description: "Return recent debug logs when debug logging is enabled.",
14724
14999
  parameters: import_typebox2.Type.Object({
@@ -14748,7 +15023,7 @@ Check index_status first when index readiness is unknown. For repository questio
14748
15023
  await stopAutoIndex(projectRoot2(ctx), HOST2);
14749
15024
  });
14750
15025
  pi.registerTool({
14751
- name: "pr_impact",
15026
+ name: TOOL_NAME.PR_IMPACT,
14752
15027
  label: "PR Impact",
14753
15028
  description: "Analyze PR or branch impact through changed symbols and call graph neighborhoods.",
14754
15029
  parameters: import_typebox2.Type.Object({
@@ -14765,7 +15040,7 @@ Check index_status first when index readiness is unknown. For repository questio
14765
15040
  }
14766
15041
  });
14767
15042
  pi.registerTool({
14768
- name: "knowledge_base_list",
15043
+ name: TOOL_NAME.PI_KNOWLEDGE_BASE_LIST,
14769
15044
  label: "List Knowledge Bases",
14770
15045
  description: "List configured knowledge-base paths included in the index.",
14771
15046
  parameters: import_typebox2.Type.Object({}),
@@ -14774,7 +15049,7 @@ Check index_status first when index readiness is unknown. For repository questio
14774
15049
  }
14775
15050
  });
14776
15051
  pi.registerTool({
14777
- name: "knowledge_base_add",
15052
+ name: TOOL_NAME.PI_KNOWLEDGE_BASE_ADD,
14778
15053
  label: "Add Knowledge Base",
14779
15054
  description: "Add a knowledge-base path to the codebase index config.",
14780
15055
  parameters: import_typebox2.Type.Object({ path: import_typebox2.Type.String({ description: "File or directory path to add" }) }),
@@ -14783,7 +15058,7 @@ Check index_status first when index readiness is unknown. For repository questio
14783
15058
  }
14784
15059
  });
14785
15060
  pi.registerTool({
14786
- name: "knowledge_base_remove",
15061
+ name: TOOL_NAME.PI_KNOWLEDGE_BASE_REMOVE,
14787
15062
  label: "Remove Knowledge Base",
14788
15063
  description: "Remove a knowledge-base path from the codebase index config.",
14789
15064
  parameters: import_typebox2.Type.Object({ path: import_typebox2.Type.String({ description: "File or directory path to remove" }) }),