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.
package/dist/index.js CHANGED
@@ -650,7 +650,7 @@ var require_eventemitter3 = __commonJS({
650
650
  }
651
651
  });
652
652
 
653
- // src/index.ts
653
+ // src/adapters/opencode.ts
654
654
  import * as path26 from "path";
655
655
  import { fileURLToPath as fileURLToPath2 } from "url";
656
656
 
@@ -1060,12 +1060,12 @@ var autoDetectProviders = AUTO_DETECT_PROVIDER_ORDER.filter(
1060
1060
 
1061
1061
  // src/config/merger.ts
1062
1062
  import { existsSync as existsSync4, readFileSync as readFileSync3 } from "fs";
1063
- import * as path6 from "path";
1063
+ import * as path7 from "path";
1064
1064
 
1065
1065
  // src/config/paths.ts
1066
1066
  import { existsSync as existsSync3 } from "fs";
1067
1067
  import * as os from "os";
1068
- import * as path3 from "path";
1068
+ import * as path4 from "path";
1069
1069
 
1070
1070
  // src/git/index.ts
1071
1071
  import { existsSync as existsSync2, readFileSync as readFileSync2, statSync as statSync2 } from "fs";
@@ -1204,15 +1204,125 @@ function getHeadPath(repoRoot) {
1204
1204
  return path2.join(repoRoot, ".git", "HEAD");
1205
1205
  }
1206
1206
 
1207
+ // src/utils/canonical-path.ts
1208
+ import * as crypto from "crypto";
1209
+ import * as fs from "fs";
1210
+ import * as path3 from "path";
1211
+
1212
+ // node_modules/unicode-case-folding/index.js
1213
+ 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]]]);
1214
+ function caseFold(input) {
1215
+ if (typeof input !== "string") {
1216
+ throw new TypeError("Input must be a string");
1217
+ }
1218
+ let result = [];
1219
+ for (const char of input) {
1220
+ const codePoint = char.codePointAt(0);
1221
+ const mapping = FOLDING_MAP.get(codePoint);
1222
+ result.push(mapping ? String.fromCodePoint(...mapping) : char);
1223
+ }
1224
+ return result.join("");
1225
+ }
1226
+
1227
+ // src/utils/canonical-path.ts
1228
+ function alternateAsciiCase(value) {
1229
+ const index = value.search(/[A-Za-z]/);
1230
+ if (index === -1) return null;
1231
+ const character = value[index];
1232
+ const alternate = character === character.toLowerCase() ? character.toUpperCase() : character.toLowerCase();
1233
+ return `${value.slice(0, index)}${alternate}${value.slice(index + 1)}`;
1234
+ }
1235
+ function probeEntryCaseSensitivity(entryPath) {
1236
+ const alternateName = alternateAsciiCase(path3.basename(entryPath));
1237
+ if (!alternateName) return void 0;
1238
+ try {
1239
+ const canonicalPath = fs.realpathSync.native(entryPath);
1240
+ const alternatePath = fs.realpathSync.native(path3.join(path3.dirname(entryPath), alternateName));
1241
+ return canonicalPath === alternatePath;
1242
+ } catch (error) {
1243
+ const code = error.code;
1244
+ if (code === "ENOENT" || code === "ENOTDIR") return false;
1245
+ return void 0;
1246
+ }
1247
+ }
1248
+ function probeEmptyWindowsDirectory(existingAncestor) {
1249
+ const probePath = path3.join(
1250
+ existingAncestor,
1251
+ `.codebase-index-case-probe-${crypto.randomBytes(8).toString("hex")}`
1252
+ );
1253
+ let created = false;
1254
+ try {
1255
+ const descriptor = fs.openSync(probePath, "wx", 384);
1256
+ created = true;
1257
+ fs.closeSync(descriptor);
1258
+ return probeEntryCaseSensitivity(probePath);
1259
+ } catch {
1260
+ return void 0;
1261
+ } finally {
1262
+ if (created) fs.unlinkSync(probePath);
1263
+ }
1264
+ }
1265
+ function detectCaseInsensitiveFileSystem(existingAncestor) {
1266
+ try {
1267
+ if (fs.statSync(existingAncestor).isDirectory()) {
1268
+ const directory = fs.opendirSync(existingAncestor);
1269
+ try {
1270
+ let entry = directory.readSync();
1271
+ while (entry) {
1272
+ if (!entry.isSymbolicLink() && alternateAsciiCase(entry.name)) {
1273
+ const result = probeEntryCaseSensitivity(path3.join(existingAncestor, entry.name));
1274
+ if (result !== void 0) return result;
1275
+ }
1276
+ entry = directory.readSync();
1277
+ }
1278
+ } finally {
1279
+ directory.closeSync();
1280
+ }
1281
+ }
1282
+ } catch {
1283
+ return void 0;
1284
+ }
1285
+ if (process.platform === "darwin") {
1286
+ return probeEntryCaseSensitivity(existingAncestor);
1287
+ }
1288
+ if (process.platform === "win32") {
1289
+ return probeEmptyWindowsDirectory(existingAncestor);
1290
+ }
1291
+ return void 0;
1292
+ }
1293
+ function foldMissingPathComponent(component) {
1294
+ return caseFold(component);
1295
+ }
1296
+ function canonicalizePathForComparison(targetPath, options = {}) {
1297
+ const resolved = path3.resolve(targetPath);
1298
+ const missingParts = [];
1299
+ let candidate = resolved;
1300
+ while (true) {
1301
+ try {
1302
+ const existingAncestor = fs.realpathSync.native(candidate);
1303
+ const isCaseInsensitive = missingParts.length > 0 ? (options.isCaseInsensitive ?? detectCaseInsensitiveFileSystem)(existingAncestor) : false;
1304
+ const suffix = isCaseInsensitive === true ? missingParts.map(foldMissingPathComponent) : missingParts;
1305
+ return path3.join(existingAncestor, ...suffix);
1306
+ } catch (error) {
1307
+ const code = error.code;
1308
+ if (code !== "ENOENT" && code !== "ENOTDIR") throw error;
1309
+ const parent = path3.dirname(candidate);
1310
+ if (parent === candidate) return resolved;
1311
+ missingParts.unshift(path3.basename(candidate));
1312
+ candidate = parent;
1313
+ }
1314
+ }
1315
+ }
1316
+
1207
1317
  // src/config/paths.ts
1208
- var OPENCODE_PROJECT_CONFIG_RELATIVE_PATH = path3.join(".opencode", "codebase-index.json");
1209
- var OPENCODE_PROJECT_INDEX_RELATIVE_PATH = path3.join(".opencode", "index");
1318
+ var OPENCODE_PROJECT_CONFIG_RELATIVE_PATH = path4.join(".opencode", "codebase-index.json");
1319
+ var OPENCODE_PROJECT_INDEX_RELATIVE_PATH = path4.join(".opencode", "index");
1210
1320
  var CODEBASE_INDEX_DIR = ".codebase-index";
1211
- var CODEBASE_PROJECT_CONFIG_RELATIVE_PATH = path3.join(CODEBASE_INDEX_DIR, "config.json");
1212
- var CODEBASE_PROJECT_INDEX_RELATIVE_PATH = path3.join(CODEBASE_INDEX_DIR, "index");
1321
+ var CODEBASE_PROJECT_CONFIG_RELATIVE_PATH = path4.join(CODEBASE_INDEX_DIR, "config.json");
1322
+ var CODEBASE_PROJECT_INDEX_RELATIVE_PATH = path4.join(CODEBASE_INDEX_DIR, "index");
1213
1323
  var CLAUDE_DIR = ".claude";
1214
- var CLAUDE_PROJECT_CONFIG_RELATIVE_PATH = path3.join(CLAUDE_DIR, "codebase-index.json");
1215
- var CLAUDE_PROJECT_INDEX_RELATIVE_PATH = path3.join(CLAUDE_DIR, "index");
1324
+ var CLAUDE_PROJECT_CONFIG_RELATIVE_PATH = path4.join(CLAUDE_DIR, "codebase-index.json");
1325
+ var CLAUDE_PROJECT_INDEX_RELATIVE_PATH = path4.join(CLAUDE_DIR, "index");
1216
1326
  function getProjectConfigRelativePath(host) {
1217
1327
  switch (host) {
1218
1328
  case "opencode":
@@ -1238,42 +1348,71 @@ function resolveWorktreeFallbackPath(projectRoot, relativePath) {
1238
1348
  if (!mainRepoRoot) {
1239
1349
  return null;
1240
1350
  }
1241
- const fallbackPath = path3.join(mainRepoRoot, relativePath);
1351
+ const fallbackPath = path4.join(mainRepoRoot, relativePath);
1242
1352
  return existsSync3(fallbackPath) ? fallbackPath : null;
1243
1353
  }
1244
1354
  function getHostProjectConfigRelativePath(host) {
1245
1355
  return getProjectConfigRelativePath(host);
1246
1356
  }
1247
- function getHostProjectIndexRelativePath(host) {
1248
- return getProjectIndexRelativePath(host);
1357
+ function getProjectConfigCandidatePaths(projectRoot, host) {
1358
+ const candidates = [path4.join(projectRoot, getProjectConfigRelativePath(host))];
1359
+ if (host !== "opencode") {
1360
+ candidates.push(path4.join(projectRoot, OPENCODE_PROJECT_CONFIG_RELATIVE_PATH));
1361
+ }
1362
+ const mainRepoRoot = resolveWorktreeMainRepoRoot(projectRoot);
1363
+ if (mainRepoRoot) {
1364
+ candidates.push(path4.join(mainRepoRoot, getProjectConfigRelativePath(host)));
1365
+ if (host !== "opencode") {
1366
+ candidates.push(path4.join(mainRepoRoot, OPENCODE_PROJECT_CONFIG_RELATIVE_PATH));
1367
+ }
1368
+ }
1369
+ return [...new Set(candidates)];
1370
+ }
1371
+ function isProjectIndexPathOwnedByProject(projectRoot, indexPath, host) {
1372
+ const projectRoots = [projectRoot];
1373
+ const mainRepoRoot = resolveWorktreeMainRepoRoot(projectRoot);
1374
+ if (mainRepoRoot) {
1375
+ projectRoots.push(mainRepoRoot);
1376
+ }
1377
+ const ownedIndexPaths = projectRoots.flatMap((root) => {
1378
+ const indexPaths = [path4.join(root, getProjectIndexRelativePath(host))];
1379
+ if (host !== "opencode") {
1380
+ indexPaths.push(path4.join(root, OPENCODE_PROJECT_INDEX_RELATIVE_PATH));
1381
+ }
1382
+ return indexPaths;
1383
+ });
1384
+ const canonicalIndexPath = canonicalizePathForComparison(indexPath);
1385
+ return ownedIndexPaths.some(
1386
+ (ownedPath) => canonicalizePathForComparison(ownedPath) === canonicalIndexPath
1387
+ );
1249
1388
  }
1250
1389
  function hasHostProjectConfig(projectRoot, host) {
1251
- return existsSync3(path3.join(projectRoot, getProjectConfigRelativePath(host)));
1390
+ return existsSync3(path4.join(projectRoot, getProjectConfigRelativePath(host)));
1252
1391
  }
1253
1392
  function hasHostGlobalConfig(host) {
1254
1393
  return existsSync3(getGlobalConfigPath(host));
1255
1394
  }
1256
- function getGlobalIndexPath(host = "opencode") {
1395
+ function getGlobalIndexPath(host) {
1257
1396
  switch (host) {
1258
1397
  case "opencode":
1259
- return path3.join(os.homedir(), ".opencode", "global-index");
1398
+ return path4.join(os.homedir(), ".opencode", "global-index");
1260
1399
  case "claude":
1261
- return path3.join(os.homedir(), ".claude", "global-index");
1400
+ return path4.join(os.homedir(), ".claude", "global-index");
1262
1401
  default:
1263
- return path3.join(os.homedir(), ".codebase-index", "global-index");
1402
+ return path4.join(os.homedir(), ".codebase-index", "global-index");
1264
1403
  }
1265
1404
  }
1266
- function getGlobalConfigPath(host = "opencode") {
1405
+ function getGlobalConfigPath(host) {
1267
1406
  switch (host) {
1268
1407
  case "opencode":
1269
- return path3.join(os.homedir(), ".config", "opencode", "codebase-index.json");
1408
+ return path4.join(os.homedir(), ".config", "opencode", "codebase-index.json");
1270
1409
  case "claude":
1271
- return path3.join(os.homedir(), ".claude", "codebase-index.json");
1410
+ return path4.join(os.homedir(), ".claude", "codebase-index.json");
1272
1411
  default:
1273
- return path3.join(os.homedir(), ".config", "codebase-index", "config.json");
1412
+ return path4.join(os.homedir(), ".config", "codebase-index", "config.json");
1274
1413
  }
1275
1414
  }
1276
- function resolveGlobalConfigPath(host = "opencode") {
1415
+ function resolveGlobalConfigPath(host) {
1277
1416
  const hostConfigPath = getGlobalConfigPath(host);
1278
1417
  if (existsSync3(hostConfigPath)) {
1279
1418
  return hostConfigPath;
@@ -1286,7 +1425,7 @@ function resolveGlobalConfigPath(host = "opencode") {
1286
1425
  }
1287
1426
  return hostConfigPath;
1288
1427
  }
1289
- function resolveGlobalIndexPath(host = "opencode") {
1428
+ function resolveGlobalIndexPath(host) {
1290
1429
  const hostIndexPath = getGlobalIndexPath(host);
1291
1430
  if (existsSync3(hostIndexPath)) {
1292
1431
  return hostIndexPath;
@@ -1302,42 +1441,43 @@ function resolveGlobalIndexPath(host = "opencode") {
1302
1441
  }
1303
1442
  return hostIndexPath;
1304
1443
  }
1305
- function resolveProjectConfigPath(projectRoot, host = "opencode") {
1306
- const hostConfigPath = path3.join(projectRoot, getProjectConfigRelativePath(host));
1307
- if (existsSync3(hostConfigPath)) {
1308
- return hostConfigPath;
1309
- }
1310
- if (host !== "opencode") {
1311
- const legacyConfigPath = path3.join(projectRoot, OPENCODE_PROJECT_CONFIG_RELATIVE_PATH);
1312
- if (existsSync3(legacyConfigPath)) {
1313
- return legacyConfigPath;
1314
- }
1315
- }
1316
- const hostFallback = resolveWorktreeFallbackPath(projectRoot, getProjectConfigRelativePath(host));
1317
- if (hostFallback) {
1318
- return hostFallback;
1319
- }
1320
- if (host !== "opencode") {
1321
- const legacyFallback = resolveWorktreeFallbackPath(projectRoot, OPENCODE_PROJECT_CONFIG_RELATIVE_PATH);
1322
- if (legacyFallback) {
1323
- return legacyFallback;
1324
- }
1325
- }
1326
- return hostConfigPath;
1444
+ function resolveProjectConfigPath(projectRoot, host) {
1445
+ const candidates = getProjectConfigCandidatePaths(projectRoot, host);
1446
+ return candidates.find((candidate) => existsSync3(candidate)) ?? path4.join(projectRoot, getProjectConfigRelativePath(host));
1327
1447
  }
1328
- function resolveWritableProjectConfigPath(projectRoot, host = "opencode") {
1329
- return path3.join(projectRoot, getProjectConfigRelativePath(host));
1448
+ function resolveWritableProjectConfigPath(projectRoot, host) {
1449
+ return path4.join(projectRoot, getProjectConfigRelativePath(host));
1330
1450
  }
1331
- function resolveProjectIndexPath(projectRoot, scope, host = "opencode") {
1451
+ function resolveProjectIndexPath(projectRoot, scope, host) {
1332
1452
  if (scope === "global") {
1333
1453
  return resolveGlobalIndexPath(host);
1334
1454
  }
1335
- const localIndexPath = path3.join(projectRoot, getProjectIndexRelativePath(host));
1455
+ const localIndexPath = path4.join(projectRoot, getProjectIndexRelativePath(host));
1456
+ const mainRepoRoot = resolveWorktreeMainRepoRoot(projectRoot);
1457
+ if (mainRepoRoot) {
1458
+ if (hasHostProjectConfig(projectRoot, host)) {
1459
+ return localIndexPath;
1460
+ }
1461
+ if (host !== "opencode") {
1462
+ const localLegacyConfigPath = path4.join(projectRoot, OPENCODE_PROJECT_CONFIG_RELATIVE_PATH);
1463
+ if (existsSync3(localLegacyConfigPath)) {
1464
+ return path4.join(projectRoot, OPENCODE_PROJECT_INDEX_RELATIVE_PATH);
1465
+ }
1466
+ const mainHostConfigPath = path4.join(mainRepoRoot, getProjectConfigRelativePath(host));
1467
+ const mainHostIndexPath = path4.join(mainRepoRoot, getProjectIndexRelativePath(host));
1468
+ const mainLegacyConfigPath = path4.join(mainRepoRoot, OPENCODE_PROJECT_CONFIG_RELATIVE_PATH);
1469
+ const mainLegacyIndexPath = path4.join(mainRepoRoot, OPENCODE_PROJECT_INDEX_RELATIVE_PATH);
1470
+ if (!existsSync3(mainHostConfigPath) && !existsSync3(mainHostIndexPath) && (existsSync3(mainLegacyConfigPath) || existsSync3(mainLegacyIndexPath))) {
1471
+ return mainLegacyIndexPath;
1472
+ }
1473
+ }
1474
+ return path4.join(mainRepoRoot, getProjectIndexRelativePath(host));
1475
+ }
1336
1476
  if (existsSync3(localIndexPath)) {
1337
1477
  return localIndexPath;
1338
1478
  }
1339
1479
  if (host !== "opencode") {
1340
- const legacyIndexPath = path3.join(projectRoot, OPENCODE_PROJECT_INDEX_RELATIVE_PATH);
1480
+ const legacyIndexPath = path4.join(projectRoot, OPENCODE_PROJECT_INDEX_RELATIVE_PATH);
1341
1481
  if (existsSync3(legacyIndexPath) && !hasHostProjectConfig(projectRoot, host)) {
1342
1482
  return legacyIndexPath;
1343
1483
  }
@@ -1345,9 +1485,6 @@ function resolveProjectIndexPath(projectRoot, scope, host = "opencode") {
1345
1485
  if (hasHostProjectConfig(projectRoot, host)) {
1346
1486
  return localIndexPath;
1347
1487
  }
1348
- if (resolveWorktreeMainRepoRoot(projectRoot)) {
1349
- return localIndexPath;
1350
- }
1351
1488
  const hostFallback = resolveWorktreeFallbackPath(projectRoot, getProjectIndexRelativePath(host));
1352
1489
  if (hostFallback) {
1353
1490
  return hostFallback;
@@ -1362,10 +1499,10 @@ function resolveProjectIndexPath(projectRoot, scope, host = "opencode") {
1362
1499
  }
1363
1500
 
1364
1501
  // src/config/rebase.ts
1365
- import * as path5 from "path";
1502
+ import * as path6 from "path";
1366
1503
 
1367
1504
  // src/utils/paths.ts
1368
- import * as path4 from "path";
1505
+ import * as path5 from "path";
1369
1506
  function normalizePathSeparators(value) {
1370
1507
  return value.replace(/\\/g, "/");
1371
1508
  }
@@ -1375,7 +1512,7 @@ function isHiddenPathSegment(part) {
1375
1512
  function isBuildPathSegment(part) {
1376
1513
  return part.toLowerCase().includes("build");
1377
1514
  }
1378
- function hasFilteredPathSegment(relativePath, separator = path4.sep) {
1515
+ function hasFilteredPathSegment(relativePath, separator = path5.sep) {
1379
1516
  return relativePath.split(separator).some(
1380
1517
  (part) => isHiddenPathSegment(part) || isBuildPathSegment(part)
1381
1518
  );
@@ -1401,7 +1538,7 @@ var RESTRICTED_DIRECTORIES = /* @__PURE__ */ new Set([
1401
1538
  "program files (x86)",
1402
1539
  "$recycle.bin"
1403
1540
  ]);
1404
- function isRestrictedDirectory(relativePath, separator = path4.sep) {
1541
+ function isRestrictedDirectory(relativePath, separator = path5.sep) {
1405
1542
  const firstSegment = relativePath.split(separator)[0];
1406
1543
  if (!firstSegment) return false;
1407
1544
  return RESTRICTED_DIRECTORIES.has(firstSegment.toLowerCase());
@@ -1409,8 +1546,8 @@ function isRestrictedDirectory(relativePath, separator = path4.sep) {
1409
1546
 
1410
1547
  // src/config/rebase.ts
1411
1548
  function isWithinRoot(rootDir, targetPath) {
1412
- const relativePath = path5.relative(rootDir, targetPath);
1413
- return relativePath === "" || !relativePath.startsWith("..") && !path5.isAbsolute(relativePath);
1549
+ const relativePath = path6.relative(rootDir, targetPath);
1550
+ return relativePath === "" || !relativePath.startsWith("..") && !path6.isAbsolute(relativePath);
1414
1551
  }
1415
1552
  function resolveInheritedKnowledgeBaseEntries(values, sourceRoot, targetRoot) {
1416
1553
  if (!Array.isArray(values)) {
@@ -1421,17 +1558,17 @@ function resolveInheritedKnowledgeBaseEntries(values, sourceRoot, targetRoot) {
1421
1558
  if (!trimmed) {
1422
1559
  return trimmed;
1423
1560
  }
1424
- if (path5.isAbsolute(trimmed)) {
1561
+ if (path6.isAbsolute(trimmed)) {
1425
1562
  if (isWithinRoot(sourceRoot, trimmed)) {
1426
- return normalizePathSeparators(path5.normalize(path5.relative(sourceRoot, trimmed) || "."));
1563
+ return normalizePathSeparators(path6.normalize(path6.relative(sourceRoot, trimmed) || "."));
1427
1564
  }
1428
- return path5.normalize(trimmed);
1565
+ return path6.normalize(trimmed);
1429
1566
  }
1430
- const resolvedFromSource = path5.resolve(sourceRoot, trimmed);
1567
+ const resolvedFromSource = path6.resolve(sourceRoot, trimmed);
1431
1568
  if (isWithinRoot(sourceRoot, resolvedFromSource)) {
1432
- return normalizePathSeparators(path5.normalize(trimmed));
1569
+ return normalizePathSeparators(path6.normalize(trimmed));
1433
1570
  }
1434
- return normalizePathSeparators(path5.normalize(path5.relative(targetRoot, resolvedFromSource)));
1571
+ return normalizePathSeparators(path6.normalize(path6.relative(targetRoot, resolvedFromSource)));
1435
1572
  }).filter(Boolean);
1436
1573
  }
1437
1574
 
@@ -1469,8 +1606,8 @@ function mergeUniqueStringArray(values) {
1469
1606
  return [...new Set(values.map((value) => String(value).trim()))];
1470
1607
  }
1471
1608
  function normalizeKnowledgeBasePath(value) {
1472
- let normalized = path6.normalize(String(value).trim());
1473
- const root = path6.parse(normalized).root;
1609
+ let normalized = path7.normalize(String(value).trim());
1610
+ const root = path7.parse(normalized).root;
1474
1611
  while (normalized.length > root.length && /[\\/]$/.test(normalized)) {
1475
1612
  normalized = normalized.slice(0, -1);
1476
1613
  }
@@ -1521,14 +1658,14 @@ function loadJsonFile(filePath) {
1521
1658
  function loadConfigFile(filePath) {
1522
1659
  return loadJsonFile(filePath);
1523
1660
  }
1524
- function loadProjectConfigLayer(projectRoot, host = "opencode") {
1661
+ function loadProjectConfigLayer(projectRoot, host) {
1525
1662
  const projectConfigPath = resolveProjectConfigPath(projectRoot, host);
1526
1663
  const projectConfig = loadJsonFile(projectConfigPath);
1527
1664
  if (!projectConfig) {
1528
1665
  return {};
1529
1666
  }
1530
1667
  const normalizedConfig = { ...projectConfig };
1531
- const projectConfigBaseDir = path6.dirname(path6.dirname(projectConfigPath));
1668
+ const projectConfigBaseDir = path7.dirname(path7.dirname(projectConfigPath));
1532
1669
  if (Array.isArray(normalizedConfig.knowledgeBases)) {
1533
1670
  normalizedConfig.knowledgeBases = resolveInheritedKnowledgeBaseEntries(
1534
1671
  normalizedConfig.knowledgeBases,
@@ -1538,7 +1675,7 @@ function loadProjectConfigLayer(projectRoot, host = "opencode") {
1538
1675
  }
1539
1676
  return normalizedConfig;
1540
1677
  }
1541
- function loadMergedConfig(projectRoot, host = "opencode") {
1678
+ function loadMergedConfig(projectRoot, host) {
1542
1679
  const globalConfigPath = resolveGlobalConfigPath(host);
1543
1680
  const projectConfigPath = resolveProjectConfigPath(projectRoot, host);
1544
1681
  let globalConfig = null;
@@ -1596,43 +1733,43 @@ import { existsSync as existsSync11, realpathSync as realpathSync5, statSync as
1596
1733
  import * as path19 from "path";
1597
1734
 
1598
1735
  // src/tools/knowledge-base-paths.ts
1599
- import * as path7 from "path";
1736
+ import * as path8 from "path";
1600
1737
  function resolveConfigPathValue(value, baseDir) {
1601
1738
  const trimmed = value.trim();
1602
1739
  if (!trimmed) {
1603
1740
  return trimmed;
1604
1741
  }
1605
- const absolutePath = path7.isAbsolute(trimmed) ? trimmed : path7.resolve(baseDir, trimmed);
1606
- return path7.normalize(absolutePath);
1742
+ const absolutePath = path8.isAbsolute(trimmed) ? trimmed : path8.resolve(baseDir, trimmed);
1743
+ return path8.normalize(absolutePath);
1607
1744
  }
1608
1745
  function serializeConfigPathValue(value, baseDir) {
1609
1746
  const trimmed = value.trim();
1610
1747
  if (!trimmed) {
1611
1748
  return trimmed;
1612
1749
  }
1613
- if (!path7.isAbsolute(trimmed)) {
1614
- return normalizePathSeparators(path7.normalize(trimmed));
1750
+ if (!path8.isAbsolute(trimmed)) {
1751
+ return normalizePathSeparators(path8.normalize(trimmed));
1615
1752
  }
1616
- const relativePath = path7.relative(baseDir, trimmed);
1617
- if (!relativePath || !relativePath.startsWith("..") && !path7.isAbsolute(relativePath)) {
1618
- return normalizePathSeparators(path7.normalize(relativePath || "."));
1753
+ const relativePath = path8.relative(baseDir, trimmed);
1754
+ if (!relativePath || !relativePath.startsWith("..") && !path8.isAbsolute(relativePath)) {
1755
+ return normalizePathSeparators(path8.normalize(relativePath || "."));
1619
1756
  }
1620
- return path7.normalize(trimmed);
1757
+ return path8.normalize(trimmed);
1621
1758
  }
1622
1759
  function resolveKnowledgeBasePath(value, projectRoot) {
1623
- return path7.isAbsolute(value) ? value : path7.resolve(projectRoot, value);
1760
+ return path8.isAbsolute(value) ? value : path8.resolve(projectRoot, value);
1624
1761
  }
1625
1762
  function normalizeKnowledgeBasePath2(value, projectRoot) {
1626
- return path7.normalize(resolveKnowledgeBasePath(value, projectRoot));
1763
+ return path8.normalize(resolveKnowledgeBasePath(value, projectRoot));
1627
1764
  }
1628
1765
  function hasMatchingKnowledgeBasePath(knowledgeBases, inputPath, projectRoot) {
1629
- const normalizedInput = path7.normalize(inputPath);
1766
+ const normalizedInput = path8.normalize(inputPath);
1630
1767
  return knowledgeBases.some((kb) => normalizeKnowledgeBasePath2(kb, projectRoot) === normalizedInput);
1631
1768
  }
1632
1769
  function findKnowledgeBasePathIndex(knowledgeBases, inputPath, projectRoot) {
1633
- const normalizedInput = path7.normalize(inputPath);
1770
+ const normalizedInput = path8.normalize(inputPath);
1634
1771
  return knowledgeBases.findIndex(
1635
- (kb) => path7.normalize(kb) === normalizedInput || normalizeKnowledgeBasePath2(kb, projectRoot) === normalizedInput
1772
+ (kb) => path8.normalize(kb) === normalizedInput || normalizeKnowledgeBasePath2(kb, projectRoot) === normalizedInput
1636
1773
  );
1637
1774
  }
1638
1775
 
@@ -2913,9 +3050,9 @@ function formatEffectivenessMetrics(snapshot) {
2913
3050
  }
2914
3051
 
2915
3052
  // src/utils/auto-index.ts
2916
- import { existsSync as existsSync7, realpathSync as realpathSync2 } from "fs";
3053
+ import { existsSync as existsSync7, realpathSync as realpathSync3 } from "fs";
2917
3054
  import * as os3 from "os";
2918
- import * as path10 from "path";
3055
+ import * as path11 from "path";
2919
3056
 
2920
3057
  // src/indexer/index-lock.ts
2921
3058
  import { randomUUID } from "crypto";
@@ -2925,13 +3062,13 @@ import {
2925
3062
  mkdirSync,
2926
3063
  readFileSync as readFileSync4,
2927
3064
  readdirSync as readdirSync2,
2928
- realpathSync,
3065
+ realpathSync as realpathSync2,
2929
3066
  renameSync,
2930
3067
  rmSync,
2931
3068
  writeFileSync
2932
3069
  } from "fs";
2933
3070
  import * as os2 from "os";
2934
- import * as path8 from "path";
3071
+ import * as path9 from "path";
2935
3072
  var OWNER_FILE_NAME = "owner.json";
2936
3073
  var RECLAIM_DIRECTORY_NAME = "reclaiming";
2937
3074
  var RECOVERY_MARKER_PREFIX = "indexing.lock.recovery.";
@@ -2988,7 +3125,7 @@ function parseReclaimOwner(value) {
2988
3125
  }
2989
3126
  function readJsonDirectory(directoryPath, parser) {
2990
3127
  try {
2991
- return parser(JSON.parse(readFileSync4(path8.join(directoryPath, OWNER_FILE_NAME), "utf-8")));
3128
+ return parser(JSON.parse(readFileSync4(path9.join(directoryPath, OWNER_FILE_NAME), "utf-8")));
2992
3129
  } catch {
2993
3130
  return null;
2994
3131
  }
@@ -3045,7 +3182,7 @@ function publishJsonDirectory(finalPath, value) {
3045
3182
  throw error;
3046
3183
  }
3047
3184
  try {
3048
- writeFileSync(path8.join(candidatePath, OWNER_FILE_NAME), JSON.stringify(value), {
3185
+ writeFileSync(path9.join(candidatePath, OWNER_FILE_NAME), JSON.stringify(value), {
3049
3186
  encoding: "utf-8",
3050
3187
  flag: "wx",
3051
3188
  mode: 384
@@ -3076,7 +3213,7 @@ function createOwner(operation) {
3076
3213
  };
3077
3214
  }
3078
3215
  function recoveryMarkerPath(indexPath, owner) {
3079
- return path8.join(indexPath, `${RECOVERY_MARKER_PREFIX}${owner.token}`);
3216
+ return path9.join(indexPath, `${RECOVERY_MARKER_PREFIX}${owner.token}`);
3080
3217
  }
3081
3218
  function publishRecoveryMarker(indexPath, owner) {
3082
3219
  const markerPath = recoveryMarkerPath(indexPath, owner);
@@ -3095,7 +3232,7 @@ function getPendingRecoveries(indexPath) {
3095
3232
  return UUID_PATTERN.test(name.slice(RECOVERY_MARKER_PREFIX.length));
3096
3233
  }).sort();
3097
3234
  for (const markerName of markerNames) {
3098
- const markerPath = path8.join(indexPath, markerName);
3235
+ const markerPath = path9.join(indexPath, markerName);
3099
3236
  const markerToken = markerName.slice(RECOVERY_MARKER_PREFIX.length);
3100
3237
  let markerStats;
3101
3238
  try {
@@ -3127,11 +3264,11 @@ function cleanupDeadPublicationCandidates(indexPath) {
3127
3264
  const pid = Number(match[1]);
3128
3265
  if (!Number.isInteger(pid) || pid <= 0) continue;
3129
3266
  if (getOwnerLiveness({ pid, hostname: os2.hostname() }) !== "dead") continue;
3130
- rmSync(path8.join(indexPath, entry), { recursive: true, force: true });
3267
+ rmSync(path9.join(indexPath, entry), { recursive: true, force: true });
3131
3268
  }
3132
3269
  }
3133
3270
  function removeDeadReclaimMarker(lockPath, expectedOwner) {
3134
- const markerPath = path8.join(lockPath, RECLAIM_DIRECTORY_NAME);
3271
+ const markerPath = path9.join(lockPath, RECLAIM_DIRECTORY_NAME);
3135
3272
  const marker = readReclaimOwner(markerPath);
3136
3273
  if (!marker || marker.expectedOwnerToken !== expectedOwner.token || getOwnerLiveness(marker) !== "dead") {
3137
3274
  return false;
@@ -3159,7 +3296,7 @@ function removeDeadReclaimMarker(lockPath, expectedOwner) {
3159
3296
  return true;
3160
3297
  }
3161
3298
  function reclaimDeadOwner(indexPath, lockPath, expectedOwner) {
3162
- const reclaimPath = path8.join(lockPath, RECLAIM_DIRECTORY_NAME);
3299
+ const reclaimPath = path9.join(lockPath, RECLAIM_DIRECTORY_NAME);
3163
3300
  const reclaimOwner = {
3164
3301
  pid: process.pid,
3165
3302
  hostname: os2.hostname(),
@@ -3216,8 +3353,8 @@ function isTransientIndexLockContention(error) {
3216
3353
  }
3217
3354
  function acquireIndexLock(indexPath, operation) {
3218
3355
  mkdirSync(indexPath, { recursive: true });
3219
- const canonicalIndexPath = realpathSync.native(indexPath);
3220
- const lockPath = path8.join(canonicalIndexPath, "indexing.lock");
3356
+ const canonicalIndexPath = realpathSync2.native(indexPath);
3357
+ const lockPath = path9.join(canonicalIndexPath, "indexing.lock");
3221
3358
  cleanupDeadPublicationCandidates(canonicalIndexPath);
3222
3359
  for (let attempt = 0; attempt < 6; attempt += 1) {
3223
3360
  const owner = createOwner(operation);
@@ -3303,7 +3440,7 @@ function recoverLeaseArtifacts(indexPath, owner, backupTargets) {
3303
3440
  const temporaryOwnerMarker = `.tmp.${owner.pid}.${owner.token}.`;
3304
3441
  for (const entry of readdirSync2(indexPath)) {
3305
3442
  if (!entry.includes(temporaryOwnerMarker)) continue;
3306
- rmSync(path8.join(indexPath, entry), { recursive: true, force: true });
3443
+ rmSync(path9.join(indexPath, entry), { recursive: true, force: true });
3307
3444
  }
3308
3445
  }
3309
3446
  function completeLeaseRecovery(lease) {
@@ -3321,7 +3458,7 @@ function completeLeaseRecovery(lease) {
3321
3458
  // src/utils/files.ts
3322
3459
  var import_ignore = __toESM(require_ignore(), 1);
3323
3460
  import { existsSync as existsSync6, readFileSync as readFileSync5, promises as fsPromises } from "fs";
3324
- import * as path9 from "path";
3461
+ import * as path10 from "path";
3325
3462
  var PROJECT_MARKERS = [
3326
3463
  ".git",
3327
3464
  "package.json",
@@ -3339,7 +3476,7 @@ var PROJECT_MARKERS = [
3339
3476
  ];
3340
3477
  function hasProjectMarker(projectRoot) {
3341
3478
  for (const marker of PROJECT_MARKERS) {
3342
- if (existsSync6(path9.join(projectRoot, marker))) {
3479
+ if (existsSync6(path10.join(projectRoot, marker))) {
3343
3480
  return true;
3344
3481
  }
3345
3482
  }
@@ -3366,7 +3503,7 @@ function createIgnoreFilter(projectRoot) {
3366
3503
  "**/*build*/**"
3367
3504
  ];
3368
3505
  ig.add(defaultIgnores);
3369
- const gitignorePath = path9.join(projectRoot, ".gitignore");
3506
+ const gitignorePath = path10.join(projectRoot, ".gitignore");
3370
3507
  if (existsSync6(gitignorePath)) {
3371
3508
  const gitignoreContent = readFileSync5(gitignorePath, "utf-8");
3372
3509
  ig.add(gitignoreContent);
@@ -3374,8 +3511,8 @@ function createIgnoreFilter(projectRoot) {
3374
3511
  return ig;
3375
3512
  }
3376
3513
  function shouldIncludeFile(filePath, projectRoot, includePatterns, excludePatterns, ignoreFilter) {
3377
- const relativePath = path9.relative(projectRoot, filePath);
3378
- if (hasFilteredPathSegment(relativePath, path9.sep)) {
3514
+ const relativePath = path10.relative(projectRoot, filePath);
3515
+ if (hasFilteredPathSegment(relativePath, path10.sep)) {
3379
3516
  return false;
3380
3517
  }
3381
3518
  if (ignoreFilter.ignores(relativePath)) {
@@ -3413,8 +3550,8 @@ async function* walkDirectory(dir, projectRoot, includePatterns, excludePatterns
3413
3550
  const filesInDir = [];
3414
3551
  const subdirs = [];
3415
3552
  for (const entry of entries) {
3416
- const fullPath = path9.join(dir, entry.name);
3417
- const relativePath = path9.relative(projectRoot, fullPath);
3553
+ const fullPath = path10.join(dir, entry.name);
3554
+ const relativePath = path10.relative(projectRoot, fullPath);
3418
3555
  if (isHiddenPathSegment(entry.name)) {
3419
3556
  if (entry.isDirectory()) {
3420
3557
  skipped.push({ path: relativePath, reason: "excluded" });
@@ -3463,7 +3600,7 @@ async function* walkDirectory(dir, projectRoot, includePatterns, excludePatterns
3463
3600
  yield f;
3464
3601
  }
3465
3602
  for (let i = options.maxFilesPerDirectory; i < filesInDir.length; i++) {
3466
- skipped.push({ path: path9.relative(projectRoot, filesInDir[i].path), reason: "excluded" });
3603
+ skipped.push({ path: path10.relative(projectRoot, filesInDir[i].path), reason: "excluded" });
3467
3604
  }
3468
3605
  const canRecurse = options.maxDepth === -1 || currentDepth < options.maxDepth;
3469
3606
  if (canRecurse) {
@@ -3503,8 +3640,8 @@ async function collectFiles(projectRoot, includePatterns, excludePatterns, maxFi
3503
3640
  if (additionalRoots && additionalRoots.length > 0) {
3504
3641
  const normalizedRoots = /* @__PURE__ */ new Set();
3505
3642
  for (const kbRoot of additionalRoots) {
3506
- const resolved = path9.normalize(
3507
- path9.isAbsolute(kbRoot) ? kbRoot : path9.resolve(projectRoot, kbRoot)
3643
+ const resolved = path10.normalize(
3644
+ path10.isAbsolute(kbRoot) ? kbRoot : path10.resolve(projectRoot, kbRoot)
3508
3645
  );
3509
3646
  normalizedRoots.add(resolved);
3510
3647
  }
@@ -3648,17 +3785,17 @@ function now() {
3648
3785
  return (/* @__PURE__ */ new Date()).toISOString();
3649
3786
  }
3650
3787
  function canonicalizePath(targetPath) {
3651
- const resolved = path10.resolve(targetPath);
3788
+ const resolved = path11.resolve(targetPath);
3652
3789
  if (existsSync7(resolved)) {
3653
3790
  try {
3654
- return realpathSync2.native(resolved);
3791
+ return realpathSync3.native(resolved);
3655
3792
  } catch {
3656
3793
  return resolved;
3657
3794
  }
3658
3795
  }
3659
- const parent = path10.dirname(resolved);
3796
+ const parent = path11.dirname(resolved);
3660
3797
  if (parent === resolved) return resolved;
3661
- return path10.join(canonicalizePath(parent), path10.basename(resolved));
3798
+ return path11.join(canonicalizePath(parent), path11.basename(resolved));
3662
3799
  }
3663
3800
  function isHomeDirectory(projectRoot) {
3664
3801
  return canonicalizePath(projectRoot) === canonicalizePath(os3.homedir());
@@ -4177,10 +4314,10 @@ function configureAutoIndex(projectRoot, host, config, getIndexer) {
4177
4314
  }
4178
4315
  coordinatorKeysByProject.set(projectKey, key);
4179
4316
  }
4180
- function startAutoIndex(projectRoot, host = "opencode", source = "startup") {
4317
+ function startAutoIndex(projectRoot, host, source = "startup") {
4181
4318
  return getCoordinator(projectRoot, host)?.start(source) ?? null;
4182
4319
  }
4183
- function requestBackgroundIndex(projectRoot, host = "opencode") {
4320
+ function requestBackgroundIndex(projectRoot, host) {
4184
4321
  return getCoordinator(projectRoot, host)?.request({
4185
4322
  checkFreshness: false,
4186
4323
  force: false,
@@ -4195,14 +4332,14 @@ function runCoordinatedIndex(projectRoot, host, force, onProgress) {
4195
4332
  source: "manual"
4196
4333
  }) ?? null;
4197
4334
  }
4198
- function getAutoIndexStatus(projectRoot, host = "opencode") {
4335
+ function getAutoIndexStatus(projectRoot, host) {
4199
4336
  return getCoordinator(projectRoot, host)?.snapshot() ?? {
4200
4337
  enabled: false,
4201
4338
  state: "idle",
4202
4339
  updatedAt: now()
4203
4340
  };
4204
4341
  }
4205
- async function waitForAutoIndexForRetrieval(projectRoot, host = "opencode") {
4342
+ async function waitForAutoIndexForRetrieval(projectRoot, host) {
4206
4343
  const coordinator = getCoordinator(projectRoot, host);
4207
4344
  if (!coordinator) return { ready: true };
4208
4345
  const initial = coordinator.snapshot();
@@ -4260,7 +4397,7 @@ async function hasReadableCurrentIndex(coordinator) {
4260
4397
 
4261
4398
  // src/tools/config-state.ts
4262
4399
  import { existsSync as existsSync8, mkdirSync as mkdirSync2, writeFileSync as writeFileSync2 } from "fs";
4263
- import * as path11 from "path";
4400
+ import * as path12 from "path";
4264
4401
  function normalizeKnowledgeBasePaths(config, projectRoot) {
4265
4402
  const normalized = { ...config };
4266
4403
  if (Array.isArray(normalized.knowledgeBases)) {
@@ -4276,19 +4413,19 @@ function toConfigRecord(rawConfig) {
4276
4413
  }
4277
4414
  return { ...rawConfig };
4278
4415
  }
4279
- function getConfigPath(projectRoot, host = "opencode") {
4416
+ function getConfigPath(projectRoot, host) {
4280
4417
  return resolveWritableProjectConfigPath(projectRoot, host);
4281
4418
  }
4282
- function loadRuntimeConfig(projectRoot, host = "opencode") {
4419
+ function loadRuntimeConfig(projectRoot, host) {
4283
4420
  return normalizeKnowledgeBasePaths(toConfigRecord(loadMergedConfig(projectRoot, host)), projectRoot);
4284
4421
  }
4285
- function loadEditableConfig(projectRoot, host = "opencode") {
4422
+ function loadEditableConfig(projectRoot, host) {
4286
4423
  return normalizeKnowledgeBasePaths(toConfigRecord(loadProjectConfigLayer(projectRoot, host)), projectRoot);
4287
4424
  }
4288
- function saveConfig(projectRoot, config, host = "opencode") {
4425
+ function saveConfig(projectRoot, config, host) {
4289
4426
  const configPath = getConfigPath(projectRoot, host);
4290
- const configDir = path11.dirname(configPath);
4291
- const configBaseDir = path11.dirname(configDir);
4427
+ const configDir = path12.dirname(configPath);
4428
+ const configBaseDir = path12.dirname(configDir);
4292
4429
  if (!existsSync8(configDir)) {
4293
4430
  mkdirSync2(configDir, { recursive: true });
4294
4431
  }
@@ -5354,10 +5491,10 @@ async function pRetry(input, options = {}) {
5354
5491
 
5355
5492
  // src/embeddings/detector.ts
5356
5493
  import { existsSync as existsSync9, readFileSync as readFileSync6 } from "fs";
5357
- import * as path12 from "path";
5494
+ import * as path13 from "path";
5358
5495
  import * as os4 from "os";
5359
5496
  function getOpenCodeAuthPath() {
5360
- return path12.join(os4.homedir(), ".local", "share", "opencode", "auth.json");
5497
+ return path13.join(os4.homedir(), ".local", "share", "opencode", "auth.json");
5361
5498
  }
5362
5499
  function loadOpenCodeAuth() {
5363
5500
  const authPath = getOpenCodeAuthPath();
@@ -6764,42 +6901,80 @@ function extractParamNames(params) {
6764
6901
 
6765
6902
  // src/native/binding.ts
6766
6903
  import * as os5 from "os";
6767
- import * as path13 from "path";
6904
+ import * as path14 from "path";
6768
6905
  import * as module from "module";
6769
6906
  import { fileURLToPath } from "url";
6770
- function getNativeBinding() {
6771
- const platform2 = os5.platform();
6772
- const arch2 = os5.arch();
6773
- let bindingName;
6907
+
6908
+ // src/identity-catalog.json
6909
+ var identity_catalog_default = {
6910
+ product: {
6911
+ current: {
6912
+ productName: "opencode-codebase-index",
6913
+ packageName: "opencode-codebase-index",
6914
+ repository: "https://github.com/Helweg/opencode-codebase-index",
6915
+ mcpBinary: "opencode-codebase-index-mcp",
6916
+ mcpServerName: "opencode-codebase-index"
6917
+ },
6918
+ future: {
6919
+ productName: "open-codebase-index",
6920
+ packageName: "open-codebase-index",
6921
+ repository: "https://github.com/Helweg/open-codebase-index",
6922
+ mcpBinary: "open-codebase-index-mcp",
6923
+ mcpServerName: "open-codebase-index"
6924
+ }
6925
+ },
6926
+ native: {
6927
+ binaryName: "codebase-index-native"
6928
+ }
6929
+ };
6930
+
6931
+ // src/identity-catalog.ts
6932
+ var IDENTITY_CATALOG = identity_catalog_default;
6933
+ var CURRENT_PRODUCT = IDENTITY_CATALOG.product.current;
6934
+ var FUTURE_PRODUCT = IDENTITY_CATALOG.product.future;
6935
+ var MCP_SERVER_CURRENT_NAME = CURRENT_PRODUCT.mcpServerName;
6936
+ var MCP_BINARY_CURRENT_NAME = CURRENT_PRODUCT.mcpBinary;
6937
+ var STABLE_NATIVE_BINARY_NAME = IDENTITY_CATALOG.native.binaryName;
6938
+
6939
+ // src/native/binding.ts
6940
+ function getNativeBindingFilename(platform2 = os5.platform(), arch2 = os5.arch()) {
6774
6941
  if (platform2 === "darwin" && arch2 === "arm64") {
6775
- bindingName = "codebase-index-native.darwin-arm64.node";
6776
- } else if (platform2 === "darwin" && arch2 === "x64") {
6777
- bindingName = "codebase-index-native.darwin-x64.node";
6778
- } else if (platform2 === "linux" && arch2 === "x64") {
6779
- bindingName = "codebase-index-native.linux-x64-gnu.node";
6780
- } else if (platform2 === "linux" && arch2 === "arm64") {
6781
- bindingName = "codebase-index-native.linux-arm64-gnu.node";
6782
- } else if (platform2 === "win32" && arch2 === "x64") {
6783
- bindingName = "codebase-index-native.win32-x64-msvc.node";
6784
- } else {
6785
- throw new Error(`Unsupported platform: ${platform2}-${arch2}`);
6942
+ return `${STABLE_NATIVE_BINARY_NAME}.darwin-arm64.node`;
6786
6943
  }
6944
+ if (platform2 === "darwin" && arch2 === "x64") {
6945
+ return `${STABLE_NATIVE_BINARY_NAME}.darwin-x64.node`;
6946
+ }
6947
+ if (platform2 === "linux" && arch2 === "x64") {
6948
+ return `${STABLE_NATIVE_BINARY_NAME}.linux-x64-gnu.node`;
6949
+ }
6950
+ if (platform2 === "linux" && arch2 === "arm64") {
6951
+ return `${STABLE_NATIVE_BINARY_NAME}.linux-arm64-gnu.node`;
6952
+ }
6953
+ if (platform2 === "win32" && arch2 === "x64") {
6954
+ return `${STABLE_NATIVE_BINARY_NAME}.win32-x64-msvc.node`;
6955
+ }
6956
+ throw new Error(`Unsupported platform: ${platform2}-${arch2}`);
6957
+ }
6958
+ function resolveNativeBindingPath(packageRoot, platform2 = os5.platform(), arch2 = os5.arch()) {
6959
+ return path14.join(packageRoot, "native", getNativeBindingFilename(platform2, arch2));
6960
+ }
6961
+ function getNativeBinding() {
6787
6962
  let currentDir;
6788
6963
  let requireTarget;
6789
6964
  if (typeof import.meta !== "undefined" && import.meta.url) {
6790
- currentDir = path13.dirname(fileURLToPath(import.meta.url));
6965
+ currentDir = path14.dirname(fileURLToPath(import.meta.url));
6791
6966
  requireTarget = import.meta.url;
6792
6967
  } else if (typeof __dirname !== "undefined") {
6793
6968
  currentDir = __dirname;
6794
6969
  requireTarget = __filename;
6795
6970
  } else {
6796
6971
  currentDir = process.cwd();
6797
- requireTarget = path13.join(currentDir, "index.js");
6972
+ requireTarget = path14.join(currentDir, "index.js");
6798
6973
  }
6799
6974
  const normalizedDir = currentDir.replace(/\\/g, "/");
6800
- const isDevMode = normalizedDir.includes("/src/native") || currentDir.includes(path13.join("src", "native"));
6801
- const packageRoot = isDevMode ? path13.resolve(currentDir, "../..") : path13.resolve(currentDir, "..");
6802
- const nativePath = path13.join(packageRoot, "native", bindingName);
6975
+ const isDevMode = normalizedDir.includes("/src/native") || currentDir.includes(path14.join("src", "native"));
6976
+ const packageRoot = isDevMode ? path14.resolve(currentDir, "../..") : path14.resolve(currentDir, "..");
6977
+ const nativePath = resolveNativeBindingPath(packageRoot);
6803
6978
  const require2 = module.createRequire(requireTarget);
6804
6979
  return require2(nativePath);
6805
6980
  }
@@ -7359,116 +7534,6 @@ import { promises as fsPromises2 } from "fs";
7359
7534
  import * as os6 from "os";
7360
7535
  import * as path15 from "path";
7361
7536
 
7362
- // src/utils/canonical-path.ts
7363
- import * as crypto from "crypto";
7364
- import * as fs from "fs";
7365
- import * as path14 from "path";
7366
-
7367
- // node_modules/unicode-case-folding/index.js
7368
- 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]]]);
7369
- function caseFold(input) {
7370
- if (typeof input !== "string") {
7371
- throw new TypeError("Input must be a string");
7372
- }
7373
- let result = [];
7374
- for (const char of input) {
7375
- const codePoint = char.codePointAt(0);
7376
- const mapping = FOLDING_MAP.get(codePoint);
7377
- result.push(mapping ? String.fromCodePoint(...mapping) : char);
7378
- }
7379
- return result.join("");
7380
- }
7381
-
7382
- // src/utils/canonical-path.ts
7383
- function alternateAsciiCase(value) {
7384
- const index = value.search(/[A-Za-z]/);
7385
- if (index === -1) return null;
7386
- const character = value[index];
7387
- const alternate = character === character.toLowerCase() ? character.toUpperCase() : character.toLowerCase();
7388
- return `${value.slice(0, index)}${alternate}${value.slice(index + 1)}`;
7389
- }
7390
- function probeEntryCaseSensitivity(entryPath) {
7391
- const alternateName = alternateAsciiCase(path14.basename(entryPath));
7392
- if (!alternateName) return void 0;
7393
- try {
7394
- const canonicalPath = fs.realpathSync.native(entryPath);
7395
- const alternatePath = fs.realpathSync.native(path14.join(path14.dirname(entryPath), alternateName));
7396
- return canonicalPath === alternatePath;
7397
- } catch (error) {
7398
- const code = error.code;
7399
- if (code === "ENOENT" || code === "ENOTDIR") return false;
7400
- return void 0;
7401
- }
7402
- }
7403
- function probeEmptyWindowsDirectory(existingAncestor) {
7404
- const probePath = path14.join(
7405
- existingAncestor,
7406
- `.codebase-index-case-probe-${crypto.randomBytes(8).toString("hex")}`
7407
- );
7408
- let created = false;
7409
- try {
7410
- const descriptor = fs.openSync(probePath, "wx", 384);
7411
- created = true;
7412
- fs.closeSync(descriptor);
7413
- return probeEntryCaseSensitivity(probePath);
7414
- } catch {
7415
- return void 0;
7416
- } finally {
7417
- if (created) fs.unlinkSync(probePath);
7418
- }
7419
- }
7420
- function detectCaseInsensitiveFileSystem(existingAncestor) {
7421
- try {
7422
- if (fs.statSync(existingAncestor).isDirectory()) {
7423
- const directory = fs.opendirSync(existingAncestor);
7424
- try {
7425
- let entry = directory.readSync();
7426
- while (entry) {
7427
- if (!entry.isSymbolicLink() && alternateAsciiCase(entry.name)) {
7428
- const result = probeEntryCaseSensitivity(path14.join(existingAncestor, entry.name));
7429
- if (result !== void 0) return result;
7430
- }
7431
- entry = directory.readSync();
7432
- }
7433
- } finally {
7434
- directory.closeSync();
7435
- }
7436
- }
7437
- } catch {
7438
- return void 0;
7439
- }
7440
- if (process.platform === "darwin") {
7441
- return probeEntryCaseSensitivity(existingAncestor);
7442
- }
7443
- if (process.platform === "win32") {
7444
- return probeEmptyWindowsDirectory(existingAncestor);
7445
- }
7446
- return void 0;
7447
- }
7448
- function foldMissingPathComponent(component) {
7449
- return caseFold(component);
7450
- }
7451
- function canonicalizePathForComparison(targetPath, options = {}) {
7452
- const resolved = path14.resolve(targetPath);
7453
- const missingParts = [];
7454
- let candidate = resolved;
7455
- while (true) {
7456
- try {
7457
- const existingAncestor = fs.realpathSync.native(candidate);
7458
- const isCaseInsensitive = missingParts.length > 0 ? (options.isCaseInsensitive ?? detectCaseInsensitiveFileSystem)(existingAncestor) : false;
7459
- const suffix = isCaseInsensitive === true ? missingParts.map(foldMissingPathComponent) : missingParts;
7460
- return path14.join(existingAncestor, ...suffix);
7461
- } catch (error) {
7462
- const code = error.code;
7463
- if (code !== "ENOENT" && code !== "ENOTDIR") throw error;
7464
- const parent = path14.dirname(candidate);
7465
- if (parent === candidate) return resolved;
7466
- missingParts.unshift(path14.basename(candidate));
7467
- candidate = parent;
7468
- }
7469
- }
7470
- }
7471
-
7472
7537
  // src/git/branch-resolution.ts
7473
7538
  import { execFile as execFile2 } from "child_process";
7474
7539
  import { randomBytes as randomBytes2 } from "crypto";
@@ -9102,6 +9167,8 @@ function hasBlameMetadata(metadata) {
9102
9167
  return blameFromMetadata(metadata) !== void 0;
9103
9168
  }
9104
9169
  var INDEX_METADATA_VERSION = "1";
9170
+ var PROJECT_PATH_STORAGE_VERSION = "2";
9171
+ var GLOBAL_PATH_STORAGE_VERSION = "1";
9105
9172
  var EMBEDDING_STRATEGY_VERSION = "2";
9106
9173
  var SWIFT_PARSER_VERSION = "1";
9107
9174
  var METAL_PARSER_VERSION = "1";
@@ -9432,18 +9499,20 @@ function selectIndexableChunks(chunks, limit, semanticOnly) {
9432
9499
  const indexableChunks = semanticOnly ? chunks.filter((chunk) => chunk.chunkType !== "other") : chunks;
9433
9500
  return selectChunksWithFileCoverage(indexableChunks, limit);
9434
9501
  }
9435
- function matchesHardSearchFilters(candidate, options) {
9502
+ function matchesHardSearchFilters(candidate, options, projectRoot) {
9436
9503
  if (options?.fileType) {
9437
9504
  const ext = candidate.metadata.filePath.split(".").pop()?.toLowerCase();
9438
9505
  const requestedExtension = options.fileType.trim().toLowerCase().replace(/^\./, "");
9439
9506
  if (ext !== requestedExtension) return false;
9440
9507
  }
9441
9508
  if (options?.directory) {
9442
- const normalizedPath = candidate.metadata.filePath.replace(/\\/g, "/");
9443
- const normalizedDir = options.directory.trim().replace(/\\/g, "/").replace(/^\.\//, "").replace(/\/$/, "");
9444
- const isAbsoluteDirectory = normalizedDir.startsWith("/");
9445
- const matchesDirectory = isAbsoluteDirectory ? normalizedPath === normalizedDir || normalizedPath.startsWith(`${normalizedDir}/`) : normalizedPath === normalizedDir || normalizedPath.startsWith(`${normalizedDir}/`) || normalizedPath.includes(`/${normalizedDir}/`) || normalizedPath.endsWith(`/${normalizedDir}`);
9446
- if (!matchesDirectory) return false;
9509
+ const candidatePath = canonicalizePathForComparison(
9510
+ path18.resolve(projectRoot, candidate.metadata.filePath.replace(/\\/g, path18.sep))
9511
+ );
9512
+ const directoryPath = canonicalizePathForComparison(
9513
+ path18.resolve(projectRoot, options.directory.trim().replace(/\\/g, path18.sep))
9514
+ );
9515
+ if (!isPathWithinRoot2(candidatePath, directoryPath)) return false;
9447
9516
  }
9448
9517
  if (options?.chunkType && candidate.metadata.chunkType !== options.chunkType) {
9449
9518
  return false;
@@ -9465,8 +9534,8 @@ function matchesHardSearchFilters(candidate, options) {
9465
9534
  }
9466
9535
  return true;
9467
9536
  }
9468
- function matchesSearchFilters(candidate, options, minScore) {
9469
- return candidate.score >= minScore && matchesHardSearchFilters(candidate, options);
9537
+ function matchesSearchFilters(candidate, options, minScore, projectRoot) {
9538
+ return candidate.score >= minScore && matchesHardSearchFilters(candidate, options, projectRoot);
9470
9539
  }
9471
9540
  function unionCandidates(semanticCandidates, keywordCandidates) {
9472
9541
  const byId = /* @__PURE__ */ new Map();
@@ -9517,7 +9586,7 @@ var Indexer = class _Indexer {
9517
9586
  readerArtifactFingerprint = null;
9518
9587
  writerArtifactFingerprint = null;
9519
9588
  readerArtifactRetryAfter = /* @__PURE__ */ new Map();
9520
- constructor(projectRoot, config, host = "opencode", runtimeOptions = {}) {
9589
+ constructor(projectRoot, config, host, runtimeOptions = {}) {
9521
9590
  this.projectRoot = projectRoot;
9522
9591
  this.projectIdentityHash = hashContent(this.getCanonicalPath(projectRoot)).slice(0, 16);
9523
9592
  this.materializedProjectRoot = runtimeOptions.materializedProjectRoot ?? projectRoot;
@@ -9530,37 +9599,90 @@ var Indexer = class _Indexer {
9530
9599
  this.indexPathOverride = runtimeOptions.indexPath;
9531
9600
  this.config = config;
9532
9601
  this.host = host;
9602
+ if (isGitRepo(this.materializedProjectRoot)) {
9603
+ this.currentBranch = this.branchNameOverride ?? getBranchOrDefault(this.materializedProjectRoot);
9604
+ this.baseBranch = getBaseBranch(this.materializedProjectRoot);
9605
+ } else {
9606
+ this.currentBranch = "default";
9607
+ this.baseBranch = "default";
9608
+ }
9533
9609
  this.indexPath = this.getIndexPath();
9534
- this.fileHashCachePath = this.getRuntimeArtifactPath("file-hashes.json");
9535
- this.failedBatchesPath = this.getRuntimeArtifactPath("failed-batches.json");
9610
+ this.refreshRuntimeArtifactPaths();
9536
9611
  this.logger = initializeLogger(config.debug);
9537
9612
  }
9538
9613
  getIndexPath() {
9539
9614
  return this.indexPathOverride ?? resolveProjectIndexPath(this.projectRoot, this.config.scope, this.host);
9540
9615
  }
9541
9616
  toCanonicalFilePath(filePath) {
9617
+ if (!path18.isAbsolute(filePath)) {
9618
+ return this.resolveStoredFilePath(filePath, this.projectRoot);
9619
+ }
9542
9620
  if (path18.resolve(this.materializedProjectRoot) === path18.resolve(this.projectRoot) || !isPathWithinRoot2(filePath, this.materializedProjectRoot)) {
9543
9621
  return filePath;
9544
9622
  }
9545
9623
  return path18.resolve(this.projectRoot, path18.relative(this.materializedProjectRoot, filePath));
9546
9624
  }
9547
- toMaterializedFilePath(filePath) {
9548
- if (path18.resolve(this.materializedProjectRoot) === path18.resolve(this.projectRoot) || !isPathWithinRoot2(filePath, this.projectRoot)) {
9625
+ toStoredFilePath(filePath) {
9626
+ const canonicalFilePath = this.toCanonicalFilePath(filePath);
9627
+ if (this.config.scope !== "project" || !isPathWithinRoot2(canonicalFilePath, this.projectRoot)) {
9628
+ return canonicalFilePath;
9629
+ }
9630
+ return path18.relative(this.projectRoot, canonicalFilePath).split(path18.sep).join("/");
9631
+ }
9632
+ resolveStoredFilePath(filePath, rootPath = this.projectRoot) {
9633
+ if (path18.isAbsolute(filePath)) {
9549
9634
  return filePath;
9550
9635
  }
9551
- return path18.resolve(this.materializedProjectRoot, path18.relative(this.projectRoot, filePath));
9636
+ const resolvedPath = path18.resolve(rootPath, ...filePath.split("/"));
9637
+ if (!isPathWithinRoot2(resolvedPath, rootPath)) {
9638
+ throw new Error(`Stored project path escapes project root: ${JSON.stringify(filePath)}`);
9639
+ }
9640
+ return resolvedPath;
9641
+ }
9642
+ getCanonicalStoredFilePath(filePath) {
9643
+ return this.getCanonicalPath(this.resolveStoredFilePath(filePath));
9644
+ }
9645
+ resolveFilePathRecord(record) {
9646
+ return {
9647
+ ...record,
9648
+ filePath: this.resolveStoredFilePath(record.filePath)
9649
+ };
9650
+ }
9651
+ resolveCallEdgeFilePath(edge) {
9652
+ if (!edge.fromSymbolFilePath) return edge;
9653
+ return {
9654
+ ...edge,
9655
+ fromSymbolFilePath: this.resolveStoredFilePath(edge.fromSymbolFilePath)
9656
+ };
9657
+ }
9658
+ toMaterializedFilePath(filePath) {
9659
+ const storedFilePath = this.toStoredFilePath(filePath);
9660
+ if (path18.isAbsolute(storedFilePath)) {
9661
+ return storedFilePath;
9662
+ }
9663
+ return this.resolveStoredFilePath(storedFilePath, this.materializedProjectRoot);
9552
9664
  }
9553
9665
  getPreparedBranchNamespace() {
9554
9666
  if (!this.branchNameOverride && !this.catalogIdentityOverride) return null;
9555
9667
  return hashContent(this.getBranchCatalogKey()).slice(0, 16);
9556
9668
  }
9669
+ getRuntimeArtifactNamespace() {
9670
+ if (this.config.scope !== "project" || this.getBranchCatalogIdentity() === "default") {
9671
+ return this.getPreparedBranchNamespace();
9672
+ }
9673
+ return hashContent(this.getBranchCatalogKey()).slice(0, 16);
9674
+ }
9557
9675
  getRuntimeArtifactPath(fileName) {
9558
- const namespace = this.getPreparedBranchNamespace();
9676
+ const namespace = this.getRuntimeArtifactNamespace();
9559
9677
  if (!namespace) return path18.join(this.indexPath, fileName);
9560
9678
  const extension = path18.extname(fileName);
9561
9679
  const baseName = fileName.slice(0, fileName.length - extension.length);
9562
9680
  return path18.join(this.indexPath, `${baseName}.${namespace}${extension}`);
9563
9681
  }
9682
+ refreshRuntimeArtifactPaths() {
9683
+ this.fileHashCachePath = this.getRuntimeArtifactPath("file-hashes.json");
9684
+ this.failedBatchesPath = this.getRuntimeArtifactPath("failed-batches.json");
9685
+ }
9564
9686
  getPreparedChunkId(chunkId) {
9565
9687
  const namespace = this.getPreparedBranchNamespace();
9566
9688
  return namespace ? `${chunkId}_${namespace}` : chunkId;
@@ -9586,19 +9708,8 @@ var Indexer = class _Indexer {
9586
9708
  return path18.resolve(targetPath);
9587
9709
  }
9588
9710
  }
9589
- isLocalProjectIndexPath() {
9590
- const localProjectIndexPaths = [path18.join(this.projectRoot, getHostProjectIndexRelativePath(this.host))];
9591
- if (this.host !== "opencode") {
9592
- localProjectIndexPaths.push(path18.join(this.projectRoot, getHostProjectIndexRelativePath("opencode")));
9593
- }
9594
- return localProjectIndexPaths.some((localPath) => {
9595
- if (!existsSync10(localPath) || !existsSync10(this.indexPath)) {
9596
- return path18.resolve(this.indexPath) === path18.resolve(localPath);
9597
- }
9598
- const indexStats = statSync4(this.indexPath);
9599
- const localStats = statSync4(localPath);
9600
- return indexStats.dev === localStats.dev && indexStats.ino === localStats.ino;
9601
- });
9711
+ isProjectOwnedIndexPath() {
9712
+ return isProjectIndexPathOwnedByProject(this.projectRoot, this.indexPath, this.host);
9602
9713
  }
9603
9714
  resetLoadedIndexState(retireDatabase = false) {
9604
9715
  if (this.database) {
@@ -9633,10 +9744,10 @@ var Indexer = class _Indexer {
9633
9744
  this.readerArtifactRetryAfter.clear();
9634
9745
  }
9635
9746
  async withIndexMutationLease(operation, callback) {
9747
+ this.refreshBranchInfo();
9636
9748
  const lease = acquireIndexLock(this.indexPath, operation);
9637
9749
  this.indexPath = lease.canonicalIndexPath;
9638
- this.fileHashCachePath = this.getRuntimeArtifactPath("file-hashes.json");
9639
- this.failedBatchesPath = this.getRuntimeArtifactPath("failed-batches.json");
9750
+ this.refreshRuntimeArtifactPaths();
9640
9751
  this.activeIndexLease = lease;
9641
9752
  let result;
9642
9753
  let callbackError;
@@ -9808,29 +9919,24 @@ var Indexer = class _Indexer {
9808
9919
  getProjectForceReembedMetadataKey() {
9809
9920
  return `index.forceReembed.${this.projectIdentityHash}`;
9810
9921
  }
9811
- getCallGraphResolutionMetadataKey() {
9812
- if (this.config.scope !== "global") {
9813
- return "index.callGraphResolutionVersion";
9814
- }
9815
- return `index.callGraphResolutionVersion.${this.projectIdentityHash}`;
9922
+ getBranchMigrationMetadataKey(prefix, catalogIdentity = this.getBranchCatalogIdentity()) {
9923
+ const branchKey = this.getBranchCatalogKeyFor(catalogIdentity);
9924
+ return `${prefix}.${hashContent(branchKey).slice(0, 24)}`;
9816
9925
  }
9817
- getSwiftParserVersionMetadataKey() {
9818
- const key = "index.parser.swiftVersion";
9819
- if (this.config.scope !== "global") {
9820
- return key;
9821
- }
9822
- return `${key}.${this.projectIdentityHash}`;
9926
+ getCallGraphResolutionMetadataKey(catalogIdentity = this.getBranchCatalogIdentity()) {
9927
+ return this.getBranchMigrationMetadataKey("index.callGraphResolutionVersion", catalogIdentity);
9823
9928
  }
9824
- getMetalParserVersionMetadataKey() {
9825
- const key = "index.parser.metalVersion";
9826
- if (this.config.scope !== "global") {
9827
- return key;
9828
- }
9829
- return `${key}.${this.projectIdentityHash}`;
9929
+ getSwiftParserVersionMetadataKey(catalogIdentity = this.getBranchCatalogIdentity()) {
9930
+ return this.getBranchMigrationMetadataKey("index.parser.swiftVersion", catalogIdentity);
9931
+ }
9932
+ getMetalParserVersionMetadataKey(catalogIdentity = this.getBranchCatalogIdentity()) {
9933
+ return this.getBranchMigrationMetadataKey("index.parser.metalVersion", catalogIdentity);
9830
9934
  }
9831
9935
  getSymbolExtractorVersionMetadataKey(catalogIdentity = this.getBranchCatalogIdentity()) {
9832
- const branchKey = this.getBranchCatalogKeyFor(catalogIdentity);
9833
- return `index.symbolExtractorVersion.${hashContent(branchKey).slice(0, 24)}`;
9936
+ return this.getBranchMigrationMetadataKey("index.symbolExtractorVersion", catalogIdentity);
9937
+ }
9938
+ areBranchMigrationVersionsCurrent(database, catalogIdentity = this.getBranchCatalogIdentity()) {
9939
+ 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;
9834
9940
  }
9835
9941
  hasProjectForceReembedPending() {
9836
9942
  return this.config.scope === "global" && this.database?.getMetadata(this.getProjectForceReembedMetadataKey()) === "true";
@@ -9965,13 +10071,14 @@ var Indexer = class _Indexer {
9965
10071
  return Array.from(keys);
9966
10072
  }
9967
10073
  isFileInCurrentScope(filePath, roots) {
9968
- if (roots.some((root) => isPathWithinRoot2(filePath, root))) return true;
9969
- const canonicalFilePath = this.getCanonicalPath(filePath);
10074
+ const canonicalFilePath = this.getCanonicalStoredFilePath(filePath);
9970
10075
  return roots.some((root) => isPathWithinRoot2(canonicalFilePath, root));
9971
10076
  }
9972
10077
  isFileInProjectRoot(filePath) {
9973
- if (isPathWithinRoot2(filePath, this.projectRoot)) return true;
9974
- return isPathWithinRoot2(this.getCanonicalPath(filePath), this.getCanonicalPath(this.projectRoot));
10078
+ return isPathWithinRoot2(
10079
+ this.getCanonicalStoredFilePath(filePath),
10080
+ this.getCanonicalPath(this.projectRoot)
10081
+ );
9975
10082
  }
9976
10083
  clearScopedFileHashCache(roots) {
9977
10084
  for (const filePath of Array.from(this.fileHashCache.keys())) {
@@ -10372,7 +10479,10 @@ var Indexer = class _Indexer {
10372
10479
  const intent = isLikelyImplementationPath2(candidate.metadata.filePath) ? "implementation" : "doc_or_test";
10373
10480
  parts.push(`intent_hint: ${intent}`);
10374
10481
  try {
10375
- const fileContent = await fsPromises3.readFile(candidate.metadata.filePath, "utf-8");
10482
+ const fileContent = await fsPromises3.readFile(
10483
+ this.toMaterializedFilePath(candidate.metadata.filePath),
10484
+ "utf-8"
10485
+ );
10376
10486
  const lines = fileContent.split("\n");
10377
10487
  const snippetStartLine = Math.max(1, candidate.metadata.startLine);
10378
10488
  const snippetEndLine = Math.min(lines.length, candidate.metadata.endLine);
@@ -10441,7 +10551,7 @@ var Indexer = class _Indexer {
10441
10551
  if (this.config.scope === "global") {
10442
10552
  return "Shared vector index could not be read. Restore or repair the complete fingerprinted shared vector artifacts; automatic reset is disabled for global scope.";
10443
10553
  }
10444
- if (!this.isLocalProjectIndexPath()) {
10554
+ if (!this.isProjectOwnedIndexPath()) {
10445
10555
  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.";
10446
10556
  }
10447
10557
  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.";
@@ -10450,7 +10560,7 @@ var Indexer = class _Indexer {
10450
10560
  if (this.config.scope === "global") {
10451
10561
  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.";
10452
10562
  }
10453
- if (!this.isLocalProjectIndexPath()) {
10563
+ if (!this.isProjectOwnedIndexPath()) {
10454
10564
  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.";
10455
10565
  }
10456
10566
  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.";
@@ -10459,10 +10569,10 @@ var Indexer = class _Indexer {
10459
10569
  if (this.config.scope === "global") {
10460
10570
  return "Shared index database could not be read. Restore or repair the shared SQLite database; automatic reset is disabled for global scope.";
10461
10571
  }
10462
- if (!this.isLocalProjectIndexPath()) {
10572
+ if (!this.isProjectOwnedIndexPath()) {
10463
10573
  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.";
10464
10574
  }
10465
- return "Index database could not be read. Run index_codebase after the active writer finishes to repair or migrate it under the writer lease.";
10575
+ 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.";
10466
10576
  }
10467
10577
  getReaderFileFingerprint(filePath, identityOnly = false) {
10468
10578
  try {
@@ -10642,7 +10752,7 @@ var Indexer = class _Indexer {
10642
10752
  const readerArtifactFingerprint = mode === "reader" ? this.captureReaderArtifactFingerprint() : null;
10643
10753
  if (mode === "writer") {
10644
10754
  await fsPromises3.mkdir(this.indexPath, { recursive: true });
10645
- if (recoveredOwners.length > 0 && this.config.scope === "project" && !this.isLocalProjectIndexPath()) {
10755
+ if (recoveredOwners.length > 0 && this.config.scope === "project" && !this.isProjectOwnedIndexPath()) {
10646
10756
  throw new Error(
10647
10757
  "Interrupted indexing recovery is unsafe while using an inherited worktree index. Run index_codebase with force=true to create a local project index boundary."
10648
10758
  );
@@ -10743,6 +10853,7 @@ var Indexer = class _Indexer {
10743
10853
  this.baseBranch = "default";
10744
10854
  this.logger.branch("debug", "Not a git repository, using default branch");
10745
10855
  }
10856
+ this.refreshRuntimeArtifactPaths();
10746
10857
  if (mode === "writer" && recoveredOwners.length > 0) {
10747
10858
  await this.recoverFromInterruptedIndexingUnlocked(recoveredOwners);
10748
10859
  }
@@ -10898,6 +11009,14 @@ var Indexer = class _Indexer {
10898
11009
  }
10899
11010
  return `Detected a corrupted local SQLite index at ${dbPath} and reset the local index. Run index_codebase to rebuild search data.`;
10900
11011
  }
11012
+ async removeProjectRuntimeStateArtifacts() {
11013
+ if (!existsSync10(this.indexPath)) return;
11014
+ const names = await fsPromises3.readdir(this.indexPath);
11015
+ const runtimeStatePattern = /^(?:file-hashes|failed-batches)(?:\.[a-f0-9]{16})?\.json$/;
11016
+ await Promise.all(
11017
+ names.filter((name) => runtimeStatePattern.test(name)).map((name) => fsPromises3.rm(path18.join(this.indexPath, name), { force: true }))
11018
+ );
11019
+ }
10901
11020
  async resetLocalIndexArtifacts() {
10902
11021
  this.store = null;
10903
11022
  this.invertedIndex = null;
@@ -10917,11 +11036,10 @@ var Indexer = class _Indexer {
10917
11036
  path18.join(this.indexPath, "vectors"),
10918
11037
  path18.join(this.indexPath, "vectors.usearch"),
10919
11038
  path18.join(this.indexPath, "vectors.meta.json"),
10920
- path18.join(this.indexPath, "inverted-index.json"),
10921
- path18.join(this.indexPath, "file-hashes.json"),
10922
- path18.join(this.indexPath, "failed-batches.json")
11039
+ path18.join(this.indexPath, "inverted-index.json")
10923
11040
  ];
10924
11041
  await Promise.all(resetPaths.map((targetPath) => fsPromises3.rm(targetPath, { recursive: true, force: true })));
11042
+ await this.removeProjectRuntimeStateArtifacts();
10925
11043
  await fsPromises3.mkdir(this.indexPath, { recursive: true });
10926
11044
  }
10927
11045
  async tryResetCorruptedIndex(stage, error) {
@@ -10971,12 +11089,20 @@ var Indexer = class _Indexer {
10971
11089
  }
10972
11090
  this.database.addChunksToBranchBatch(this.getBranchCatalogKey(), chunkIds);
10973
11091
  }
11092
+ getExpectedPathStorageVersion() {
11093
+ return this.config.scope === "project" ? PROJECT_PATH_STORAGE_VERSION : GLOBAL_PATH_STORAGE_VERSION;
11094
+ }
11095
+ hasStoredIndexData() {
11096
+ const stats = this.database?.getStats();
11097
+ return (this.store?.count() ?? 0) > 0 || (stats?.chunkCount ?? 0) > 0 || (stats?.symbolCount ?? 0) > 0 || this.fileHashCache.size > 0;
11098
+ }
10974
11099
  loadIndexMetadata() {
10975
11100
  if (!this.database) return null;
10976
11101
  const version = this.database.getMetadata("index.version");
10977
11102
  if (!version) return null;
10978
11103
  return {
10979
11104
  indexVersion: version,
11105
+ pathStorageVersion: this.database.getMetadata("index.pathStorageVersion") ?? GLOBAL_PATH_STORAGE_VERSION,
10980
11106
  embeddingProvider: this.database.getMetadata("index.embeddingProvider") ?? "",
10981
11107
  embeddingModel: this.database.getMetadata("index.embeddingModel") ?? "",
10982
11108
  embeddingDimensions: parseInt(this.database.getMetadata("index.embeddingDimensions") ?? "0", 10),
@@ -10991,6 +11117,7 @@ var Indexer = class _Indexer {
10991
11117
  const existingCreatedAt = this.database.getMetadata("index.createdAt");
10992
11118
  const completeProjectEmbeddingStrategyReset = !this.hasProjectForceReembedPending();
10993
11119
  this.database.setMetadata("index.version", INDEX_METADATA_VERSION);
11120
+ this.database.setMetadata("index.pathStorageVersion", this.getExpectedPathStorageVersion());
10994
11121
  this.database.setMetadata("index.embeddingProvider", provider.provider);
10995
11122
  this.database.setMetadata("index.embeddingModel", provider.modelInfo.model);
10996
11123
  this.database.setMetadata("index.embeddingDimensions", provider.modelInfo.dimensions.toString());
@@ -11013,6 +11140,16 @@ var Indexer = class _Indexer {
11013
11140
  }
11014
11141
  validateIndexCompatibility(provider) {
11015
11142
  const storedMetadata = this.loadIndexMetadata();
11143
+ const storedPathStorageVersion = this.database?.getMetadata("index.pathStorageVersion") ?? GLOBAL_PATH_STORAGE_VERSION;
11144
+ const expectedPathStorageVersion = this.getExpectedPathStorageVersion();
11145
+ if (this.hasStoredIndexData() && storedPathStorageVersion !== expectedPathStorageVersion) {
11146
+ return {
11147
+ compatible: false,
11148
+ code: "PATH_STORAGE_MISMATCH" /* PATH_STORAGE_MISMATCH */,
11149
+ 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.`,
11150
+ storedMetadata: storedMetadata ?? void 0
11151
+ };
11152
+ }
11016
11153
  if (!storedMetadata) {
11017
11154
  return { compatible: true };
11018
11155
  }
@@ -11064,6 +11201,7 @@ var Indexer = class _Indexer {
11064
11201
  return this.indexCompatibility;
11065
11202
  }
11066
11203
  async ensureInitialized() {
11204
+ this.refreshBranchInfo();
11067
11205
  let initializedReader = false;
11068
11206
  while (true) {
11069
11207
  if (this.initializationPromise) {
@@ -11171,8 +11309,8 @@ var Indexer = class _Indexer {
11171
11309
  }
11172
11310
  const branchKey = this.getBranchCatalogKey();
11173
11311
  const alreadyIndexed = database.getBranchChunkIds(branchKey).length > 0 && database.getBranchSymbolIds(branchKey).length > 0;
11174
- const symbolsCurrent = database.getMetadata(this.getSymbolExtractorVersionMetadataKey()) === SYMBOL_EXTRACTOR_VERSION;
11175
- if (alreadyIndexed && symbolsCurrent && this.getStoredBranchCommit(database) === normalizedCommit) {
11312
+ const migrationsCurrent = this.areBranchMigrationVersionsCurrent(database);
11313
+ if (alreadyIndexed && migrationsCurrent && this.getStoredBranchCommit(database) === normalizedCommit) {
11176
11314
  return { prepared: false };
11177
11315
  }
11178
11316
  const stats = await this.indexUnlocked(onProgress, [], true);
@@ -11266,21 +11404,21 @@ var Indexer = class _Indexer {
11266
11404
  const currentFileHashes = /* @__PURE__ */ new Map();
11267
11405
  const needsCallGraphResolutionMigration = database.getMetadata(this.getCallGraphResolutionMetadataKey()) !== CALL_GRAPH_RESOLUTION_VERSION;
11268
11406
  for (const f of files) {
11269
- const canonicalPath = this.toCanonicalFilePath(f.path);
11407
+ const storedPath = this.toStoredFilePath(f.path);
11270
11408
  const currentHash = hashFile(f.path);
11271
- currentFileHashes.set(canonicalPath, currentHash);
11272
- const cachedHashMatches = this.fileHashCache.get(canonicalPath) === currentHash;
11273
- const needsCallGraphRefresh = cachedHashMatches && needsCallGraphResolutionMigration && database.getChunksByFile(canonicalPath).some(
11409
+ currentFileHashes.set(storedPath, currentHash);
11410
+ const cachedHashMatches = this.fileHashCache.get(storedPath) === currentHash;
11411
+ const needsCallGraphRefresh = cachedHashMatches && needsCallGraphResolutionMigration && database.getChunksByFile(storedPath).some(
11274
11412
  (chunk) => chunk.language === "php" || chunk.language === "c" || chunk.language === "cpp"
11275
11413
  );
11276
- const requiresSwiftParserUpgrade = reparseCachedSwiftFiles && path18.extname(canonicalPath).toLowerCase() === ".swift";
11277
- const requiresMetalParserUpgrade = reparseCachedMetalFiles && path18.extname(canonicalPath).toLowerCase() === ".metal";
11414
+ const requiresSwiftParserUpgrade = reparseCachedSwiftFiles && path18.extname(storedPath).toLowerCase() === ".swift";
11415
+ const requiresMetalParserUpgrade = reparseCachedMetalFiles && path18.extname(storedPath).toLowerCase() === ".metal";
11278
11416
  if (cachedHashMatches && !needsCallGraphRefresh && !requiresSwiftParserUpgrade && !requiresMetalParserUpgrade && !refreshCachedSymbols) {
11279
- unchangedFilePaths.add(canonicalPath);
11417
+ unchangedFilePaths.add(storedPath);
11280
11418
  this.logger.recordCacheHit();
11281
11419
  } else {
11282
11420
  const content = await fsPromises3.readFile(f.path, "utf-8");
11283
- changedFiles.push({ path: canonicalPath, content, hash: currentHash });
11421
+ changedFiles.push({ path: storedPath, content, hash: currentHash });
11284
11422
  this.logger.recordCacheMiss();
11285
11423
  }
11286
11424
  }
@@ -11385,8 +11523,7 @@ var Indexer = class _Indexer {
11385
11523
  for (const parsed of parsedFiles) {
11386
11524
  currentFilePaths.add(parsed.path);
11387
11525
  if (parsed.chunks.length === 0) {
11388
- const relativePath = path18.relative(this.projectRoot, parsed.path);
11389
- stats.parseFailures.push(relativePath);
11526
+ stats.parseFailures.push(path18.isAbsolute(parsed.path) ? path18.relative(this.projectRoot, parsed.path) : parsed.path);
11390
11527
  }
11391
11528
  let chunksToProcess = parsed.chunks;
11392
11529
  if (this.config.indexing.fallbackToTextOnMaxChunks && chunksToProcess.length > this.config.indexing.maxChunksPerFile) {
@@ -12027,6 +12164,43 @@ var Indexer = class _Indexer {
12027
12164
  const union = a.size + b.size - intersection;
12028
12165
  return intersection / union;
12029
12166
  }
12167
+ getBranchPrefilterState(database, branchChunkIds) {
12168
+ const hasInitializedBranchCatalog = branchChunkIds !== null && database.getAllBranches().length > 0;
12169
+ return {
12170
+ hasInitializedBranchCatalog,
12171
+ shouldPrefilterByBranch: branchChunkIds !== null && (this.config.scope === "global" || hasInitializedBranchCatalog)
12172
+ };
12173
+ }
12174
+ searchCandidatesWithBranchPrefilter(initialLimit, totalCount, branchChunkIds, shouldPrefilterByBranch, search, getChunkId) {
12175
+ const normalizedLimit = Math.max(0, Math.floor(initialLimit));
12176
+ if (normalizedLimit === 0) return [];
12177
+ if (!shouldPrefilterByBranch || !branchChunkIds) {
12178
+ return search(normalizedLimit);
12179
+ }
12180
+ const targetCount = Math.min(normalizedLimit, branchChunkIds.size);
12181
+ if (targetCount === 0 || totalCount === 0) return [];
12182
+ let requestedLimit = Math.min(normalizedLimit, totalCount);
12183
+ while (true) {
12184
+ const results = search(requestedLimit);
12185
+ const branchResults = results.filter((candidate) => branchChunkIds.has(getChunkId(candidate)));
12186
+ if (branchResults.length >= targetCount || results.length < requestedLimit || requestedLimit >= totalCount) {
12187
+ return branchResults;
12188
+ }
12189
+ const nextLimit = Math.min(totalCount, Math.max(requestedLimit + 1, requestedLimit * 2));
12190
+ if (nextLimit === requestedLimit) return branchResults;
12191
+ requestedLimit = nextLimit;
12192
+ }
12193
+ }
12194
+ searchSemanticCandidates(store, embedding, initialLimit, branchChunkIds, shouldPrefilterByBranch) {
12195
+ return this.searchCandidatesWithBranchPrefilter(
12196
+ initialLimit,
12197
+ store.count(),
12198
+ branchChunkIds,
12199
+ shouldPrefilterByBranch,
12200
+ (requestedLimit) => store.search(embedding, requestedLimit),
12201
+ (candidate) => candidate.id
12202
+ );
12203
+ }
12030
12204
  async search(query, limit, options) {
12031
12205
  const { store, provider, invertedIndex, database, readIssues, compatibility } = await this.ensureInitialized();
12032
12206
  this.requireReadableComponents(readIssues, "vectors", "database");
@@ -12071,12 +12245,7 @@ var Indexer = class _Indexer {
12071
12245
  });
12072
12246
  }
12073
12247
  const embeddingMs = performance2.now() - embeddingStartTime;
12074
- const vectorStartTime = performance2.now();
12075
- const semanticResults = embedding ? store.search(embedding, maxResults * 4) : [];
12076
- const vectorMs = performance2.now() - vectorStartTime;
12077
- const keywordStartTime = performance2.now();
12078
- const keywordResults = await this.keywordSearch(query, maxResults * 4, store, invertedIndex);
12079
- const keywordMs = performance2.now() - keywordStartTime;
12248
+ const prefilterStartTime = performance2.now();
12080
12249
  let branchChunkIds = null;
12081
12250
  let branchSymbolIds = null;
12082
12251
  if (filterByBranch && (this.config.scope === "global" || this.currentBranch !== "default")) {
@@ -12084,35 +12253,38 @@ var Indexer = class _Indexer {
12084
12253
  branchChunkIds = new Set(branchCatalogKeys.flatMap((branchKey) => database.getBranchChunkIds(branchKey)));
12085
12254
  branchSymbolIds = new Set(branchCatalogKeys.flatMap((branchKey) => database.getBranchSymbolIds(branchKey)));
12086
12255
  }
12087
- const prefilterStartTime = performance2.now();
12088
- const shouldPrefilterByBranch = branchChunkIds !== null && (this.config.scope === "global" || branchChunkIds.size > 0);
12089
- const allowBranchPrefilterFallback = this.config.scope !== "global";
12090
- const prefilteredSemantic = shouldPrefilterByBranch && branchChunkIds ? semanticResults.filter((r) => branchChunkIds.has(r.id)) : semanticResults;
12091
- const prefilteredKeyword = shouldPrefilterByBranch && branchChunkIds ? keywordResults.filter((r) => branchChunkIds.has(r.id)) : keywordResults;
12092
- const semanticCandidates = allowBranchPrefilterFallback && shouldPrefilterByBranch && semanticResults.length > 0 && prefilteredSemantic.length === 0 ? semanticResults : prefilteredSemantic;
12093
- const keywordCandidates = allowBranchPrefilterFallback && shouldPrefilterByBranch && keywordResults.length > 0 && prefilteredKeyword.length === 0 ? keywordResults : prefilteredKeyword;
12256
+ const { hasInitializedBranchCatalog, shouldPrefilterByBranch } = this.getBranchPrefilterState(database, branchChunkIds);
12257
+ const prefilterMs = performance2.now() - prefilterStartTime;
12258
+ const vectorStartTime = performance2.now();
12259
+ const semanticCandidates = embedding ? this.searchSemanticCandidates(
12260
+ store,
12261
+ embedding,
12262
+ maxResults * 4,
12263
+ branchChunkIds,
12264
+ shouldPrefilterByBranch
12265
+ ) : [];
12266
+ const vectorMs = performance2.now() - vectorStartTime;
12267
+ const keywordStartTime = performance2.now();
12268
+ const keywordCandidates = await this.keywordSearch(
12269
+ query,
12270
+ maxResults * 4,
12271
+ store,
12272
+ invertedIndex,
12273
+ branchChunkIds,
12274
+ shouldPrefilterByBranch
12275
+ );
12276
+ const keywordMs = performance2.now() - keywordStartTime;
12094
12277
  const scopedSemanticCandidates = semanticCandidates.filter(
12095
- (candidate) => matchesHardSearchFilters(candidate, options)
12278
+ (candidate) => matchesHardSearchFilters(candidate, options, this.projectRoot)
12096
12279
  );
12097
12280
  const scopedKeywordCandidates = keywordCandidates.filter(
12098
- (candidate) => matchesHardSearchFilters(candidate, options)
12281
+ (candidate) => matchesHardSearchFilters(candidate, options, this.projectRoot)
12099
12282
  );
12100
- const prefilterMs = performance2.now() - prefilterStartTime;
12101
- if (this.config.scope !== "global" && branchChunkIds && branchChunkIds.size === 0) {
12283
+ if (this.config.scope !== "global" && branchChunkIds && !hasInitializedBranchCatalog) {
12102
12284
  this.logger.search("warn", "Branch prefilter skipped because branch catalog is empty", {
12103
12285
  branch: this.currentBranch
12104
12286
  });
12105
12287
  }
12106
- if (allowBranchPrefilterFallback && shouldPrefilterByBranch && semanticResults.length > 0 && prefilteredSemantic.length === 0) {
12107
- this.logger.search("warn", "Branch prefilter produced no semantic overlap, using unfiltered semantic candidates", {
12108
- branch: this.currentBranch
12109
- });
12110
- }
12111
- if (allowBranchPrefilterFallback && shouldPrefilterByBranch && keywordResults.length > 0 && prefilteredKeyword.length === 0) {
12112
- this.logger.search("warn", "Branch prefilter produced no keyword overlap, using unfiltered keyword candidates", {
12113
- branch: this.currentBranch
12114
- });
12115
- }
12116
12288
  const fusionStartTime = performance2.now();
12117
12289
  const rankingHybridWeight = embedding === void 0 && fusionStrategy === "weighted" ? 1 : effectiveHybridWeight;
12118
12290
  const combined = rankHybridResults(query, scopedSemanticCandidates, scopedKeywordCandidates, {
@@ -12163,12 +12335,14 @@ var Indexer = class _Indexer {
12163
12335
  const primaryLane = mergeTieredResults(prePrimaryLane, symbolLane, maxResults * 4);
12164
12336
  const tiered = mergeTieredResults(primaryLane, rescued, maxResults * 4);
12165
12337
  const hasCodeHints = extractCodeTermHints(query).length > 0 || identifierHints.length > 0;
12166
- const baseFiltered = tiered.filter((r) => matchesSearchFilters(r, options, this.config.search.minScore));
12338
+ const baseFiltered = tiered.filter(
12339
+ (r) => matchesSearchFilters(r, options, this.config.search.minScore, this.projectRoot)
12340
+ );
12167
12341
  const implementationOnly = baseFiltered.filter(
12168
12342
  (r) => isLikelyImplementationPath2(r.metadata.filePath) && isImplementationChunkType(r.metadata.chunkType)
12169
12343
  );
12170
12344
  const filtered = (sourceIntent && hasCodeHints && implementationOnly.length > 0 ? implementationOnly : baseFiltered).slice(0, maxResults);
12171
- 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) : [];
12345
+ 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) : [];
12172
12346
  const finalResults = filtered.length > 0 ? filtered : identifierFallback;
12173
12347
  const totalSearchMs = performance2.now() - searchStartTime;
12174
12348
  this.logger.recordSearch(totalSearchMs, {
@@ -12193,10 +12367,11 @@ var Indexer = class _Indexer {
12193
12367
  let content = "";
12194
12368
  let contextStartLine = r.metadata.startLine;
12195
12369
  let contextEndLine = r.metadata.endLine;
12370
+ const resolvedFilePath = this.resolveStoredFilePath(r.metadata.filePath);
12196
12371
  if (!metadataOnly && this.config.search.includeContext) {
12197
12372
  try {
12198
12373
  const fileContent = await fsPromises3.readFile(
12199
- r.metadata.filePath,
12374
+ resolvedFilePath,
12200
12375
  "utf-8"
12201
12376
  );
12202
12377
  const lines = fileContent.split("\n");
@@ -12209,7 +12384,7 @@ var Indexer = class _Indexer {
12209
12384
  }
12210
12385
  }
12211
12386
  return {
12212
- filePath: r.metadata.filePath,
12387
+ filePath: resolvedFilePath,
12213
12388
  startLine: contextStartLine,
12214
12389
  endLine: contextEndLine,
12215
12390
  content,
@@ -12221,8 +12396,18 @@ var Indexer = class _Indexer {
12221
12396
  })
12222
12397
  );
12223
12398
  }
12224
- async keywordSearch(query, limit, store, invertedIndex) {
12225
- const scores = invertedIndex.search(query);
12399
+ async keywordSearch(query, limit, store, invertedIndex, branchChunkIds = null, shouldPrefilterByBranch = false) {
12400
+ const normalizedLimit = Math.max(0, Math.floor(limit));
12401
+ if (normalizedLimit === 0) return [];
12402
+ const scoreEntries = this.searchCandidatesWithBranchPrefilter(
12403
+ normalizedLimit,
12404
+ invertedIndex.getDocumentCount(),
12405
+ branchChunkIds,
12406
+ shouldPrefilterByBranch,
12407
+ (requestedLimit) => Array.from(invertedIndex.search(query, requestedLimit)),
12408
+ ([chunkId]) => chunkId
12409
+ );
12410
+ const scores = new Map(scoreEntries);
12226
12411
  if (scores.size === 0) {
12227
12412
  return [];
12228
12413
  }
@@ -12236,7 +12421,7 @@ var Indexer = class _Indexer {
12236
12421
  }
12237
12422
  }
12238
12423
  results.sort((a, b) => b.score - a.score);
12239
- return results.slice(0, limit);
12424
+ return results.slice(0, normalizedLimit);
12240
12425
  }
12241
12426
  async getStatus() {
12242
12427
  const { store, configuredProviderInfo, database, readIssues, compatibility } = await this.ensureInitialized();
@@ -12303,7 +12488,7 @@ var Indexer = class _Indexer {
12303
12488
  );
12304
12489
  const currentFileHashes = /* @__PURE__ */ new Map();
12305
12490
  for (const file of files) {
12306
- currentFileHashes.set(this.toCanonicalFilePath(file.path), hashFile(file.path));
12491
+ currentFileHashes.set(this.toStoredFilePath(file.path), hashFile(file.path));
12307
12492
  }
12308
12493
  const scopedRoots = this.config.scope === "global" ? this.getScopedRoots() : null;
12309
12494
  const cachedFileHashes = scopedRoots ? new Map(Array.from(this.fileHashCache).filter(([filePath]) => this.isFileInCurrentScope(filePath, scopedRoots))) : this.fileHashCache;
@@ -12315,17 +12500,7 @@ var Indexer = class _Indexer {
12315
12500
  return { readable: true, current: false, reason: "files-changed" };
12316
12501
  }
12317
12502
  }
12318
- const hasSwiftFiles = Array.from(currentFileHashes.keys()).some(
12319
- (filePath) => path18.extname(filePath).toLowerCase() === ".swift"
12320
- );
12321
- const hasMetalFiles = Array.from(currentFileHashes.keys()).some(
12322
- (filePath) => path18.extname(filePath).toLowerCase() === ".metal"
12323
- );
12324
- const hasCallGraphMigrationFiles = Array.from(currentFileHashes.keys()).some((filePath) => {
12325
- const extension = path18.extname(filePath).toLowerCase();
12326
- return extension === ".php" || extension === ".c" || extension === ".cc" || extension === ".cpp" || extension === ".cxx";
12327
- });
12328
- 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) {
12503
+ if (!this.areBranchMigrationVersionsCurrent(database)) {
12329
12504
  return { readable: true, current: false, reason: "migration-required" };
12330
12505
  }
12331
12506
  if (isGitRepo(this.materializedProjectRoot)) {
@@ -12385,6 +12560,7 @@ var Indexer = class _Indexer {
12385
12560
  this.deleteBranchCommitMetadata(database, clearedBranchKeys2);
12386
12561
  this.saveFailedBatches([]);
12387
12562
  database.deleteMetadata("index.version");
12563
+ database.deleteMetadata("index.pathStorageVersion");
12388
12564
  database.deleteMetadata("index.embeddingProvider");
12389
12565
  database.deleteMetadata("index.embeddingModel");
12390
12566
  database.deleteMetadata("index.embeddingDimensions");
@@ -12403,7 +12579,7 @@ var Indexer = class _Indexer {
12403
12579
  this.indexCompatibility = compatibility;
12404
12580
  return;
12405
12581
  }
12406
- if (!this.isLocalProjectIndexPath()) {
12582
+ if (!this.isProjectOwnedIndexPath()) {
12407
12583
  throw new Error(
12408
12584
  "Project-scoped force rebuild is unsafe while using an inherited worktree index. Create a local project config boundary before clearing the index."
12409
12585
  );
@@ -12414,11 +12590,11 @@ var Indexer = class _Indexer {
12414
12590
  invertedIndex.clear();
12415
12591
  this.saveInvertedIndex(invertedIndex);
12416
12592
  this.fileHashCache.clear();
12417
- this.saveFileHashCache();
12593
+ await this.removeProjectRuntimeStateArtifacts();
12418
12594
  database.clearAllIndexedData();
12419
12595
  this.deleteBranchCommitMetadata(database, clearedBranchKeys);
12420
- this.saveFailedBatches([]);
12421
12596
  database.deleteMetadata("index.version");
12597
+ database.deleteMetadata("index.pathStorageVersion");
12422
12598
  database.deleteMetadata("index.embeddingProvider");
12423
12599
  database.deleteMetadata("index.embeddingModel");
12424
12600
  database.deleteMetadata("index.embeddingDimensions");
@@ -12446,32 +12622,46 @@ var Indexer = class _Indexer {
12446
12622
  existing.push(key);
12447
12623
  filePathsToChunkKeys.set(metadata.filePath, existing);
12448
12624
  }
12449
- const removedFilePaths = [];
12450
- const removedChunkKeys = [];
12625
+ const missingStoredFilePaths = [];
12626
+ const missingChunkKeys = [];
12451
12627
  const chunkKeysByRemovedFile = /* @__PURE__ */ new Map();
12452
12628
  for (const [filePath, chunkKeys] of filePathsToChunkKeys) {
12453
- if (!existsSync10(filePath)) {
12629
+ if (!existsSync10(this.toMaterializedFilePath(filePath))) {
12454
12630
  chunkKeysByRemovedFile.set(filePath, chunkKeys);
12455
12631
  for (const key of chunkKeys) {
12456
- removedChunkKeys.push(key);
12632
+ missingChunkKeys.push(key);
12457
12633
  }
12458
- removedFilePaths.push(filePath);
12634
+ missingStoredFilePaths.push(filePath);
12459
12635
  }
12460
12636
  }
12637
+ const branchCatalogKeys = this.getBranchCatalogKeys();
12638
+ for (const branchKey of branchCatalogKeys) {
12639
+ database.deleteBranchChunksForBranch(branchKey, missingChunkKeys);
12640
+ }
12641
+ const referencedChunkKeys = new Set(database.getReferencedChunkIds(missingChunkKeys));
12642
+ const removedChunkKeys = missingChunkKeys.filter((key) => !referencedChunkKeys.has(key));
12461
12643
  if (removedChunkKeys.length > 0) {
12462
12644
  this.rebuildVectorStoreExcludingChunkIds(store, database, removedChunkKeys);
12463
12645
  for (const key of removedChunkKeys) {
12464
12646
  invertedIndex.removeChunk(key);
12465
12647
  }
12648
+ database.deleteChunksByIds(removedChunkKeys);
12466
12649
  }
12467
- for (const filePath of removedFilePaths) {
12468
- const fileChunkKeys = chunkKeysByRemovedFile.get(filePath) ?? [];
12469
- if (fileChunkKeys.length > 0) {
12470
- database.deleteChunksByIds(fileChunkKeys);
12471
- }
12472
- database.deleteCallEdgesByFile(filePath);
12473
- database.deleteSymbolsByFile(filePath);
12474
- }
12650
+ const missingSymbolIds = Array.from(new Set(
12651
+ missingStoredFilePaths.flatMap(
12652
+ (filePath) => database.getSymbolsByFile(filePath).map((symbol) => symbol.id)
12653
+ )
12654
+ ));
12655
+ for (const branchKey of branchCatalogKeys) {
12656
+ database.deleteBranchSymbolsForBranch(branchKey, missingSymbolIds);
12657
+ }
12658
+ const referencedSymbolIds = new Set(database.getReferencedSymbolIds(missingSymbolIds));
12659
+ const removedSymbolIds = missingSymbolIds.filter((symbolId) => !referencedSymbolIds.has(symbolId));
12660
+ database.clearCallEdgeTargetsForSymbols(removedSymbolIds);
12661
+ const removedChunkKeySet = new Set(removedChunkKeys);
12662
+ const removedStoredFilePaths = missingStoredFilePaths.filter(
12663
+ (filePath) => (chunkKeysByRemovedFile.get(filePath) ?? []).some((key) => removedChunkKeySet.has(key))
12664
+ );
12475
12665
  const removedCount = removedChunkKeys.length;
12476
12666
  if (removedCount > 0) {
12477
12667
  store.save();
@@ -12507,9 +12697,16 @@ var Indexer = class _Indexer {
12507
12697
  removedStale: removedCount,
12508
12698
  orphanEmbeddings: gcOrphanEmbeddings,
12509
12699
  orphanChunks: gcOrphanChunks,
12510
- removedFiles: removedFilePaths.length
12700
+ removedFiles: removedStoredFilePaths.length
12511
12701
  });
12512
- return { removed: removedCount, filePaths: removedFilePaths, gcOrphanEmbeddings, gcOrphanChunks, gcOrphanSymbols, gcOrphanCallEdges };
12702
+ return {
12703
+ removed: removedCount,
12704
+ filePaths: removedStoredFilePaths.map((filePath) => this.resolveStoredFilePath(filePath)),
12705
+ gcOrphanEmbeddings,
12706
+ gcOrphanChunks,
12707
+ gcOrphanSymbols,
12708
+ gcOrphanCallEdges
12709
+ };
12513
12710
  }
12514
12711
  async retryFailedBatches() {
12515
12712
  return this.withIndexMutationLease("retry-failed-batches", async (recoveredOwners) => {
@@ -12704,9 +12901,18 @@ var Indexer = class _Indexer {
12704
12901
  return this.baseBranch;
12705
12902
  }
12706
12903
  refreshBranchInfo() {
12904
+ const previousBranch = this.currentBranch;
12707
12905
  if (isGitRepo(this.materializedProjectRoot)) {
12708
12906
  this.currentBranch = this.branchNameOverride ?? getBranchOrDefault(this.materializedProjectRoot);
12709
12907
  this.baseBranch = getBaseBranch(this.materializedProjectRoot);
12908
+ } else {
12909
+ this.currentBranch = "default";
12910
+ this.baseBranch = "default";
12911
+ }
12912
+ if (this.currentBranch !== previousBranch) {
12913
+ this.refreshRuntimeArtifactPaths();
12914
+ this.fileHashCache.clear();
12915
+ this.loadFileHashCache();
12710
12916
  }
12711
12917
  }
12712
12918
  async getDatabaseStats() {
@@ -12731,6 +12937,7 @@ var Indexer = class _Indexer {
12731
12937
  return [];
12732
12938
  }
12733
12939
  const filterByBranch = options?.filterByBranch ?? true;
12940
+ const excludedStoredFile = options?.excludeFile ? this.toStoredFilePath(options.excludeFile) : void 0;
12734
12941
  this.logger.search("debug", "Starting find similar", {
12735
12942
  codeLength: code.length,
12736
12943
  limit,
@@ -12740,31 +12947,29 @@ var Indexer = class _Indexer {
12740
12947
  const { embedding, tokensUsed } = await provider.embedDocument(code);
12741
12948
  const embeddingMs = performance2.now() - embeddingStartTime;
12742
12949
  this.logger.recordEmbeddingApiCall(tokensUsed);
12743
- const vectorStartTime = performance2.now();
12744
- const semanticResults = store.search(embedding, limit * 2);
12745
- const vectorMs = performance2.now() - vectorStartTime;
12950
+ const prefilterStartTime = performance2.now();
12746
12951
  let branchChunkIds = null;
12747
12952
  if (filterByBranch && (this.config.scope === "global" || this.currentBranch !== "default")) {
12748
12953
  branchChunkIds = new Set(
12749
12954
  this.getBranchCatalogKeys().flatMap((branchKey) => database.getBranchChunkIds(branchKey))
12750
12955
  );
12751
12956
  }
12752
- const prefilterStartTime = performance2.now();
12753
- const shouldPrefilterByBranch = branchChunkIds !== null && (this.config.scope === "global" || branchChunkIds.size > 0);
12754
- const allowBranchPrefilterFallback = this.config.scope !== "global";
12755
- const prefilteredSemantic = shouldPrefilterByBranch && branchChunkIds ? semanticResults.filter((r) => branchChunkIds.has(r.id)) : semanticResults;
12756
- const semanticCandidates = allowBranchPrefilterFallback && shouldPrefilterByBranch && semanticResults.length > 0 && prefilteredSemantic.length === 0 ? semanticResults : prefilteredSemantic;
12957
+ const { hasInitializedBranchCatalog, shouldPrefilterByBranch } = this.getBranchPrefilterState(database, branchChunkIds);
12757
12958
  const prefilterMs = performance2.now() - prefilterStartTime;
12758
- if (this.config.scope !== "global" && branchChunkIds && branchChunkIds.size === 0) {
12959
+ const vectorStartTime = performance2.now();
12960
+ const semanticCandidates = this.searchSemanticCandidates(
12961
+ store,
12962
+ embedding,
12963
+ limit * 2,
12964
+ branchChunkIds,
12965
+ shouldPrefilterByBranch
12966
+ );
12967
+ const vectorMs = performance2.now() - vectorStartTime;
12968
+ if (this.config.scope !== "global" && branchChunkIds && !hasInitializedBranchCatalog) {
12759
12969
  this.logger.search("warn", "Branch prefilter skipped because branch catalog is empty", {
12760
12970
  branch: this.currentBranch
12761
12971
  });
12762
12972
  }
12763
- if (allowBranchPrefilterFallback && shouldPrefilterByBranch && semanticResults.length > 0 && prefilteredSemantic.length === 0) {
12764
- this.logger.search("warn", "Branch prefilter produced no semantic overlap, using unfiltered semantic candidates", {
12765
- branch: this.currentBranch
12766
- });
12767
- }
12768
12973
  const rerankTopN = this.config.search.rerankTopN;
12769
12974
  const ranked = rankSemanticOnlyResults(code, semanticCandidates, {
12770
12975
  rerankTopN,
@@ -12773,21 +12978,10 @@ var Indexer = class _Indexer {
12773
12978
  });
12774
12979
  const filtered = ranked.filter((r) => {
12775
12980
  if (r.score < this.config.search.minScore) return false;
12776
- if (options?.excludeFile) {
12777
- if (r.metadata.filePath === options.excludeFile) return false;
12778
- }
12779
- if (options?.fileType) {
12780
- const ext = r.metadata.filePath.split(".").pop()?.toLowerCase();
12781
- if (ext !== options.fileType.toLowerCase().replace(/^\./, "")) return false;
12981
+ if (excludedStoredFile) {
12982
+ if (r.metadata.filePath === excludedStoredFile) return false;
12782
12983
  }
12783
- if (options?.directory) {
12784
- const normalizedDir = options.directory.replace(/^\/|\/$/g, "");
12785
- if (!r.metadata.filePath.includes(`/${normalizedDir}/`) && !r.metadata.filePath.includes(`${normalizedDir}/`)) return false;
12786
- }
12787
- if (options?.chunkType) {
12788
- if (r.metadata.chunkType !== options.chunkType) return false;
12789
- }
12790
- return true;
12984
+ return matchesHardSearchFilters(r, options, this.projectRoot);
12791
12985
  }).slice(0, limit);
12792
12986
  const totalSearchMs = performance2.now() - searchStartTime;
12793
12987
  this.logger.recordSearch(totalSearchMs, {
@@ -12807,10 +13001,11 @@ var Indexer = class _Indexer {
12807
13001
  return Promise.all(
12808
13002
  filtered.map(async (r) => {
12809
13003
  let content = "";
13004
+ const resolvedFilePath = this.resolveStoredFilePath(r.metadata.filePath);
12810
13005
  if (this.config.search.includeContext) {
12811
13006
  try {
12812
13007
  const fileContent = await fsPromises3.readFile(
12813
- r.metadata.filePath,
13008
+ resolvedFilePath,
12814
13009
  "utf-8"
12815
13010
  );
12816
13011
  const lines = fileContent.split("\n");
@@ -12820,7 +13015,7 @@ var Indexer = class _Indexer {
12820
13015
  }
12821
13016
  }
12822
13017
  return {
12823
- filePath: r.metadata.filePath,
13018
+ filePath: resolvedFilePath,
12824
13019
  startLine: r.metadata.startLine,
12825
13020
  endLine: r.metadata.endLine,
12826
13021
  content,
@@ -12841,7 +13036,7 @@ var Indexer = class _Indexer {
12841
13036
  for (const edge of database.getCallersWithContext(targetName, branchKey, callTypeFilter)) {
12842
13037
  if (!seen.has(edge.id)) {
12843
13038
  seen.add(edge.id);
12844
- results.push(edge);
13039
+ results.push(this.resolveCallEdgeFilePath(edge));
12845
13040
  }
12846
13041
  }
12847
13042
  }
@@ -12860,7 +13055,7 @@ var Indexer = class _Indexer {
12860
13055
  const safelyMatchesUnresolvedSymbol = includeUnresolved && !edge.toSymbolId;
12861
13056
  if (!matchesResolvedSymbol && !safelyMatchesUnresolvedSymbol || seen.has(edge.id)) continue;
12862
13057
  seen.add(edge.id);
12863
- results.push(edge);
13058
+ results.push(this.resolveCallEdgeFilePath(edge));
12864
13059
  }
12865
13060
  }
12866
13061
  return results;
@@ -12874,7 +13069,7 @@ var Indexer = class _Indexer {
12874
13069
  for (const edge of database.getCallees(symbolId, branchKey, callTypeFilter)) {
12875
13070
  if (!seen.has(edge.id)) {
12876
13071
  seen.add(edge.id);
12877
- results.push(edge);
13072
+ results.push(this.resolveCallEdgeFilePath(edge));
12878
13073
  }
12879
13074
  }
12880
13075
  }
@@ -12890,7 +13085,7 @@ var Indexer = class _Indexer {
12890
13085
  shortest = path27;
12891
13086
  }
12892
13087
  }
12893
- return shortest;
13088
+ return shortest.map((hop) => this.resolveFilePathRecord(hop));
12894
13089
  }
12895
13090
  async findCallPathBySymbolIds(fromSymbolId, toSymbolId, maxDepth = 10) {
12896
13091
  const { database, readIssues } = await this.ensureInitialized();
@@ -12956,7 +13151,7 @@ var Indexer = class _Indexer {
12956
13151
  shortest = path27;
12957
13152
  }
12958
13153
  }
12959
- return shortest;
13154
+ return shortest.map((hop) => this.resolveFilePathRecord(hop));
12960
13155
  }
12961
13156
  async getCallGraphSymbols() {
12962
13157
  const { database, readIssues } = await this.ensureInitialized();
@@ -12964,7 +13159,7 @@ var Indexer = class _Indexer {
12964
13159
  const symbols = /* @__PURE__ */ new Map();
12965
13160
  for (const branchKey of this.getBranchCatalogKeys()) {
12966
13161
  for (const symbol of database.getSymbolsForBranch(branchKey)) {
12967
- symbols.set(symbol.id, symbol);
13162
+ symbols.set(symbol.id, this.resolveFilePathRecord(symbol));
12968
13163
  }
12969
13164
  }
12970
13165
  return [...symbols.values()];
@@ -12973,31 +13168,32 @@ var Indexer = class _Indexer {
12973
13168
  const { database, readIssues } = await this.ensureInitialized();
12974
13169
  this.requireReadableComponents(readIssues, "database");
12975
13170
  const resolvedBranch = branch ?? this.getBranchCatalogKey();
12976
- return database.getSymbolsForBranch(resolvedBranch);
13171
+ return database.getSymbolsForBranch(resolvedBranch).map((symbol) => this.resolveFilePathRecord(symbol));
12977
13172
  }
12978
13173
  async getSymbolsForFiles(filePaths, branch) {
12979
13174
  const { database, readIssues } = await this.ensureInitialized();
12980
13175
  this.requireReadableComponents(readIssues, "database");
12981
13176
  const resolvedBranch = branch ?? this.getBranchCatalogKey();
12982
- return database.getSymbolsForFiles(filePaths, resolvedBranch);
13177
+ const storedFilePaths = filePaths.map((filePath) => this.toStoredFilePath(filePath));
13178
+ return database.getSymbolsForFiles(storedFilePaths, resolvedBranch).map((symbol) => this.resolveFilePathRecord(symbol));
12983
13179
  }
12984
13180
  async getTransitiveReachability(rootSymbolIds, direction, maxDepth) {
12985
13181
  const { database, readIssues } = await this.ensureInitialized();
12986
13182
  this.requireReadableComponents(readIssues, "database");
12987
13183
  const branch = this.getBranchCatalogKey();
12988
- return database.getTransitiveReachability(rootSymbolIds, branch, direction, maxDepth);
13184
+ return database.getTransitiveReachability(rootSymbolIds, branch, direction, maxDepth).map((entry) => this.resolveFilePathRecord(entry));
12989
13185
  }
12990
13186
  async detectCommunities(branch, symbolIds) {
12991
13187
  const { database, readIssues } = await this.ensureInitialized();
12992
13188
  this.requireReadableComponents(readIssues, "database");
12993
13189
  const resolvedBranch = branch ?? this.getBranchCatalogKey();
12994
- return database.detectCommunities(resolvedBranch, symbolIds);
13190
+ return database.detectCommunities(resolvedBranch, symbolIds).map((entry) => this.resolveFilePathRecord(entry));
12995
13191
  }
12996
13192
  async computeCentrality(branch) {
12997
13193
  const { database, readIssues } = await this.ensureInitialized();
12998
13194
  this.requireReadableComponents(readIssues, "database");
12999
13195
  const resolvedBranch = branch ?? this.getBranchCatalogKey();
13000
- return database.computeCentrality(resolvedBranch);
13196
+ return database.computeCentrality(resolvedBranch).map((entry) => this.resolveFilePathRecord(entry));
13001
13197
  }
13002
13198
  async getPrImpact(opts, onPreparationProgress) {
13003
13199
  const initialState = await this.ensureInitialized();
@@ -13033,10 +13229,8 @@ var Indexer = class _Indexer {
13033
13229
  const requestedRef = opts.pr !== void 0 ? expectedCommit : headRefName ?? resolvedBranch;
13034
13230
  const storedCommit = this.getStoredBranchCommit(database, catalogIdentity);
13035
13231
  const catalogIdentityMatches = storedCommit === expectedCommit;
13036
- const symbolsCurrent = database.getMetadata(
13037
- this.getSymbolExtractorVersionMetadataKey(catalogIdentity)
13038
- ) === SYMBOL_EXTRACTOR_VERSION;
13039
- if (branchSymbols.length === 0 || !catalogIdentityMatches || !symbolsCurrent) {
13232
+ const migrationsCurrent = this.areBranchMigrationVersionsCurrent(database, catalogIdentity);
13233
+ if (branchSymbols.length === 0 || !catalogIdentityMatches || !migrationsCurrent) {
13040
13234
  if (!resolvedBranch || resolvedBranch === "default") {
13041
13235
  throw new Error("Run index_codebase first to build the call graph and symbol index for this project.");
13042
13236
  }
@@ -13092,8 +13286,9 @@ var Indexer = class _Indexer {
13092
13286
  );
13093
13287
  }
13094
13288
  }
13095
- const absoluteChangedFiles = changedFiles.map((f) => path18.resolve(this.projectRoot, f));
13096
- const directSymbols = database.getSymbolsForFiles(absoluteChangedFiles, branchKey);
13289
+ const toStoredChangedFiles = (filePaths) => filePaths.map((filePath) => this.toStoredFilePath(path18.resolve(this.projectRoot, filePath)));
13290
+ const storedChangedFiles = toStoredChangedFiles(changedFiles);
13291
+ const directSymbols = database.getSymbolsForFiles(storedChangedFiles, branchKey);
13097
13292
  const directIds = directSymbols.map((s) => s.id);
13098
13293
  const direction = opts.direction ?? "both";
13099
13294
  const maxDepth = opts.maxDepth ?? 5;
@@ -13135,7 +13330,7 @@ var Indexer = class _Indexer {
13135
13330
  id: c.symbolId,
13136
13331
  name: c.symbolName,
13137
13332
  callerCount: c.callerCount,
13138
- filePath: c.filePath
13333
+ filePath: this.resolveStoredFilePath(c.filePath)
13139
13334
  }));
13140
13335
  const totalAffected = allAffectedIds.length;
13141
13336
  let riskLevel;
@@ -13175,9 +13370,9 @@ var Indexer = class _Indexer {
13175
13370
  projectRoot: this.projectRoot,
13176
13371
  baseBranch: this.baseBranch
13177
13372
  });
13178
- const otherAbsolute = otherChanged.files.map((f) => path18.resolve(this.projectRoot, f));
13373
+ const otherStored = toStoredChangedFiles(otherChanged.files);
13179
13374
  const prBranchKey = this.getBranchCatalogKeyFor(otherChanged.catalogIdentity);
13180
- const otherSymbols = database.getSymbolsForFiles(otherAbsolute, prBranchKey);
13375
+ const otherSymbols = database.getSymbolsForFiles(otherStored, prBranchKey);
13181
13376
  const otherLabels = /* @__PURE__ */ new Set();
13182
13377
  for (const sym of otherSymbols) {
13183
13378
  const label = symbolToCommunity.get(structuralKey(sym.filePath, sym.name));
@@ -13208,12 +13403,12 @@ var Indexer = class _Indexer {
13208
13403
  id: s.id,
13209
13404
  name: s.name,
13210
13405
  kind: s.kind,
13211
- filePath: s.filePath
13406
+ filePath: this.resolveStoredFilePath(s.filePath)
13212
13407
  })),
13213
13408
  transitiveCallers: transitiveCallers.map((c) => ({
13214
13409
  id: c.symbolId,
13215
13410
  name: c.symbolName,
13216
- filePath: c.filePath,
13411
+ filePath: this.resolveStoredFilePath(c.filePath),
13217
13412
  depth: c.depth
13218
13413
  })),
13219
13414
  totalAffected,
@@ -13243,7 +13438,7 @@ var Indexer = class _Indexer {
13243
13438
  const absoluteDirectoryFilter = directory ? path18.resolve(this.projectRoot, directory) : void 0;
13244
13439
  for (const filePath of filePaths) {
13245
13440
  if (directory) {
13246
- const absoluteFilePath = path18.resolve(filePath);
13441
+ const absoluteFilePath = this.resolveStoredFilePath(filePath);
13247
13442
  const matchesRelative = filePath === directory || filePath.startsWith(directory + "/");
13248
13443
  const matchesProjectRelative = absoluteDirectoryFilter !== void 0 && (absoluteFilePath === absoluteDirectoryFilter || absoluteFilePath.startsWith(absoluteDirectoryFilter + path18.sep));
13249
13444
  if (!matchesRelative && !matchesProjectRelative) {
@@ -13252,14 +13447,14 @@ var Indexer = class _Indexer {
13252
13447
  }
13253
13448
  for (const sym of database.getSymbolsByFile(filePath)) {
13254
13449
  if (symbolIdSet.has(sym.id) && !seenSymbols.has(sym.id)) {
13255
- seenSymbols.set(sym.id, sym);
13450
+ seenSymbols.set(sym.id, this.resolveFilePathRecord(sym));
13256
13451
  }
13257
13452
  }
13258
13453
  }
13259
13454
  for (const symbolId of seenSymbols.keys()) {
13260
13455
  for (const edge of database.getCallees(symbolId, branchKey)) {
13261
13456
  if (!seenEdges.has(edge.id)) {
13262
- seenEdges.set(edge.id, edge);
13457
+ seenEdges.set(edge.id, this.resolveCallEdgeFilePath(edge));
13263
13458
  }
13264
13459
  }
13265
13460
  }
@@ -13366,14 +13561,14 @@ function getOrCreateIndexer(projectRoot, host) {
13366
13561
  configureAutoIndex(projectRoot, host, config, () => getOrCreateIndexer(projectRoot, host));
13367
13562
  return indexer;
13368
13563
  }
13369
- function initializeTools(projectRoot, config, host = "opencode") {
13564
+ function initializeTools(projectRoot, config, host) {
13370
13565
  defaultProjectRoots.set(host, projectRoot);
13371
13566
  const key = getIndexerCacheKey(projectRoot, host);
13372
13567
  configCache.set(key, config);
13373
13568
  indexerCache.set(key, new Indexer(projectRoot, config, host));
13374
13569
  configureAutoIndex(projectRoot, host, config, () => getOrCreateIndexer(projectRoot, host));
13375
13570
  }
13376
- function getIndexerForProject(projectRoot, host = "opencode") {
13571
+ function getIndexerForProject(projectRoot, host) {
13377
13572
  const root = getProjectRoot(projectRoot, host);
13378
13573
  return getOrCreateIndexer(root, host);
13379
13574
  }
@@ -13381,7 +13576,7 @@ function recordToolEffectiveness(projectRoot, host, event) {
13381
13576
  if (!isToolEffectivenessEnabled(projectRoot, host)) return;
13382
13577
  safelyRecordToolEffectiveness(event);
13383
13578
  }
13384
- function refreshIndexerForDirectory(projectRoot, host = "opencode", config = parseConfig(loadRuntimeConfig(projectRoot, host))) {
13579
+ function refreshIndexerForDirectory(projectRoot, host, config = parseConfig(loadRuntimeConfig(projectRoot, host))) {
13385
13580
  const key = getIndexerCacheKey(projectRoot, host);
13386
13581
  configCache.set(key, config);
13387
13582
  indexerCache.set(key, new Indexer(projectRoot, config, host));
@@ -13889,6 +14084,9 @@ Run /index to rebuild the index without the removed knowledge base.`;
13889
14084
  return result;
13890
14085
  }
13891
14086
 
14087
+ // src/watcher/file-watcher.ts
14088
+ import { existsSync as existsSync12 } from "fs";
14089
+
13892
14090
  // node_modules/chokidar/index.js
13893
14091
  import { EventEmitter as EventEmitter2 } from "events";
13894
14092
  import { stat as statcb, Stats } from "fs";
@@ -14056,10 +14254,10 @@ var ReaddirpStream = class extends Readable {
14056
14254
  }
14057
14255
  async _formatEntry(dirent, path27) {
14058
14256
  let entry;
14059
- const basename7 = this._isDirent ? dirent.name : dirent;
14257
+ const basename8 = this._isDirent ? dirent.name : dirent;
14060
14258
  try {
14061
- const fullPath = presolve(pjoin(path27, basename7));
14062
- entry = { path: prelative(this._root, fullPath), fullPath, basename: basename7 };
14259
+ const fullPath = presolve(pjoin(path27, basename8));
14260
+ entry = { path: prelative(this._root, fullPath), fullPath, basename: basename8 };
14063
14261
  entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
14064
14262
  } catch (err) {
14065
14263
  this._onError(err);
@@ -14600,9 +14798,9 @@ var NodeFsHandler = class {
14600
14798
  _watchWithNodeFs(path27, listener) {
14601
14799
  const opts = this.fsw.options;
14602
14800
  const directory = sp.dirname(path27);
14603
- const basename7 = sp.basename(path27);
14801
+ const basename8 = sp.basename(path27);
14604
14802
  const parent = this.fsw._getWatchedDir(directory);
14605
- parent.add(basename7);
14803
+ parent.add(basename8);
14606
14804
  const absolutePath = sp.resolve(path27);
14607
14805
  const options = {
14608
14806
  persistent: opts.persistent
@@ -14612,7 +14810,7 @@ var NodeFsHandler = class {
14612
14810
  let closer;
14613
14811
  if (opts.usePolling) {
14614
14812
  const enableBin = opts.interval !== opts.binaryInterval;
14615
- options.interval = enableBin && isBinaryPath(basename7) ? opts.binaryInterval : opts.interval;
14813
+ options.interval = enableBin && isBinaryPath(basename8) ? opts.binaryInterval : opts.interval;
14616
14814
  closer = setFsWatchFileListener(path27, absolutePath, options, {
14617
14815
  listener,
14618
14816
  rawEmitter: this.fsw._emitRaw
@@ -14634,11 +14832,11 @@ var NodeFsHandler = class {
14634
14832
  if (this.fsw.closed) {
14635
14833
  return;
14636
14834
  }
14637
- const dirname13 = sp.dirname(file);
14638
- const basename7 = sp.basename(file);
14639
- const parent = this.fsw._getWatchedDir(dirname13);
14835
+ const dirname14 = sp.dirname(file);
14836
+ const basename8 = sp.basename(file);
14837
+ const parent = this.fsw._getWatchedDir(dirname14);
14640
14838
  let prevStats = stats;
14641
- if (parent.has(basename7))
14839
+ if (parent.has(basename8))
14642
14840
  return;
14643
14841
  const listener = async (path27, newStats) => {
14644
14842
  if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5))
@@ -14663,9 +14861,9 @@ var NodeFsHandler = class {
14663
14861
  prevStats = newStats2;
14664
14862
  }
14665
14863
  } catch (error) {
14666
- this.fsw._remove(dirname13, basename7);
14864
+ this.fsw._remove(dirname14, basename8);
14667
14865
  }
14668
- } else if (parent.has(basename7)) {
14866
+ } else if (parent.has(basename8)) {
14669
14867
  const at = newStats.atimeMs;
14670
14868
  const mt = newStats.mtimeMs;
14671
14869
  if (!at || at <= mt || mt !== prevStats.mtimeMs) {
@@ -15627,8 +15825,8 @@ var FileWatcher = class {
15627
15825
  watcher = null;
15628
15826
  projectRoot;
15629
15827
  config;
15630
- host;
15631
15828
  configPath;
15829
+ projectConfigPaths;
15632
15830
  pendingChanges = /* @__PURE__ */ new Map();
15633
15831
  debounceTimer = null;
15634
15832
  debounceMs = 1e3;
@@ -15637,11 +15835,11 @@ var FileWatcher = class {
15637
15835
  resolveReady = null;
15638
15836
  pollingFallbackAttempted = false;
15639
15837
  pendingClose = null;
15640
- constructor(projectRoot, config, host = "opencode", options = {}) {
15838
+ constructor(projectRoot, config, host, options = {}) {
15641
15839
  this.projectRoot = projectRoot;
15642
15840
  this.config = config;
15643
- this.host = host;
15644
15841
  this.configPath = options.configPath;
15842
+ this.projectConfigPaths = options.configPath ? [options.configPath] : getProjectConfigCandidatePaths(projectRoot, host);
15645
15843
  }
15646
15844
  start(handler) {
15647
15845
  if (this.watcher) {
@@ -15659,7 +15857,19 @@ var FileWatcher = class {
15659
15857
  }
15660
15858
  createWatcher(usePolling = false) {
15661
15859
  const ignoreFilter = createIgnoreFilter(this.projectRoot);
15662
- const watchTargets = this.configPath ? [this.projectRoot, this.configPath] : this.projectRoot;
15860
+ let watchTargets = this.projectRoot;
15861
+ if (this.configPath) {
15862
+ watchTargets = [this.projectRoot, this.configPath];
15863
+ } else {
15864
+ const externalConfigTargets = this.projectConfigPaths.filter((projectConfigPath) => {
15865
+ const relativeConfigPath = path20.relative(this.projectRoot, projectConfigPath);
15866
+ return this.isOutsideProjectPath(relativeConfigPath);
15867
+ }).map((projectConfigPath) => existsSync12(projectConfigPath) ? projectConfigPath : this.getNearestExistingDirectory(path20.dirname(projectConfigPath)));
15868
+ const uniqueExternalConfigTargets = [...new Set(externalConfigTargets)];
15869
+ if (uniqueExternalConfigTargets.length > 0) {
15870
+ watchTargets = [this.projectRoot, ...uniqueExternalConfigTargets];
15871
+ }
15872
+ }
15663
15873
  const watcherOptions = {
15664
15874
  ignored: (filePath) => {
15665
15875
  const relativePath = path20.relative(this.projectRoot, filePath);
@@ -15667,6 +15877,9 @@ var FileWatcher = class {
15667
15877
  if (this.isProjectConfigPathOrAncestor(relativePath)) {
15668
15878
  return false;
15669
15879
  }
15880
+ if (this.isOutsideProjectPath(relativePath)) {
15881
+ return true;
15882
+ }
15670
15883
  if (hasFilteredPathSegment(relativePath, path20.sep)) {
15671
15884
  return true;
15672
15885
  }
@@ -15769,14 +15982,22 @@ var FileWatcher = class {
15769
15982
  (configPath) => configPath === normalizedRelativePath || configPath.startsWith(`${normalizedRelativePath}${path20.sep}`)
15770
15983
  );
15771
15984
  }
15772
- getProjectConfigRelativePaths() {
15773
- if (this.configPath) {
15774
- return [path20.normalize(path20.relative(this.projectRoot, this.configPath))];
15985
+ isOutsideProjectPath(relativePath) {
15986
+ return relativePath === ".." || relativePath.startsWith(`..${path20.sep}`) || path20.isAbsolute(relativePath);
15987
+ }
15988
+ getNearestExistingDirectory(directoryPath) {
15989
+ let candidate = directoryPath;
15990
+ while (!existsSync12(candidate)) {
15991
+ const parent = path20.dirname(candidate);
15992
+ if (parent === candidate) break;
15993
+ candidate = parent;
15775
15994
  }
15776
- return [
15777
- resolveProjectConfigPath(this.projectRoot, this.host),
15778
- resolveWritableProjectConfigPath(this.projectRoot, this.host)
15779
- ].map((configPath) => path20.normalize(path20.relative(this.projectRoot, configPath)));
15995
+ return candidate;
15996
+ }
15997
+ getProjectConfigRelativePaths() {
15998
+ return this.projectConfigPaths.map(
15999
+ (configPath) => path20.normalize(path20.relative(this.projectRoot, configPath))
16000
+ );
15780
16001
  }
15781
16002
  scheduleFlush() {
15782
16003
  if (this.debounceTimer) {
@@ -15903,8 +16124,9 @@ var GitHeadWatcher = class {
15903
16124
  };
15904
16125
 
15905
16126
  // src/watcher/index.ts
15906
- function createWatcherWithIndexer(getIndexer, projectRoot, config, host = "opencode", options = {}) {
16127
+ function createWatcherWithIndexer(getIndexer, projectRoot, config, host, options = {}) {
15907
16128
  const fileWatcher = new FileWatcher(projectRoot, config, host, options);
16129
+ const configPaths = getConfigPaths(projectRoot, host, options);
15908
16130
  configureAutoIndex(projectRoot, host, parseConfig(config), getIndexer);
15909
16131
  let stopped = false;
15910
16132
  const requestReindex = () => {
@@ -15921,7 +16143,6 @@ function createWatcherWithIndexer(getIndexer, projectRoot, config, host = "openc
15921
16143
  );
15922
16144
  const hasDelete = changes.some((c) => c.type === "unlink");
15923
16145
  if (hasAddOrChange || hasDelete) {
15924
- const configPaths = getConfigPaths(projectRoot, host, options);
15925
16146
  if (changes.some((change) => configPaths.includes(pathNormalize(change.path)))) {
15926
16147
  const parsedConfig = options.configPath ? parseConfig(loadConfigFile(options.configPath)) : void 0;
15927
16148
  const refreshedConfig = refreshIndexerForDirectory(projectRoot, host, parsedConfig);
@@ -15936,7 +16157,9 @@ function createWatcherWithIndexer(getIndexer, projectRoot, config, host = "openc
15936
16157
  if (isGitRepo(projectRoot)) {
15937
16158
  gitWatcher = new GitHeadWatcher(projectRoot);
15938
16159
  gitWatcher.start(async (oldBranch, newBranch) => {
15939
- getIndexer().getLogger().branch("info", "Branch changed", {
16160
+ const indexer = getIndexer();
16161
+ indexer.refreshBranchInfo();
16162
+ indexer.getLogger().branch("info", "Branch changed", {
15940
16163
  oldBranch,
15941
16164
  newBranch
15942
16165
  });
@@ -15962,10 +16185,9 @@ function getConfigPaths(projectRoot, host, options) {
15962
16185
  if (options.configPath) {
15963
16186
  return [pathNormalize(options.configPath)];
15964
16187
  }
15965
- return [
15966
- resolveProjectConfigPath(projectRoot, host),
15967
- resolveWritableProjectConfigPath(projectRoot, host)
15968
- ].map((configPath) => pathNormalize(configPath));
16188
+ return getProjectConfigCandidatePaths(projectRoot, host).map(
16189
+ (configPath) => pathNormalize(configPath)
16190
+ );
15969
16191
  }
15970
16192
 
15971
16193
  // node_modules/@opencode-ai/plugin/dist/tool.js
@@ -16057,7 +16279,7 @@ function formatPrImpact(result) {
16057
16279
  return lines.join("\n");
16058
16280
  }
16059
16281
 
16060
- // src/tools/pr-impact.ts
16282
+ // src/adapters/opencode/pr-impact.ts
16061
16283
  var z2 = tool.schema;
16062
16284
  var AUTOMATIC_PREPARATION_POLICY = "Uses configured maxFileSize, maxChunksPerFile, maxDepth, and maxFilesPerDirectory guards. No separate aggregate token or cost ceiling is configured; maxDepth=-1 remains unlimited.";
16063
16285
  var pr_impact = tool({
@@ -16754,7 +16976,7 @@ async function executeCallGraphPath(projectRoot, host, args) {
16754
16976
  return { text: formatCallGraphPathResult(path27) };
16755
16977
  }
16756
16978
 
16757
- // src/tools/index.ts
16979
+ // src/adapters/opencode/tools.ts
16758
16980
  import { writeFileSync as writeFileSync4 } from "fs";
16759
16981
  import * as os7 from "os";
16760
16982
  import * as path24 from "path";
@@ -17462,7 +17684,7 @@ function transformForVisualization(symbols, edges, options = {}) {
17462
17684
  };
17463
17685
  }
17464
17686
 
17465
- // src/tools/index.ts
17687
+ // src/adapters/opencode/tools.ts
17466
17688
  var z3 = tool.schema;
17467
17689
  var DEFAULT_HOST = "opencode";
17468
17690
  var CHUNK_TYPE_VALUES = CHUNK_TYPES;
@@ -17729,8 +17951,84 @@ var index_visualize = tool({
17729
17951
  }
17730
17952
  });
17731
17953
 
17954
+ // src/tools/tool-names.ts
17955
+ var TOOL_NAME = {
17956
+ CODEBASE_CONTEXT: "codebase_context",
17957
+ CODEBASE_SEARCH: "codebase_search",
17958
+ CODEBASE_PEEK: "codebase_peek",
17959
+ FIND_SIMILAR: "find_similar",
17960
+ IMPLEMENTATION_LOOKUP: "implementation_lookup",
17961
+ INDEX_CODEBASE: "index_codebase",
17962
+ INDEX_STATUS: "index_status",
17963
+ INDEX_HEALTH_CHECK: "index_health_check",
17964
+ INDEX_METRICS: "index_metrics",
17965
+ INDEX_LOGS: "index_logs",
17966
+ CALL_GRAPH: "call_graph",
17967
+ CALL_GRAPH_PATH: "call_graph_path",
17968
+ PR_IMPACT: "pr_impact",
17969
+ ADD_KNOWLEDGE_BASE: "add_knowledge_base",
17970
+ LIST_KNOWLEDGE_BASES: "list_knowledge_bases",
17971
+ REMOVE_KNOWLEDGE_BASE: "remove_knowledge_base",
17972
+ PI_KNOWLEDGE_BASE_ADD: "knowledge_base_add",
17973
+ PI_KNOWLEDGE_BASE_LIST: "knowledge_base_list",
17974
+ PI_KNOWLEDGE_BASE_REMOVE: "knowledge_base_remove",
17975
+ INDEX_VISUALIZE: "index_visualize"
17976
+ };
17977
+ var PORTABLE_TOOL_NAMES = [
17978
+ TOOL_NAME.CODEBASE_CONTEXT,
17979
+ TOOL_NAME.CODEBASE_SEARCH,
17980
+ TOOL_NAME.CODEBASE_PEEK,
17981
+ TOOL_NAME.INDEX_CODEBASE,
17982
+ TOOL_NAME.INDEX_STATUS,
17983
+ TOOL_NAME.INDEX_HEALTH_CHECK,
17984
+ TOOL_NAME.INDEX_METRICS,
17985
+ TOOL_NAME.INDEX_LOGS,
17986
+ TOOL_NAME.FIND_SIMILAR,
17987
+ TOOL_NAME.IMPLEMENTATION_LOOKUP,
17988
+ TOOL_NAME.CALL_GRAPH,
17989
+ TOOL_NAME.CALL_GRAPH_PATH,
17990
+ TOOL_NAME.PR_IMPACT
17991
+ ];
17992
+ var OPENCODE_TOOL_NAMES = [
17993
+ TOOL_NAME.CODEBASE_CONTEXT,
17994
+ TOOL_NAME.CODEBASE_SEARCH,
17995
+ TOOL_NAME.CODEBASE_PEEK,
17996
+ TOOL_NAME.INDEX_CODEBASE,
17997
+ TOOL_NAME.INDEX_STATUS,
17998
+ TOOL_NAME.INDEX_HEALTH_CHECK,
17999
+ TOOL_NAME.INDEX_METRICS,
18000
+ TOOL_NAME.INDEX_LOGS,
18001
+ TOOL_NAME.FIND_SIMILAR,
18002
+ TOOL_NAME.CALL_GRAPH,
18003
+ TOOL_NAME.CALL_GRAPH_PATH,
18004
+ TOOL_NAME.IMPLEMENTATION_LOOKUP,
18005
+ TOOL_NAME.ADD_KNOWLEDGE_BASE,
18006
+ TOOL_NAME.LIST_KNOWLEDGE_BASES,
18007
+ TOOL_NAME.REMOVE_KNOWLEDGE_BASE,
18008
+ TOOL_NAME.PR_IMPACT,
18009
+ TOOL_NAME.INDEX_VISUALIZE
18010
+ ];
18011
+ var PI_TOOL_NAMES = [
18012
+ TOOL_NAME.CODEBASE_CONTEXT,
18013
+ TOOL_NAME.CODEBASE_SEARCH,
18014
+ TOOL_NAME.CODEBASE_PEEK,
18015
+ TOOL_NAME.FIND_SIMILAR,
18016
+ TOOL_NAME.IMPLEMENTATION_LOOKUP,
18017
+ TOOL_NAME.INDEX_CODEBASE,
18018
+ TOOL_NAME.INDEX_STATUS,
18019
+ TOOL_NAME.INDEX_HEALTH_CHECK,
18020
+ TOOL_NAME.INDEX_METRICS,
18021
+ TOOL_NAME.INDEX_LOGS,
18022
+ TOOL_NAME.CALL_GRAPH,
18023
+ TOOL_NAME.CALL_GRAPH_PATH,
18024
+ TOOL_NAME.PR_IMPACT,
18025
+ TOOL_NAME.PI_KNOWLEDGE_BASE_LIST,
18026
+ TOOL_NAME.PI_KNOWLEDGE_BASE_ADD,
18027
+ TOOL_NAME.PI_KNOWLEDGE_BASE_REMOVE
18028
+ ];
18029
+
17732
18030
  // src/commands/loader.ts
17733
- import { existsSync as existsSync12, readdirSync as readdirSync3, readFileSync as readFileSync8 } from "fs";
18031
+ import { existsSync as existsSync13, readdirSync as readdirSync3, readFileSync as readFileSync8 } from "fs";
17734
18032
  import * as path25 from "path";
17735
18033
  function parseFrontmatter(content) {
17736
18034
  const frontmatterRegex = /^---\s*\n([\s\S]*?)\n---\s*\n([\s\S]*)$/;
@@ -17752,7 +18050,7 @@ function parseFrontmatter(content) {
17752
18050
  }
17753
18051
  function loadCommandsFromDirectory(commandsDir) {
17754
18052
  const commands = /* @__PURE__ */ new Map();
17755
- if (!existsSync12(commandsDir)) {
18053
+ if (!existsSync13(commandsDir)) {
17756
18054
  return commands;
17757
18055
  }
17758
18056
  const files = readdirSync3(commandsDir).filter((f) => f.endsWith(".md"));
@@ -18098,7 +18396,7 @@ var RoutingHintController = class {
18098
18396
  }
18099
18397
  };
18100
18398
 
18101
- // src/index.ts
18399
+ // src/adapters/opencode.ts
18102
18400
  var activeWatchers = /* @__PURE__ */ new Map();
18103
18401
  function replaceActiveWatcher(projectRoot, nextWatcher) {
18104
18402
  const existing = activeWatchers.get(projectRoot);
@@ -18115,7 +18413,8 @@ function getCommandsDir() {
18115
18413
  if (typeof import.meta !== "undefined" && import.meta.url) {
18116
18414
  currentDir = path26.dirname(fileURLToPath2(import.meta.url));
18117
18415
  }
18118
- return path26.join(currentDir, "..", "commands");
18416
+ const packageRoot = path26.basename(currentDir) === "adapters" ? path26.join(currentDir, "..", "..") : path26.join(currentDir, "..");
18417
+ return path26.join(packageRoot, "commands");
18119
18418
  }
18120
18419
  function appendRoutingHints(output, hints, preferredRole) {
18121
18420
  const preferredBucket = preferredRole === "developer" ? output.developer : output.system;
@@ -18136,7 +18435,7 @@ function resolveProjectRoot(directory, worktree) {
18136
18435
  var plugin = async ({ directory, worktree }) => {
18137
18436
  try {
18138
18437
  const projectRoot = resolveProjectRoot(directory, worktree);
18139
- const rawConfig = loadMergedConfig(projectRoot);
18438
+ const rawConfig = loadMergedConfig(projectRoot, "opencode");
18140
18439
  const config = parseConfig(rawConfig);
18141
18440
  initializeTools2(projectRoot, config);
18142
18441
  const getProjectIndexer = () => getIndexerForProject2(projectRoot);
@@ -18162,23 +18461,23 @@ var plugin = async ({ directory, worktree }) => {
18162
18461
  }
18163
18462
  return {
18164
18463
  tool: {
18165
- codebase_context,
18166
- codebase_search,
18167
- codebase_peek,
18168
- index_codebase,
18169
- index_status,
18170
- index_health_check,
18171
- index_metrics,
18172
- index_logs,
18173
- find_similar,
18174
- call_graph,
18175
- call_graph_path,
18176
- implementation_lookup,
18177
- add_knowledge_base,
18178
- list_knowledge_bases,
18179
- remove_knowledge_base,
18180
- pr_impact,
18181
- index_visualize
18464
+ [TOOL_NAME.CODEBASE_CONTEXT]: codebase_context,
18465
+ [TOOL_NAME.CODEBASE_SEARCH]: codebase_search,
18466
+ [TOOL_NAME.CODEBASE_PEEK]: codebase_peek,
18467
+ [TOOL_NAME.INDEX_CODEBASE]: index_codebase,
18468
+ [TOOL_NAME.INDEX_STATUS]: index_status,
18469
+ [TOOL_NAME.INDEX_HEALTH_CHECK]: index_health_check,
18470
+ [TOOL_NAME.INDEX_METRICS]: index_metrics,
18471
+ [TOOL_NAME.INDEX_LOGS]: index_logs,
18472
+ [TOOL_NAME.FIND_SIMILAR]: find_similar,
18473
+ [TOOL_NAME.CALL_GRAPH]: call_graph,
18474
+ [TOOL_NAME.CALL_GRAPH_PATH]: call_graph_path,
18475
+ [TOOL_NAME.IMPLEMENTATION_LOOKUP]: implementation_lookup,
18476
+ [TOOL_NAME.ADD_KNOWLEDGE_BASE]: add_knowledge_base,
18477
+ [TOOL_NAME.LIST_KNOWLEDGE_BASES]: list_knowledge_bases,
18478
+ [TOOL_NAME.REMOVE_KNOWLEDGE_BASE]: remove_knowledge_base,
18479
+ [TOOL_NAME.PR_IMPACT]: pr_impact,
18480
+ [TOOL_NAME.INDEX_VISUALIZE]: index_visualize
18182
18481
  },
18183
18482
  async "chat.message"(input, output) {
18184
18483
  routingHints?.observeUserMessage(input.sessionID, output.parts);
@@ -18218,9 +18517,9 @@ var plugin = async ({ directory, worktree }) => {
18218
18517
  };
18219
18518
  }
18220
18519
  };
18221
- var index_default = plugin;
18520
+ var opencode_default = plugin;
18222
18521
  export {
18223
- index_default as default
18522
+ opencode_default as default
18224
18523
  };
18225
18524
  /*! Bundled license information:
18226
18525