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.
@@ -650,7 +650,7 @@ var require_eventemitter3 = __commonJS({
650
650
  }
651
651
  });
652
652
 
653
- // src/pi-extension.ts
653
+ // src/adapters/pi/extension.ts
654
654
  import { Type as Type2 } from "typebox";
655
655
 
656
656
  // src/config/constants.ts
@@ -1444,7 +1444,7 @@ import * as path19 from "path";
1444
1444
  // src/config/paths.ts
1445
1445
  import { existsSync as existsSync4 } from "fs";
1446
1446
  import * as os2 from "os";
1447
- import * as path4 from "path";
1447
+ import * as path5 from "path";
1448
1448
 
1449
1449
  // src/git/index.ts
1450
1450
  import { existsSync as existsSync3, readFileSync as readFileSync3, statSync as statSync2 } from "fs";
@@ -1576,15 +1576,125 @@ function getBranchOrDefault(repoRoot) {
1576
1576
  return getCurrentBranch(repoRoot) ?? "default";
1577
1577
  }
1578
1578
 
1579
+ // src/utils/canonical-path.ts
1580
+ import * as crypto from "crypto";
1581
+ import * as fs from "fs";
1582
+ import * as path4 from "path";
1583
+
1584
+ // node_modules/unicode-case-folding/index.js
1585
+ 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]]]);
1586
+ function caseFold(input) {
1587
+ if (typeof input !== "string") {
1588
+ throw new TypeError("Input must be a string");
1589
+ }
1590
+ let result = [];
1591
+ for (const char of input) {
1592
+ const codePoint = char.codePointAt(0);
1593
+ const mapping = FOLDING_MAP.get(codePoint);
1594
+ result.push(mapping ? String.fromCodePoint(...mapping) : char);
1595
+ }
1596
+ return result.join("");
1597
+ }
1598
+
1599
+ // src/utils/canonical-path.ts
1600
+ function alternateAsciiCase(value) {
1601
+ const index = value.search(/[A-Za-z]/);
1602
+ if (index === -1) return null;
1603
+ const character = value[index];
1604
+ const alternate = character === character.toLowerCase() ? character.toUpperCase() : character.toLowerCase();
1605
+ return `${value.slice(0, index)}${alternate}${value.slice(index + 1)}`;
1606
+ }
1607
+ function probeEntryCaseSensitivity(entryPath) {
1608
+ const alternateName = alternateAsciiCase(path4.basename(entryPath));
1609
+ if (!alternateName) return void 0;
1610
+ try {
1611
+ const canonicalPath = fs.realpathSync.native(entryPath);
1612
+ const alternatePath = fs.realpathSync.native(path4.join(path4.dirname(entryPath), alternateName));
1613
+ return canonicalPath === alternatePath;
1614
+ } catch (error) {
1615
+ const code = error.code;
1616
+ if (code === "ENOENT" || code === "ENOTDIR") return false;
1617
+ return void 0;
1618
+ }
1619
+ }
1620
+ function probeEmptyWindowsDirectory(existingAncestor) {
1621
+ const probePath = path4.join(
1622
+ existingAncestor,
1623
+ `.codebase-index-case-probe-${crypto.randomBytes(8).toString("hex")}`
1624
+ );
1625
+ let created = false;
1626
+ try {
1627
+ const descriptor = fs.openSync(probePath, "wx", 384);
1628
+ created = true;
1629
+ fs.closeSync(descriptor);
1630
+ return probeEntryCaseSensitivity(probePath);
1631
+ } catch {
1632
+ return void 0;
1633
+ } finally {
1634
+ if (created) fs.unlinkSync(probePath);
1635
+ }
1636
+ }
1637
+ function detectCaseInsensitiveFileSystem(existingAncestor) {
1638
+ try {
1639
+ if (fs.statSync(existingAncestor).isDirectory()) {
1640
+ const directory = fs.opendirSync(existingAncestor);
1641
+ try {
1642
+ let entry = directory.readSync();
1643
+ while (entry) {
1644
+ if (!entry.isSymbolicLink() && alternateAsciiCase(entry.name)) {
1645
+ const result = probeEntryCaseSensitivity(path4.join(existingAncestor, entry.name));
1646
+ if (result !== void 0) return result;
1647
+ }
1648
+ entry = directory.readSync();
1649
+ }
1650
+ } finally {
1651
+ directory.closeSync();
1652
+ }
1653
+ }
1654
+ } catch {
1655
+ return void 0;
1656
+ }
1657
+ if (process.platform === "darwin") {
1658
+ return probeEntryCaseSensitivity(existingAncestor);
1659
+ }
1660
+ if (process.platform === "win32") {
1661
+ return probeEmptyWindowsDirectory(existingAncestor);
1662
+ }
1663
+ return void 0;
1664
+ }
1665
+ function foldMissingPathComponent(component) {
1666
+ return caseFold(component);
1667
+ }
1668
+ function canonicalizePathForComparison(targetPath, options = {}) {
1669
+ const resolved = path4.resolve(targetPath);
1670
+ const missingParts = [];
1671
+ let candidate = resolved;
1672
+ while (true) {
1673
+ try {
1674
+ const existingAncestor = fs.realpathSync.native(candidate);
1675
+ const isCaseInsensitive = missingParts.length > 0 ? (options.isCaseInsensitive ?? detectCaseInsensitiveFileSystem)(existingAncestor) : false;
1676
+ const suffix = isCaseInsensitive === true ? missingParts.map(foldMissingPathComponent) : missingParts;
1677
+ return path4.join(existingAncestor, ...suffix);
1678
+ } catch (error) {
1679
+ const code = error.code;
1680
+ if (code !== "ENOENT" && code !== "ENOTDIR") throw error;
1681
+ const parent = path4.dirname(candidate);
1682
+ if (parent === candidate) return resolved;
1683
+ missingParts.unshift(path4.basename(candidate));
1684
+ candidate = parent;
1685
+ }
1686
+ }
1687
+ }
1688
+
1579
1689
  // src/config/paths.ts
1580
- var OPENCODE_PROJECT_CONFIG_RELATIVE_PATH = path4.join(".opencode", "codebase-index.json");
1581
- var OPENCODE_PROJECT_INDEX_RELATIVE_PATH = path4.join(".opencode", "index");
1690
+ var OPENCODE_PROJECT_CONFIG_RELATIVE_PATH = path5.join(".opencode", "codebase-index.json");
1691
+ var OPENCODE_PROJECT_INDEX_RELATIVE_PATH = path5.join(".opencode", "index");
1582
1692
  var CODEBASE_INDEX_DIR = ".codebase-index";
1583
- var CODEBASE_PROJECT_CONFIG_RELATIVE_PATH = path4.join(CODEBASE_INDEX_DIR, "config.json");
1584
- var CODEBASE_PROJECT_INDEX_RELATIVE_PATH = path4.join(CODEBASE_INDEX_DIR, "index");
1693
+ var CODEBASE_PROJECT_CONFIG_RELATIVE_PATH = path5.join(CODEBASE_INDEX_DIR, "config.json");
1694
+ var CODEBASE_PROJECT_INDEX_RELATIVE_PATH = path5.join(CODEBASE_INDEX_DIR, "index");
1585
1695
  var CLAUDE_DIR = ".claude";
1586
- var CLAUDE_PROJECT_CONFIG_RELATIVE_PATH = path4.join(CLAUDE_DIR, "codebase-index.json");
1587
- var CLAUDE_PROJECT_INDEX_RELATIVE_PATH = path4.join(CLAUDE_DIR, "index");
1696
+ var CLAUDE_PROJECT_CONFIG_RELATIVE_PATH = path5.join(CLAUDE_DIR, "codebase-index.json");
1697
+ var CLAUDE_PROJECT_INDEX_RELATIVE_PATH = path5.join(CLAUDE_DIR, "index");
1588
1698
  function getProjectConfigRelativePath(host) {
1589
1699
  switch (host) {
1590
1700
  case "opencode":
@@ -1610,42 +1720,71 @@ function resolveWorktreeFallbackPath(projectRoot3, relativePath) {
1610
1720
  if (!mainRepoRoot) {
1611
1721
  return null;
1612
1722
  }
1613
- const fallbackPath = path4.join(mainRepoRoot, relativePath);
1723
+ const fallbackPath = path5.join(mainRepoRoot, relativePath);
1614
1724
  return existsSync4(fallbackPath) ? fallbackPath : null;
1615
1725
  }
1616
1726
  function getHostProjectConfigRelativePath(host) {
1617
1727
  return getProjectConfigRelativePath(host);
1618
1728
  }
1619
- function getHostProjectIndexRelativePath(host) {
1620
- return getProjectIndexRelativePath(host);
1729
+ function getProjectConfigCandidatePaths(projectRoot3, host) {
1730
+ const candidates = [path5.join(projectRoot3, getProjectConfigRelativePath(host))];
1731
+ if (host !== "opencode") {
1732
+ candidates.push(path5.join(projectRoot3, OPENCODE_PROJECT_CONFIG_RELATIVE_PATH));
1733
+ }
1734
+ const mainRepoRoot = resolveWorktreeMainRepoRoot(projectRoot3);
1735
+ if (mainRepoRoot) {
1736
+ candidates.push(path5.join(mainRepoRoot, getProjectConfigRelativePath(host)));
1737
+ if (host !== "opencode") {
1738
+ candidates.push(path5.join(mainRepoRoot, OPENCODE_PROJECT_CONFIG_RELATIVE_PATH));
1739
+ }
1740
+ }
1741
+ return [...new Set(candidates)];
1742
+ }
1743
+ function isProjectIndexPathOwnedByProject(projectRoot3, indexPath, host) {
1744
+ const projectRoots = [projectRoot3];
1745
+ const mainRepoRoot = resolveWorktreeMainRepoRoot(projectRoot3);
1746
+ if (mainRepoRoot) {
1747
+ projectRoots.push(mainRepoRoot);
1748
+ }
1749
+ const ownedIndexPaths = projectRoots.flatMap((root) => {
1750
+ const indexPaths = [path5.join(root, getProjectIndexRelativePath(host))];
1751
+ if (host !== "opencode") {
1752
+ indexPaths.push(path5.join(root, OPENCODE_PROJECT_INDEX_RELATIVE_PATH));
1753
+ }
1754
+ return indexPaths;
1755
+ });
1756
+ const canonicalIndexPath = canonicalizePathForComparison(indexPath);
1757
+ return ownedIndexPaths.some(
1758
+ (ownedPath) => canonicalizePathForComparison(ownedPath) === canonicalIndexPath
1759
+ );
1621
1760
  }
1622
1761
  function hasHostProjectConfig(projectRoot3, host) {
1623
- return existsSync4(path4.join(projectRoot3, getProjectConfigRelativePath(host)));
1762
+ return existsSync4(path5.join(projectRoot3, getProjectConfigRelativePath(host)));
1624
1763
  }
1625
1764
  function hasHostGlobalConfig(host) {
1626
1765
  return existsSync4(getGlobalConfigPath(host));
1627
1766
  }
1628
- function getGlobalIndexPath(host = "opencode") {
1767
+ function getGlobalIndexPath(host) {
1629
1768
  switch (host) {
1630
1769
  case "opencode":
1631
- return path4.join(os2.homedir(), ".opencode", "global-index");
1770
+ return path5.join(os2.homedir(), ".opencode", "global-index");
1632
1771
  case "claude":
1633
- return path4.join(os2.homedir(), ".claude", "global-index");
1772
+ return path5.join(os2.homedir(), ".claude", "global-index");
1634
1773
  default:
1635
- return path4.join(os2.homedir(), ".codebase-index", "global-index");
1774
+ return path5.join(os2.homedir(), ".codebase-index", "global-index");
1636
1775
  }
1637
1776
  }
1638
- function getGlobalConfigPath(host = "opencode") {
1777
+ function getGlobalConfigPath(host) {
1639
1778
  switch (host) {
1640
1779
  case "opencode":
1641
- return path4.join(os2.homedir(), ".config", "opencode", "codebase-index.json");
1780
+ return path5.join(os2.homedir(), ".config", "opencode", "codebase-index.json");
1642
1781
  case "claude":
1643
- return path4.join(os2.homedir(), ".claude", "codebase-index.json");
1782
+ return path5.join(os2.homedir(), ".claude", "codebase-index.json");
1644
1783
  default:
1645
- return path4.join(os2.homedir(), ".config", "codebase-index", "config.json");
1784
+ return path5.join(os2.homedir(), ".config", "codebase-index", "config.json");
1646
1785
  }
1647
1786
  }
1648
- function resolveGlobalConfigPath(host = "opencode") {
1787
+ function resolveGlobalConfigPath(host) {
1649
1788
  const hostConfigPath = getGlobalConfigPath(host);
1650
1789
  if (existsSync4(hostConfigPath)) {
1651
1790
  return hostConfigPath;
@@ -1658,7 +1797,7 @@ function resolveGlobalConfigPath(host = "opencode") {
1658
1797
  }
1659
1798
  return hostConfigPath;
1660
1799
  }
1661
- function resolveGlobalIndexPath(host = "opencode") {
1800
+ function resolveGlobalIndexPath(host) {
1662
1801
  const hostIndexPath = getGlobalIndexPath(host);
1663
1802
  if (existsSync4(hostIndexPath)) {
1664
1803
  return hostIndexPath;
@@ -1674,42 +1813,43 @@ function resolveGlobalIndexPath(host = "opencode") {
1674
1813
  }
1675
1814
  return hostIndexPath;
1676
1815
  }
1677
- function resolveProjectConfigPath(projectRoot3, host = "opencode") {
1678
- const hostConfigPath = path4.join(projectRoot3, getProjectConfigRelativePath(host));
1679
- if (existsSync4(hostConfigPath)) {
1680
- return hostConfigPath;
1681
- }
1682
- if (host !== "opencode") {
1683
- const legacyConfigPath = path4.join(projectRoot3, OPENCODE_PROJECT_CONFIG_RELATIVE_PATH);
1684
- if (existsSync4(legacyConfigPath)) {
1685
- return legacyConfigPath;
1686
- }
1687
- }
1688
- const hostFallback = resolveWorktreeFallbackPath(projectRoot3, getProjectConfigRelativePath(host));
1689
- if (hostFallback) {
1690
- return hostFallback;
1691
- }
1692
- if (host !== "opencode") {
1693
- const legacyFallback = resolveWorktreeFallbackPath(projectRoot3, OPENCODE_PROJECT_CONFIG_RELATIVE_PATH);
1694
- if (legacyFallback) {
1695
- return legacyFallback;
1696
- }
1697
- }
1698
- return hostConfigPath;
1816
+ function resolveProjectConfigPath(projectRoot3, host) {
1817
+ const candidates = getProjectConfigCandidatePaths(projectRoot3, host);
1818
+ return candidates.find((candidate) => existsSync4(candidate)) ?? path5.join(projectRoot3, getProjectConfigRelativePath(host));
1699
1819
  }
1700
- function resolveWritableProjectConfigPath(projectRoot3, host = "opencode") {
1701
- return path4.join(projectRoot3, getProjectConfigRelativePath(host));
1820
+ function resolveWritableProjectConfigPath(projectRoot3, host) {
1821
+ return path5.join(projectRoot3, getProjectConfigRelativePath(host));
1702
1822
  }
1703
- function resolveProjectIndexPath(projectRoot3, scope, host = "opencode") {
1823
+ function resolveProjectIndexPath(projectRoot3, scope, host) {
1704
1824
  if (scope === "global") {
1705
1825
  return resolveGlobalIndexPath(host);
1706
1826
  }
1707
- const localIndexPath = path4.join(projectRoot3, getProjectIndexRelativePath(host));
1827
+ const localIndexPath = path5.join(projectRoot3, getProjectIndexRelativePath(host));
1828
+ const mainRepoRoot = resolveWorktreeMainRepoRoot(projectRoot3);
1829
+ if (mainRepoRoot) {
1830
+ if (hasHostProjectConfig(projectRoot3, host)) {
1831
+ return localIndexPath;
1832
+ }
1833
+ if (host !== "opencode") {
1834
+ const localLegacyConfigPath = path5.join(projectRoot3, OPENCODE_PROJECT_CONFIG_RELATIVE_PATH);
1835
+ if (existsSync4(localLegacyConfigPath)) {
1836
+ return path5.join(projectRoot3, OPENCODE_PROJECT_INDEX_RELATIVE_PATH);
1837
+ }
1838
+ const mainHostConfigPath = path5.join(mainRepoRoot, getProjectConfigRelativePath(host));
1839
+ const mainHostIndexPath = path5.join(mainRepoRoot, getProjectIndexRelativePath(host));
1840
+ const mainLegacyConfigPath = path5.join(mainRepoRoot, OPENCODE_PROJECT_CONFIG_RELATIVE_PATH);
1841
+ const mainLegacyIndexPath = path5.join(mainRepoRoot, OPENCODE_PROJECT_INDEX_RELATIVE_PATH);
1842
+ if (!existsSync4(mainHostConfigPath) && !existsSync4(mainHostIndexPath) && (existsSync4(mainLegacyConfigPath) || existsSync4(mainLegacyIndexPath))) {
1843
+ return mainLegacyIndexPath;
1844
+ }
1845
+ }
1846
+ return path5.join(mainRepoRoot, getProjectIndexRelativePath(host));
1847
+ }
1708
1848
  if (existsSync4(localIndexPath)) {
1709
1849
  return localIndexPath;
1710
1850
  }
1711
1851
  if (host !== "opencode") {
1712
- const legacyIndexPath = path4.join(projectRoot3, OPENCODE_PROJECT_INDEX_RELATIVE_PATH);
1852
+ const legacyIndexPath = path5.join(projectRoot3, OPENCODE_PROJECT_INDEX_RELATIVE_PATH);
1713
1853
  if (existsSync4(legacyIndexPath) && !hasHostProjectConfig(projectRoot3, host)) {
1714
1854
  return legacyIndexPath;
1715
1855
  }
@@ -1717,9 +1857,6 @@ function resolveProjectIndexPath(projectRoot3, scope, host = "opencode") {
1717
1857
  if (hasHostProjectConfig(projectRoot3, host)) {
1718
1858
  return localIndexPath;
1719
1859
  }
1720
- if (resolveWorktreeMainRepoRoot(projectRoot3)) {
1721
- return localIndexPath;
1722
- }
1723
1860
  const hostFallback = resolveWorktreeFallbackPath(projectRoot3, getProjectIndexRelativePath(host));
1724
1861
  if (hostFallback) {
1725
1862
  return hostFallback;
@@ -1734,10 +1871,10 @@ function resolveProjectIndexPath(projectRoot3, scope, host = "opencode") {
1734
1871
  }
1735
1872
 
1736
1873
  // src/tools/knowledge-base-paths.ts
1737
- import * as path6 from "path";
1874
+ import * as path7 from "path";
1738
1875
 
1739
1876
  // src/utils/paths.ts
1740
- import * as path5 from "path";
1877
+ import * as path6 from "path";
1741
1878
  function normalizePathSeparators(value) {
1742
1879
  return value.replace(/\\/g, "/");
1743
1880
  }
@@ -1754,37 +1891,37 @@ function resolveConfigPathValue(value, baseDir) {
1754
1891
  if (!trimmed) {
1755
1892
  return trimmed;
1756
1893
  }
1757
- const absolutePath = path6.isAbsolute(trimmed) ? trimmed : path6.resolve(baseDir, trimmed);
1758
- return path6.normalize(absolutePath);
1894
+ const absolutePath = path7.isAbsolute(trimmed) ? trimmed : path7.resolve(baseDir, trimmed);
1895
+ return path7.normalize(absolutePath);
1759
1896
  }
1760
1897
  function serializeConfigPathValue(value, baseDir) {
1761
1898
  const trimmed = value.trim();
1762
1899
  if (!trimmed) {
1763
1900
  return trimmed;
1764
1901
  }
1765
- if (!path6.isAbsolute(trimmed)) {
1766
- return normalizePathSeparators(path6.normalize(trimmed));
1902
+ if (!path7.isAbsolute(trimmed)) {
1903
+ return normalizePathSeparators(path7.normalize(trimmed));
1767
1904
  }
1768
- const relativePath = path6.relative(baseDir, trimmed);
1769
- if (!relativePath || !relativePath.startsWith("..") && !path6.isAbsolute(relativePath)) {
1770
- return normalizePathSeparators(path6.normalize(relativePath || "."));
1905
+ const relativePath = path7.relative(baseDir, trimmed);
1906
+ if (!relativePath || !relativePath.startsWith("..") && !path7.isAbsolute(relativePath)) {
1907
+ return normalizePathSeparators(path7.normalize(relativePath || "."));
1771
1908
  }
1772
- return path6.normalize(trimmed);
1909
+ return path7.normalize(trimmed);
1773
1910
  }
1774
1911
  function resolveKnowledgeBasePath(value, projectRoot3) {
1775
- return path6.isAbsolute(value) ? value : path6.resolve(projectRoot3, value);
1912
+ return path7.isAbsolute(value) ? value : path7.resolve(projectRoot3, value);
1776
1913
  }
1777
1914
  function normalizeKnowledgeBasePath(value, projectRoot3) {
1778
- return path6.normalize(resolveKnowledgeBasePath(value, projectRoot3));
1915
+ return path7.normalize(resolveKnowledgeBasePath(value, projectRoot3));
1779
1916
  }
1780
1917
  function hasMatchingKnowledgeBasePath(knowledgeBases, inputPath, projectRoot3) {
1781
- const normalizedInput = path6.normalize(inputPath);
1918
+ const normalizedInput = path7.normalize(inputPath);
1782
1919
  return knowledgeBases.some((kb) => normalizeKnowledgeBasePath(kb, projectRoot3) === normalizedInput);
1783
1920
  }
1784
1921
  function findKnowledgeBasePathIndex(knowledgeBases, inputPath, projectRoot3) {
1785
- const normalizedInput = path6.normalize(inputPath);
1922
+ const normalizedInput = path7.normalize(inputPath);
1786
1923
  return knowledgeBases.findIndex(
1787
- (kb) => path6.normalize(kb) === normalizedInput || normalizeKnowledgeBasePath(kb, projectRoot3) === normalizedInput
1924
+ (kb) => path7.normalize(kb) === normalizedInput || normalizeKnowledgeBasePath(kb, projectRoot3) === normalizedInput
1788
1925
  );
1789
1926
  }
1790
1927
 
@@ -3065,9 +3202,9 @@ function formatEffectivenessMetrics(snapshot) {
3065
3202
  }
3066
3203
 
3067
3204
  // src/utils/auto-index.ts
3068
- import { existsSync as existsSync7, realpathSync as realpathSync2 } from "fs";
3205
+ import { existsSync as existsSync7, realpathSync as realpathSync3 } from "fs";
3069
3206
  import * as os4 from "os";
3070
- import * as path9 from "path";
3207
+ import * as path10 from "path";
3071
3208
 
3072
3209
  // src/indexer/index-lock.ts
3073
3210
  import { randomUUID } from "crypto";
@@ -3077,13 +3214,13 @@ import {
3077
3214
  mkdirSync,
3078
3215
  readFileSync as readFileSync4,
3079
3216
  readdirSync as readdirSync2,
3080
- realpathSync,
3217
+ realpathSync as realpathSync2,
3081
3218
  renameSync,
3082
3219
  rmSync,
3083
3220
  writeFileSync
3084
3221
  } from "fs";
3085
3222
  import * as os3 from "os";
3086
- import * as path7 from "path";
3223
+ import * as path8 from "path";
3087
3224
  var OWNER_FILE_NAME = "owner.json";
3088
3225
  var RECLAIM_DIRECTORY_NAME = "reclaiming";
3089
3226
  var RECOVERY_MARKER_PREFIX = "indexing.lock.recovery.";
@@ -3140,7 +3277,7 @@ function parseReclaimOwner(value) {
3140
3277
  }
3141
3278
  function readJsonDirectory(directoryPath, parser) {
3142
3279
  try {
3143
- return parser(JSON.parse(readFileSync4(path7.join(directoryPath, OWNER_FILE_NAME), "utf-8")));
3280
+ return parser(JSON.parse(readFileSync4(path8.join(directoryPath, OWNER_FILE_NAME), "utf-8")));
3144
3281
  } catch {
3145
3282
  return null;
3146
3283
  }
@@ -3197,7 +3334,7 @@ function publishJsonDirectory(finalPath, value) {
3197
3334
  throw error;
3198
3335
  }
3199
3336
  try {
3200
- writeFileSync(path7.join(candidatePath, OWNER_FILE_NAME), JSON.stringify(value), {
3337
+ writeFileSync(path8.join(candidatePath, OWNER_FILE_NAME), JSON.stringify(value), {
3201
3338
  encoding: "utf-8",
3202
3339
  flag: "wx",
3203
3340
  mode: 384
@@ -3228,7 +3365,7 @@ function createOwner(operation) {
3228
3365
  };
3229
3366
  }
3230
3367
  function recoveryMarkerPath(indexPath, owner) {
3231
- return path7.join(indexPath, `${RECOVERY_MARKER_PREFIX}${owner.token}`);
3368
+ return path8.join(indexPath, `${RECOVERY_MARKER_PREFIX}${owner.token}`);
3232
3369
  }
3233
3370
  function publishRecoveryMarker(indexPath, owner) {
3234
3371
  const markerPath = recoveryMarkerPath(indexPath, owner);
@@ -3247,7 +3384,7 @@ function getPendingRecoveries(indexPath) {
3247
3384
  return UUID_PATTERN.test(name.slice(RECOVERY_MARKER_PREFIX.length));
3248
3385
  }).sort();
3249
3386
  for (const markerName of markerNames) {
3250
- const markerPath = path7.join(indexPath, markerName);
3387
+ const markerPath = path8.join(indexPath, markerName);
3251
3388
  const markerToken = markerName.slice(RECOVERY_MARKER_PREFIX.length);
3252
3389
  let markerStats;
3253
3390
  try {
@@ -3279,11 +3416,11 @@ function cleanupDeadPublicationCandidates(indexPath) {
3279
3416
  const pid = Number(match[1]);
3280
3417
  if (!Number.isInteger(pid) || pid <= 0) continue;
3281
3418
  if (getOwnerLiveness({ pid, hostname: os3.hostname() }) !== "dead") continue;
3282
- rmSync(path7.join(indexPath, entry), { recursive: true, force: true });
3419
+ rmSync(path8.join(indexPath, entry), { recursive: true, force: true });
3283
3420
  }
3284
3421
  }
3285
3422
  function removeDeadReclaimMarker(lockPath, expectedOwner) {
3286
- const markerPath = path7.join(lockPath, RECLAIM_DIRECTORY_NAME);
3423
+ const markerPath = path8.join(lockPath, RECLAIM_DIRECTORY_NAME);
3287
3424
  const marker = readReclaimOwner(markerPath);
3288
3425
  if (!marker || marker.expectedOwnerToken !== expectedOwner.token || getOwnerLiveness(marker) !== "dead") {
3289
3426
  return false;
@@ -3311,7 +3448,7 @@ function removeDeadReclaimMarker(lockPath, expectedOwner) {
3311
3448
  return true;
3312
3449
  }
3313
3450
  function reclaimDeadOwner(indexPath, lockPath, expectedOwner) {
3314
- const reclaimPath = path7.join(lockPath, RECLAIM_DIRECTORY_NAME);
3451
+ const reclaimPath = path8.join(lockPath, RECLAIM_DIRECTORY_NAME);
3315
3452
  const reclaimOwner = {
3316
3453
  pid: process.pid,
3317
3454
  hostname: os3.hostname(),
@@ -3368,8 +3505,8 @@ function isTransientIndexLockContention(error) {
3368
3505
  }
3369
3506
  function acquireIndexLock(indexPath, operation) {
3370
3507
  mkdirSync(indexPath, { recursive: true });
3371
- const canonicalIndexPath = realpathSync.native(indexPath);
3372
- const lockPath = path7.join(canonicalIndexPath, "indexing.lock");
3508
+ const canonicalIndexPath = realpathSync2.native(indexPath);
3509
+ const lockPath = path8.join(canonicalIndexPath, "indexing.lock");
3373
3510
  cleanupDeadPublicationCandidates(canonicalIndexPath);
3374
3511
  for (let attempt = 0; attempt < 6; attempt += 1) {
3375
3512
  const owner = createOwner(operation);
@@ -3455,7 +3592,7 @@ function recoverLeaseArtifacts(indexPath, owner, backupTargets) {
3455
3592
  const temporaryOwnerMarker = `.tmp.${owner.pid}.${owner.token}.`;
3456
3593
  for (const entry of readdirSync2(indexPath)) {
3457
3594
  if (!entry.includes(temporaryOwnerMarker)) continue;
3458
- rmSync(path7.join(indexPath, entry), { recursive: true, force: true });
3595
+ rmSync(path8.join(indexPath, entry), { recursive: true, force: true });
3459
3596
  }
3460
3597
  }
3461
3598
  function completeLeaseRecovery(lease) {
@@ -3473,7 +3610,7 @@ function completeLeaseRecovery(lease) {
3473
3610
  // src/utils/files.ts
3474
3611
  var import_ignore = __toESM(require_ignore(), 1);
3475
3612
  import { existsSync as existsSync6, readFileSync as readFileSync5, promises as fsPromises } from "fs";
3476
- import * as path8 from "path";
3613
+ import * as path9 from "path";
3477
3614
  var PROJECT_MARKERS = [
3478
3615
  ".git",
3479
3616
  "package.json",
@@ -3491,7 +3628,7 @@ var PROJECT_MARKERS = [
3491
3628
  ];
3492
3629
  function hasProjectMarker(projectRoot3) {
3493
3630
  for (const marker of PROJECT_MARKERS) {
3494
- if (existsSync6(path8.join(projectRoot3, marker))) {
3631
+ if (existsSync6(path9.join(projectRoot3, marker))) {
3495
3632
  return true;
3496
3633
  }
3497
3634
  }
@@ -3518,7 +3655,7 @@ function createIgnoreFilter(projectRoot3) {
3518
3655
  "**/*build*/**"
3519
3656
  ];
3520
3657
  ig.add(defaultIgnores);
3521
- const gitignorePath = path8.join(projectRoot3, ".gitignore");
3658
+ const gitignorePath = path9.join(projectRoot3, ".gitignore");
3522
3659
  if (existsSync6(gitignorePath)) {
3523
3660
  const gitignoreContent = readFileSync5(gitignorePath, "utf-8");
3524
3661
  ig.add(gitignoreContent);
@@ -3545,8 +3682,8 @@ async function* walkDirectory(dir, projectRoot3, includePatterns, excludePattern
3545
3682
  const filesInDir = [];
3546
3683
  const subdirs = [];
3547
3684
  for (const entry of entries) {
3548
- const fullPath = path8.join(dir, entry.name);
3549
- const relativePath = path8.relative(projectRoot3, fullPath);
3685
+ const fullPath = path9.join(dir, entry.name);
3686
+ const relativePath = path9.relative(projectRoot3, fullPath);
3550
3687
  if (isHiddenPathSegment(entry.name)) {
3551
3688
  if (entry.isDirectory()) {
3552
3689
  skipped.push({ path: relativePath, reason: "excluded" });
@@ -3595,7 +3732,7 @@ async function* walkDirectory(dir, projectRoot3, includePatterns, excludePattern
3595
3732
  yield f;
3596
3733
  }
3597
3734
  for (let i = options.maxFilesPerDirectory; i < filesInDir.length; i++) {
3598
- skipped.push({ path: path8.relative(projectRoot3, filesInDir[i].path), reason: "excluded" });
3735
+ skipped.push({ path: path9.relative(projectRoot3, filesInDir[i].path), reason: "excluded" });
3599
3736
  }
3600
3737
  const canRecurse = options.maxDepth === -1 || currentDepth < options.maxDepth;
3601
3738
  if (canRecurse) {
@@ -3635,8 +3772,8 @@ async function collectFiles(projectRoot3, includePatterns, excludePatterns, maxF
3635
3772
  if (additionalRoots && additionalRoots.length > 0) {
3636
3773
  const normalizedRoots = /* @__PURE__ */ new Set();
3637
3774
  for (const kbRoot of additionalRoots) {
3638
- const resolved = path8.normalize(
3639
- path8.isAbsolute(kbRoot) ? kbRoot : path8.resolve(projectRoot3, kbRoot)
3775
+ const resolved = path9.normalize(
3776
+ path9.isAbsolute(kbRoot) ? kbRoot : path9.resolve(projectRoot3, kbRoot)
3640
3777
  );
3641
3778
  normalizedRoots.add(resolved);
3642
3779
  }
@@ -3780,17 +3917,17 @@ function now() {
3780
3917
  return (/* @__PURE__ */ new Date()).toISOString();
3781
3918
  }
3782
3919
  function canonicalizePath(targetPath) {
3783
- const resolved = path9.resolve(targetPath);
3920
+ const resolved = path10.resolve(targetPath);
3784
3921
  if (existsSync7(resolved)) {
3785
3922
  try {
3786
- return realpathSync2.native(resolved);
3923
+ return realpathSync3.native(resolved);
3787
3924
  } catch {
3788
3925
  return resolved;
3789
3926
  }
3790
3927
  }
3791
- const parent = path9.dirname(resolved);
3928
+ const parent = path10.dirname(resolved);
3792
3929
  if (parent === resolved) return resolved;
3793
- return path9.join(canonicalizePath(parent), path9.basename(resolved));
3930
+ return path10.join(canonicalizePath(parent), path10.basename(resolved));
3794
3931
  }
3795
3932
  function isHomeDirectory(projectRoot3) {
3796
3933
  return canonicalizePath(projectRoot3) === canonicalizePath(os4.homedir());
@@ -4317,14 +4454,14 @@ function runCoordinatedIndex(projectRoot3, host, force, onProgress) {
4317
4454
  source: "manual"
4318
4455
  }) ?? null;
4319
4456
  }
4320
- function getAutoIndexStatus(projectRoot3, host = "opencode") {
4457
+ function getAutoIndexStatus(projectRoot3, host) {
4321
4458
  return getCoordinator(projectRoot3, host)?.snapshot() ?? {
4322
4459
  enabled: false,
4323
4460
  state: "idle",
4324
4461
  updatedAt: now()
4325
4462
  };
4326
4463
  }
4327
- async function waitForAutoIndexForRetrieval(projectRoot3, host = "opencode") {
4464
+ async function waitForAutoIndexForRetrieval(projectRoot3, host) {
4328
4465
  const coordinator = getCoordinator(projectRoot3, host);
4329
4466
  if (!coordinator) return { ready: true };
4330
4467
  const initial = coordinator.snapshot();
@@ -4371,7 +4508,7 @@ async function waitForAutoIndexForRetrieval(projectRoot3, host = "opencode") {
4371
4508
  text: `Automatic indexing is ${status.state}. Retry shortly or call index_status for progress. You can also run index_codebase explicitly.`
4372
4509
  };
4373
4510
  }
4374
- async function stopAutoIndex(projectRoot3, host = "opencode") {
4511
+ async function stopAutoIndex(projectRoot3, host) {
4375
4512
  await getCoordinator(projectRoot3, host)?.stop();
4376
4513
  }
4377
4514
  async function hasReadableCurrentIndex(coordinator) {
@@ -4385,17 +4522,17 @@ async function hasReadableCurrentIndex(coordinator) {
4385
4522
 
4386
4523
  // src/tools/config-state.ts
4387
4524
  import { existsSync as existsSync9, mkdirSync as mkdirSync2, writeFileSync as writeFileSync2 } from "fs";
4388
- import * as path12 from "path";
4525
+ import * as path13 from "path";
4389
4526
 
4390
4527
  // src/config/merger.ts
4391
4528
  import { existsSync as existsSync8, readFileSync as readFileSync6 } from "fs";
4392
- import * as path11 from "path";
4529
+ import * as path12 from "path";
4393
4530
 
4394
4531
  // src/config/rebase.ts
4395
- import * as path10 from "path";
4532
+ import * as path11 from "path";
4396
4533
  function isWithinRoot(rootDir, targetPath) {
4397
- const relativePath = path10.relative(rootDir, targetPath);
4398
- return relativePath === "" || !relativePath.startsWith("..") && !path10.isAbsolute(relativePath);
4534
+ const relativePath = path11.relative(rootDir, targetPath);
4535
+ return relativePath === "" || !relativePath.startsWith("..") && !path11.isAbsolute(relativePath);
4399
4536
  }
4400
4537
  function resolveInheritedKnowledgeBaseEntries(values, sourceRoot, targetRoot) {
4401
4538
  if (!Array.isArray(values)) {
@@ -4406,17 +4543,17 @@ function resolveInheritedKnowledgeBaseEntries(values, sourceRoot, targetRoot) {
4406
4543
  if (!trimmed) {
4407
4544
  return trimmed;
4408
4545
  }
4409
- if (path10.isAbsolute(trimmed)) {
4546
+ if (path11.isAbsolute(trimmed)) {
4410
4547
  if (isWithinRoot(sourceRoot, trimmed)) {
4411
- return normalizePathSeparators(path10.normalize(path10.relative(sourceRoot, trimmed) || "."));
4548
+ return normalizePathSeparators(path11.normalize(path11.relative(sourceRoot, trimmed) || "."));
4412
4549
  }
4413
- return path10.normalize(trimmed);
4550
+ return path11.normalize(trimmed);
4414
4551
  }
4415
- const resolvedFromSource = path10.resolve(sourceRoot, trimmed);
4552
+ const resolvedFromSource = path11.resolve(sourceRoot, trimmed);
4416
4553
  if (isWithinRoot(sourceRoot, resolvedFromSource)) {
4417
- return normalizePathSeparators(path10.normalize(trimmed));
4554
+ return normalizePathSeparators(path11.normalize(trimmed));
4418
4555
  }
4419
- return normalizePathSeparators(path10.normalize(path10.relative(targetRoot, resolvedFromSource)));
4556
+ return normalizePathSeparators(path11.normalize(path11.relative(targetRoot, resolvedFromSource)));
4420
4557
  }).filter(Boolean);
4421
4558
  }
4422
4559
 
@@ -4454,8 +4591,8 @@ function mergeUniqueStringArray(values) {
4454
4591
  return [...new Set(values.map((value) => String(value).trim()))];
4455
4592
  }
4456
4593
  function normalizeKnowledgeBasePath2(value) {
4457
- let normalized = path11.normalize(String(value).trim());
4458
- const root = path11.parse(normalized).root;
4594
+ let normalized = path12.normalize(String(value).trim());
4595
+ const root = path12.parse(normalized).root;
4459
4596
  while (normalized.length > root.length && /[\\/]$/.test(normalized)) {
4460
4597
  normalized = normalized.slice(0, -1);
4461
4598
  }
@@ -4503,14 +4640,14 @@ function loadJsonFile(filePath) {
4503
4640
  throw new Error(`Failed to load config file ${filePath}: ${message}`);
4504
4641
  }
4505
4642
  }
4506
- function loadProjectConfigLayer(projectRoot3, host = "opencode") {
4643
+ function loadProjectConfigLayer(projectRoot3, host) {
4507
4644
  const projectConfigPath = resolveProjectConfigPath(projectRoot3, host);
4508
4645
  const projectConfig = loadJsonFile(projectConfigPath);
4509
4646
  if (!projectConfig) {
4510
4647
  return {};
4511
4648
  }
4512
4649
  const normalizedConfig = { ...projectConfig };
4513
- const projectConfigBaseDir = path11.dirname(path11.dirname(projectConfigPath));
4650
+ const projectConfigBaseDir = path12.dirname(path12.dirname(projectConfigPath));
4514
4651
  if (Array.isArray(normalizedConfig.knowledgeBases)) {
4515
4652
  normalizedConfig.knowledgeBases = resolveInheritedKnowledgeBaseEntries(
4516
4653
  normalizedConfig.knowledgeBases,
@@ -4520,7 +4657,7 @@ function loadProjectConfigLayer(projectRoot3, host = "opencode") {
4520
4657
  }
4521
4658
  return normalizedConfig;
4522
4659
  }
4523
- function loadMergedConfig(projectRoot3, host = "opencode") {
4660
+ function loadMergedConfig(projectRoot3, host) {
4524
4661
  const globalConfigPath = resolveGlobalConfigPath(host);
4525
4662
  const projectConfigPath = resolveProjectConfigPath(projectRoot3, host);
4526
4663
  let globalConfig = null;
@@ -4589,19 +4726,19 @@ function toConfigRecord(rawConfig) {
4589
4726
  }
4590
4727
  return { ...rawConfig };
4591
4728
  }
4592
- function getConfigPath(projectRoot3, host = "opencode") {
4729
+ function getConfigPath(projectRoot3, host) {
4593
4730
  return resolveWritableProjectConfigPath(projectRoot3, host);
4594
4731
  }
4595
- function loadRuntimeConfig(projectRoot3, host = "opencode") {
4732
+ function loadRuntimeConfig(projectRoot3, host) {
4596
4733
  return normalizeKnowledgeBasePaths(toConfigRecord(loadMergedConfig(projectRoot3, host)), projectRoot3);
4597
4734
  }
4598
- function loadEditableConfig(projectRoot3, host = "opencode") {
4735
+ function loadEditableConfig(projectRoot3, host) {
4599
4736
  return normalizeKnowledgeBasePaths(toConfigRecord(loadProjectConfigLayer(projectRoot3, host)), projectRoot3);
4600
4737
  }
4601
- function saveConfig(projectRoot3, config, host = "opencode") {
4738
+ function saveConfig(projectRoot3, config, host) {
4602
4739
  const configPath = getConfigPath(projectRoot3, host);
4603
- const configDir = path12.dirname(configPath);
4604
- const configBaseDir = path12.dirname(configDir);
4740
+ const configDir = path13.dirname(configPath);
4741
+ const configBaseDir = path13.dirname(configDir);
4605
4742
  if (!existsSync9(configDir)) {
4606
4743
  mkdirSync2(configDir, { recursive: true });
4607
4744
  }
@@ -6753,42 +6890,80 @@ function extractParamNames(params) {
6753
6890
 
6754
6891
  // src/native/binding.ts
6755
6892
  import * as os5 from "os";
6756
- import * as path13 from "path";
6893
+ import * as path14 from "path";
6757
6894
  import * as module from "module";
6758
6895
  import { fileURLToPath } from "url";
6759
- function getNativeBinding() {
6760
- const platform2 = os5.platform();
6761
- const arch2 = os5.arch();
6762
- let bindingName;
6896
+
6897
+ // src/identity-catalog.json
6898
+ var identity_catalog_default = {
6899
+ product: {
6900
+ current: {
6901
+ productName: "opencode-codebase-index",
6902
+ packageName: "opencode-codebase-index",
6903
+ repository: "https://github.com/Helweg/opencode-codebase-index",
6904
+ mcpBinary: "opencode-codebase-index-mcp",
6905
+ mcpServerName: "opencode-codebase-index"
6906
+ },
6907
+ future: {
6908
+ productName: "open-codebase-index",
6909
+ packageName: "open-codebase-index",
6910
+ repository: "https://github.com/Helweg/open-codebase-index",
6911
+ mcpBinary: "open-codebase-index-mcp",
6912
+ mcpServerName: "open-codebase-index"
6913
+ }
6914
+ },
6915
+ native: {
6916
+ binaryName: "codebase-index-native"
6917
+ }
6918
+ };
6919
+
6920
+ // src/identity-catalog.ts
6921
+ var IDENTITY_CATALOG = identity_catalog_default;
6922
+ var CURRENT_PRODUCT = IDENTITY_CATALOG.product.current;
6923
+ var FUTURE_PRODUCT = IDENTITY_CATALOG.product.future;
6924
+ var MCP_SERVER_CURRENT_NAME = CURRENT_PRODUCT.mcpServerName;
6925
+ var MCP_BINARY_CURRENT_NAME = CURRENT_PRODUCT.mcpBinary;
6926
+ var STABLE_NATIVE_BINARY_NAME = IDENTITY_CATALOG.native.binaryName;
6927
+
6928
+ // src/native/binding.ts
6929
+ function getNativeBindingFilename(platform2 = os5.platform(), arch2 = os5.arch()) {
6763
6930
  if (platform2 === "darwin" && arch2 === "arm64") {
6764
- bindingName = "codebase-index-native.darwin-arm64.node";
6765
- } else if (platform2 === "darwin" && arch2 === "x64") {
6766
- bindingName = "codebase-index-native.darwin-x64.node";
6767
- } else if (platform2 === "linux" && arch2 === "x64") {
6768
- bindingName = "codebase-index-native.linux-x64-gnu.node";
6769
- } else if (platform2 === "linux" && arch2 === "arm64") {
6770
- bindingName = "codebase-index-native.linux-arm64-gnu.node";
6771
- } else if (platform2 === "win32" && arch2 === "x64") {
6772
- bindingName = "codebase-index-native.win32-x64-msvc.node";
6773
- } else {
6774
- throw new Error(`Unsupported platform: ${platform2}-${arch2}`);
6931
+ return `${STABLE_NATIVE_BINARY_NAME}.darwin-arm64.node`;
6775
6932
  }
6933
+ if (platform2 === "darwin" && arch2 === "x64") {
6934
+ return `${STABLE_NATIVE_BINARY_NAME}.darwin-x64.node`;
6935
+ }
6936
+ if (platform2 === "linux" && arch2 === "x64") {
6937
+ return `${STABLE_NATIVE_BINARY_NAME}.linux-x64-gnu.node`;
6938
+ }
6939
+ if (platform2 === "linux" && arch2 === "arm64") {
6940
+ return `${STABLE_NATIVE_BINARY_NAME}.linux-arm64-gnu.node`;
6941
+ }
6942
+ if (platform2 === "win32" && arch2 === "x64") {
6943
+ return `${STABLE_NATIVE_BINARY_NAME}.win32-x64-msvc.node`;
6944
+ }
6945
+ throw new Error(`Unsupported platform: ${platform2}-${arch2}`);
6946
+ }
6947
+ function resolveNativeBindingPath(packageRoot, platform2 = os5.platform(), arch2 = os5.arch()) {
6948
+ return path14.join(packageRoot, "native", getNativeBindingFilename(platform2, arch2));
6949
+ }
6950
+ function getNativeBinding() {
6776
6951
  let currentDir;
6777
6952
  let requireTarget;
6778
6953
  if (typeof import.meta !== "undefined" && import.meta.url) {
6779
- currentDir = path13.dirname(fileURLToPath(import.meta.url));
6954
+ currentDir = path14.dirname(fileURLToPath(import.meta.url));
6780
6955
  requireTarget = import.meta.url;
6781
6956
  } else if (typeof __dirname !== "undefined") {
6782
6957
  currentDir = __dirname;
6783
6958
  requireTarget = __filename;
6784
6959
  } else {
6785
6960
  currentDir = process.cwd();
6786
- requireTarget = path13.join(currentDir, "index.js");
6961
+ requireTarget = path14.join(currentDir, "index.js");
6787
6962
  }
6788
6963
  const normalizedDir = currentDir.replace(/\\/g, "/");
6789
- const isDevMode = normalizedDir.includes("/src/native") || currentDir.includes(path13.join("src", "native"));
6790
- const packageRoot = isDevMode ? path13.resolve(currentDir, "../..") : path13.resolve(currentDir, "..");
6791
- const nativePath = path13.join(packageRoot, "native", bindingName);
6964
+ const isDevMode = normalizedDir.includes("/src/native") || currentDir.includes(path14.join("src", "native"));
6965
+ const packageRoot = isDevMode ? path14.resolve(currentDir, "../..") : path14.resolve(currentDir, "..");
6966
+ const nativePath = resolveNativeBindingPath(packageRoot);
6792
6967
  const require2 = module.createRequire(requireTarget);
6793
6968
  return require2(nativePath);
6794
6969
  }
@@ -7348,116 +7523,6 @@ import { promises as fsPromises2 } from "fs";
7348
7523
  import * as os6 from "os";
7349
7524
  import * as path15 from "path";
7350
7525
 
7351
- // src/utils/canonical-path.ts
7352
- import * as crypto from "crypto";
7353
- import * as fs from "fs";
7354
- import * as path14 from "path";
7355
-
7356
- // node_modules/unicode-case-folding/index.js
7357
- 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]]]);
7358
- function caseFold(input) {
7359
- if (typeof input !== "string") {
7360
- throw new TypeError("Input must be a string");
7361
- }
7362
- let result = [];
7363
- for (const char of input) {
7364
- const codePoint = char.codePointAt(0);
7365
- const mapping = FOLDING_MAP.get(codePoint);
7366
- result.push(mapping ? String.fromCodePoint(...mapping) : char);
7367
- }
7368
- return result.join("");
7369
- }
7370
-
7371
- // src/utils/canonical-path.ts
7372
- function alternateAsciiCase(value) {
7373
- const index = value.search(/[A-Za-z]/);
7374
- if (index === -1) return null;
7375
- const character = value[index];
7376
- const alternate = character === character.toLowerCase() ? character.toUpperCase() : character.toLowerCase();
7377
- return `${value.slice(0, index)}${alternate}${value.slice(index + 1)}`;
7378
- }
7379
- function probeEntryCaseSensitivity(entryPath) {
7380
- const alternateName = alternateAsciiCase(path14.basename(entryPath));
7381
- if (!alternateName) return void 0;
7382
- try {
7383
- const canonicalPath = fs.realpathSync.native(entryPath);
7384
- const alternatePath = fs.realpathSync.native(path14.join(path14.dirname(entryPath), alternateName));
7385
- return canonicalPath === alternatePath;
7386
- } catch (error) {
7387
- const code = error.code;
7388
- if (code === "ENOENT" || code === "ENOTDIR") return false;
7389
- return void 0;
7390
- }
7391
- }
7392
- function probeEmptyWindowsDirectory(existingAncestor) {
7393
- const probePath = path14.join(
7394
- existingAncestor,
7395
- `.codebase-index-case-probe-${crypto.randomBytes(8).toString("hex")}`
7396
- );
7397
- let created = false;
7398
- try {
7399
- const descriptor = fs.openSync(probePath, "wx", 384);
7400
- created = true;
7401
- fs.closeSync(descriptor);
7402
- return probeEntryCaseSensitivity(probePath);
7403
- } catch {
7404
- return void 0;
7405
- } finally {
7406
- if (created) fs.unlinkSync(probePath);
7407
- }
7408
- }
7409
- function detectCaseInsensitiveFileSystem(existingAncestor) {
7410
- try {
7411
- if (fs.statSync(existingAncestor).isDirectory()) {
7412
- const directory = fs.opendirSync(existingAncestor);
7413
- try {
7414
- let entry = directory.readSync();
7415
- while (entry) {
7416
- if (!entry.isSymbolicLink() && alternateAsciiCase(entry.name)) {
7417
- const result = probeEntryCaseSensitivity(path14.join(existingAncestor, entry.name));
7418
- if (result !== void 0) return result;
7419
- }
7420
- entry = directory.readSync();
7421
- }
7422
- } finally {
7423
- directory.closeSync();
7424
- }
7425
- }
7426
- } catch {
7427
- return void 0;
7428
- }
7429
- if (process.platform === "darwin") {
7430
- return probeEntryCaseSensitivity(existingAncestor);
7431
- }
7432
- if (process.platform === "win32") {
7433
- return probeEmptyWindowsDirectory(existingAncestor);
7434
- }
7435
- return void 0;
7436
- }
7437
- function foldMissingPathComponent(component) {
7438
- return caseFold(component);
7439
- }
7440
- function canonicalizePathForComparison(targetPath, options = {}) {
7441
- const resolved = path14.resolve(targetPath);
7442
- const missingParts = [];
7443
- let candidate = resolved;
7444
- while (true) {
7445
- try {
7446
- const existingAncestor = fs.realpathSync.native(candidate);
7447
- const isCaseInsensitive = missingParts.length > 0 ? (options.isCaseInsensitive ?? detectCaseInsensitiveFileSystem)(existingAncestor) : false;
7448
- const suffix = isCaseInsensitive === true ? missingParts.map(foldMissingPathComponent) : missingParts;
7449
- return path14.join(existingAncestor, ...suffix);
7450
- } catch (error) {
7451
- const code = error.code;
7452
- if (code !== "ENOENT" && code !== "ENOTDIR") throw error;
7453
- const parent = path14.dirname(candidate);
7454
- if (parent === candidate) return resolved;
7455
- missingParts.unshift(path14.basename(candidate));
7456
- candidate = parent;
7457
- }
7458
- }
7459
- }
7460
-
7461
7526
  // src/git/branch-resolution.ts
7462
7527
  import { execFile as execFile2 } from "child_process";
7463
7528
  import { randomBytes as randomBytes2 } from "crypto";
@@ -9091,6 +9156,8 @@ function hasBlameMetadata(metadata) {
9091
9156
  return blameFromMetadata(metadata) !== void 0;
9092
9157
  }
9093
9158
  var INDEX_METADATA_VERSION = "1";
9159
+ var PROJECT_PATH_STORAGE_VERSION = "2";
9160
+ var GLOBAL_PATH_STORAGE_VERSION = "1";
9094
9161
  var EMBEDDING_STRATEGY_VERSION = "2";
9095
9162
  var SWIFT_PARSER_VERSION = "1";
9096
9163
  var METAL_PARSER_VERSION = "1";
@@ -9421,18 +9488,20 @@ function selectIndexableChunks(chunks, limit, semanticOnly) {
9421
9488
  const indexableChunks = semanticOnly ? chunks.filter((chunk) => chunk.chunkType !== "other") : chunks;
9422
9489
  return selectChunksWithFileCoverage(indexableChunks, limit);
9423
9490
  }
9424
- function matchesHardSearchFilters(candidate, options) {
9491
+ function matchesHardSearchFilters(candidate, options, projectRoot3) {
9425
9492
  if (options?.fileType) {
9426
9493
  const ext = candidate.metadata.filePath.split(".").pop()?.toLowerCase();
9427
9494
  const requestedExtension = options.fileType.trim().toLowerCase().replace(/^\./, "");
9428
9495
  if (ext !== requestedExtension) return false;
9429
9496
  }
9430
9497
  if (options?.directory) {
9431
- const normalizedPath = candidate.metadata.filePath.replace(/\\/g, "/");
9432
- const normalizedDir = options.directory.trim().replace(/\\/g, "/").replace(/^\.\//, "").replace(/\/$/, "");
9433
- const isAbsoluteDirectory = normalizedDir.startsWith("/");
9434
- const matchesDirectory = isAbsoluteDirectory ? normalizedPath === normalizedDir || normalizedPath.startsWith(`${normalizedDir}/`) : normalizedPath === normalizedDir || normalizedPath.startsWith(`${normalizedDir}/`) || normalizedPath.includes(`/${normalizedDir}/`) || normalizedPath.endsWith(`/${normalizedDir}`);
9435
- if (!matchesDirectory) return false;
9498
+ const candidatePath = canonicalizePathForComparison(
9499
+ path18.resolve(projectRoot3, candidate.metadata.filePath.replace(/\\/g, path18.sep))
9500
+ );
9501
+ const directoryPath = canonicalizePathForComparison(
9502
+ path18.resolve(projectRoot3, options.directory.trim().replace(/\\/g, path18.sep))
9503
+ );
9504
+ if (!isPathWithinRoot2(candidatePath, directoryPath)) return false;
9436
9505
  }
9437
9506
  if (options?.chunkType && candidate.metadata.chunkType !== options.chunkType) {
9438
9507
  return false;
@@ -9454,8 +9523,8 @@ function matchesHardSearchFilters(candidate, options) {
9454
9523
  }
9455
9524
  return true;
9456
9525
  }
9457
- function matchesSearchFilters(candidate, options, minScore) {
9458
- return candidate.score >= minScore && matchesHardSearchFilters(candidate, options);
9526
+ function matchesSearchFilters(candidate, options, minScore, projectRoot3) {
9527
+ return candidate.score >= minScore && matchesHardSearchFilters(candidate, options, projectRoot3);
9459
9528
  }
9460
9529
  function unionCandidates(semanticCandidates, keywordCandidates) {
9461
9530
  const byId = /* @__PURE__ */ new Map();
@@ -9506,7 +9575,7 @@ var Indexer = class _Indexer {
9506
9575
  readerArtifactFingerprint = null;
9507
9576
  writerArtifactFingerprint = null;
9508
9577
  readerArtifactRetryAfter = /* @__PURE__ */ new Map();
9509
- constructor(projectRoot3, config, host = "opencode", runtimeOptions = {}) {
9578
+ constructor(projectRoot3, config, host, runtimeOptions = {}) {
9510
9579
  this.projectRoot = projectRoot3;
9511
9580
  this.projectIdentityHash = hashContent(this.getCanonicalPath(projectRoot3)).slice(0, 16);
9512
9581
  this.materializedProjectRoot = runtimeOptions.materializedProjectRoot ?? projectRoot3;
@@ -9519,37 +9588,90 @@ var Indexer = class _Indexer {
9519
9588
  this.indexPathOverride = runtimeOptions.indexPath;
9520
9589
  this.config = config;
9521
9590
  this.host = host;
9591
+ if (isGitRepo(this.materializedProjectRoot)) {
9592
+ this.currentBranch = this.branchNameOverride ?? getBranchOrDefault(this.materializedProjectRoot);
9593
+ this.baseBranch = getBaseBranch(this.materializedProjectRoot);
9594
+ } else {
9595
+ this.currentBranch = "default";
9596
+ this.baseBranch = "default";
9597
+ }
9522
9598
  this.indexPath = this.getIndexPath();
9523
- this.fileHashCachePath = this.getRuntimeArtifactPath("file-hashes.json");
9524
- this.failedBatchesPath = this.getRuntimeArtifactPath("failed-batches.json");
9599
+ this.refreshRuntimeArtifactPaths();
9525
9600
  this.logger = initializeLogger(config.debug);
9526
9601
  }
9527
9602
  getIndexPath() {
9528
9603
  return this.indexPathOverride ?? resolveProjectIndexPath(this.projectRoot, this.config.scope, this.host);
9529
9604
  }
9530
9605
  toCanonicalFilePath(filePath) {
9606
+ if (!path18.isAbsolute(filePath)) {
9607
+ return this.resolveStoredFilePath(filePath, this.projectRoot);
9608
+ }
9531
9609
  if (path18.resolve(this.materializedProjectRoot) === path18.resolve(this.projectRoot) || !isPathWithinRoot2(filePath, this.materializedProjectRoot)) {
9532
9610
  return filePath;
9533
9611
  }
9534
9612
  return path18.resolve(this.projectRoot, path18.relative(this.materializedProjectRoot, filePath));
9535
9613
  }
9536
- toMaterializedFilePath(filePath) {
9537
- if (path18.resolve(this.materializedProjectRoot) === path18.resolve(this.projectRoot) || !isPathWithinRoot2(filePath, this.projectRoot)) {
9614
+ toStoredFilePath(filePath) {
9615
+ const canonicalFilePath = this.toCanonicalFilePath(filePath);
9616
+ if (this.config.scope !== "project" || !isPathWithinRoot2(canonicalFilePath, this.projectRoot)) {
9617
+ return canonicalFilePath;
9618
+ }
9619
+ return path18.relative(this.projectRoot, canonicalFilePath).split(path18.sep).join("/");
9620
+ }
9621
+ resolveStoredFilePath(filePath, rootPath = this.projectRoot) {
9622
+ if (path18.isAbsolute(filePath)) {
9538
9623
  return filePath;
9539
9624
  }
9540
- return path18.resolve(this.materializedProjectRoot, path18.relative(this.projectRoot, filePath));
9625
+ const resolvedPath = path18.resolve(rootPath, ...filePath.split("/"));
9626
+ if (!isPathWithinRoot2(resolvedPath, rootPath)) {
9627
+ throw new Error(`Stored project path escapes project root: ${JSON.stringify(filePath)}`);
9628
+ }
9629
+ return resolvedPath;
9630
+ }
9631
+ getCanonicalStoredFilePath(filePath) {
9632
+ return this.getCanonicalPath(this.resolveStoredFilePath(filePath));
9633
+ }
9634
+ resolveFilePathRecord(record) {
9635
+ return {
9636
+ ...record,
9637
+ filePath: this.resolveStoredFilePath(record.filePath)
9638
+ };
9639
+ }
9640
+ resolveCallEdgeFilePath(edge) {
9641
+ if (!edge.fromSymbolFilePath) return edge;
9642
+ return {
9643
+ ...edge,
9644
+ fromSymbolFilePath: this.resolveStoredFilePath(edge.fromSymbolFilePath)
9645
+ };
9646
+ }
9647
+ toMaterializedFilePath(filePath) {
9648
+ const storedFilePath = this.toStoredFilePath(filePath);
9649
+ if (path18.isAbsolute(storedFilePath)) {
9650
+ return storedFilePath;
9651
+ }
9652
+ return this.resolveStoredFilePath(storedFilePath, this.materializedProjectRoot);
9541
9653
  }
9542
9654
  getPreparedBranchNamespace() {
9543
9655
  if (!this.branchNameOverride && !this.catalogIdentityOverride) return null;
9544
9656
  return hashContent(this.getBranchCatalogKey()).slice(0, 16);
9545
9657
  }
9658
+ getRuntimeArtifactNamespace() {
9659
+ if (this.config.scope !== "project" || this.getBranchCatalogIdentity() === "default") {
9660
+ return this.getPreparedBranchNamespace();
9661
+ }
9662
+ return hashContent(this.getBranchCatalogKey()).slice(0, 16);
9663
+ }
9546
9664
  getRuntimeArtifactPath(fileName) {
9547
- const namespace = this.getPreparedBranchNamespace();
9665
+ const namespace = this.getRuntimeArtifactNamespace();
9548
9666
  if (!namespace) return path18.join(this.indexPath, fileName);
9549
9667
  const extension = path18.extname(fileName);
9550
9668
  const baseName = fileName.slice(0, fileName.length - extension.length);
9551
9669
  return path18.join(this.indexPath, `${baseName}.${namespace}${extension}`);
9552
9670
  }
9671
+ refreshRuntimeArtifactPaths() {
9672
+ this.fileHashCachePath = this.getRuntimeArtifactPath("file-hashes.json");
9673
+ this.failedBatchesPath = this.getRuntimeArtifactPath("failed-batches.json");
9674
+ }
9553
9675
  getPreparedChunkId(chunkId) {
9554
9676
  const namespace = this.getPreparedBranchNamespace();
9555
9677
  return namespace ? `${chunkId}_${namespace}` : chunkId;
@@ -9575,19 +9697,8 @@ var Indexer = class _Indexer {
9575
9697
  return path18.resolve(targetPath);
9576
9698
  }
9577
9699
  }
9578
- isLocalProjectIndexPath() {
9579
- const localProjectIndexPaths = [path18.join(this.projectRoot, getHostProjectIndexRelativePath(this.host))];
9580
- if (this.host !== "opencode") {
9581
- localProjectIndexPaths.push(path18.join(this.projectRoot, getHostProjectIndexRelativePath("opencode")));
9582
- }
9583
- return localProjectIndexPaths.some((localPath) => {
9584
- if (!existsSync10(localPath) || !existsSync10(this.indexPath)) {
9585
- return path18.resolve(this.indexPath) === path18.resolve(localPath);
9586
- }
9587
- const indexStats = statSync4(this.indexPath);
9588
- const localStats = statSync4(localPath);
9589
- return indexStats.dev === localStats.dev && indexStats.ino === localStats.ino;
9590
- });
9700
+ isProjectOwnedIndexPath() {
9701
+ return isProjectIndexPathOwnedByProject(this.projectRoot, this.indexPath, this.host);
9591
9702
  }
9592
9703
  resetLoadedIndexState(retireDatabase = false) {
9593
9704
  if (this.database) {
@@ -9622,10 +9733,10 @@ var Indexer = class _Indexer {
9622
9733
  this.readerArtifactRetryAfter.clear();
9623
9734
  }
9624
9735
  async withIndexMutationLease(operation, callback) {
9736
+ this.refreshBranchInfo();
9625
9737
  const lease = acquireIndexLock(this.indexPath, operation);
9626
9738
  this.indexPath = lease.canonicalIndexPath;
9627
- this.fileHashCachePath = this.getRuntimeArtifactPath("file-hashes.json");
9628
- this.failedBatchesPath = this.getRuntimeArtifactPath("failed-batches.json");
9739
+ this.refreshRuntimeArtifactPaths();
9629
9740
  this.activeIndexLease = lease;
9630
9741
  let result;
9631
9742
  let callbackError;
@@ -9797,29 +9908,24 @@ var Indexer = class _Indexer {
9797
9908
  getProjectForceReembedMetadataKey() {
9798
9909
  return `index.forceReembed.${this.projectIdentityHash}`;
9799
9910
  }
9800
- getCallGraphResolutionMetadataKey() {
9801
- if (this.config.scope !== "global") {
9802
- return "index.callGraphResolutionVersion";
9803
- }
9804
- return `index.callGraphResolutionVersion.${this.projectIdentityHash}`;
9911
+ getBranchMigrationMetadataKey(prefix, catalogIdentity = this.getBranchCatalogIdentity()) {
9912
+ const branchKey = this.getBranchCatalogKeyFor(catalogIdentity);
9913
+ return `${prefix}.${hashContent(branchKey).slice(0, 24)}`;
9805
9914
  }
9806
- getSwiftParserVersionMetadataKey() {
9807
- const key = "index.parser.swiftVersion";
9808
- if (this.config.scope !== "global") {
9809
- return key;
9810
- }
9811
- return `${key}.${this.projectIdentityHash}`;
9915
+ getCallGraphResolutionMetadataKey(catalogIdentity = this.getBranchCatalogIdentity()) {
9916
+ return this.getBranchMigrationMetadataKey("index.callGraphResolutionVersion", catalogIdentity);
9812
9917
  }
9813
- getMetalParserVersionMetadataKey() {
9814
- const key = "index.parser.metalVersion";
9815
- if (this.config.scope !== "global") {
9816
- return key;
9817
- }
9818
- return `${key}.${this.projectIdentityHash}`;
9918
+ getSwiftParserVersionMetadataKey(catalogIdentity = this.getBranchCatalogIdentity()) {
9919
+ return this.getBranchMigrationMetadataKey("index.parser.swiftVersion", catalogIdentity);
9920
+ }
9921
+ getMetalParserVersionMetadataKey(catalogIdentity = this.getBranchCatalogIdentity()) {
9922
+ return this.getBranchMigrationMetadataKey("index.parser.metalVersion", catalogIdentity);
9819
9923
  }
9820
9924
  getSymbolExtractorVersionMetadataKey(catalogIdentity = this.getBranchCatalogIdentity()) {
9821
- const branchKey = this.getBranchCatalogKeyFor(catalogIdentity);
9822
- return `index.symbolExtractorVersion.${hashContent(branchKey).slice(0, 24)}`;
9925
+ return this.getBranchMigrationMetadataKey("index.symbolExtractorVersion", catalogIdentity);
9926
+ }
9927
+ areBranchMigrationVersionsCurrent(database, catalogIdentity = this.getBranchCatalogIdentity()) {
9928
+ 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;
9823
9929
  }
9824
9930
  hasProjectForceReembedPending() {
9825
9931
  return this.config.scope === "global" && this.database?.getMetadata(this.getProjectForceReembedMetadataKey()) === "true";
@@ -9954,13 +10060,14 @@ var Indexer = class _Indexer {
9954
10060
  return Array.from(keys);
9955
10061
  }
9956
10062
  isFileInCurrentScope(filePath, roots) {
9957
- if (roots.some((root) => isPathWithinRoot2(filePath, root))) return true;
9958
- const canonicalFilePath = this.getCanonicalPath(filePath);
10063
+ const canonicalFilePath = this.getCanonicalStoredFilePath(filePath);
9959
10064
  return roots.some((root) => isPathWithinRoot2(canonicalFilePath, root));
9960
10065
  }
9961
10066
  isFileInProjectRoot(filePath) {
9962
- if (isPathWithinRoot2(filePath, this.projectRoot)) return true;
9963
- return isPathWithinRoot2(this.getCanonicalPath(filePath), this.getCanonicalPath(this.projectRoot));
10067
+ return isPathWithinRoot2(
10068
+ this.getCanonicalStoredFilePath(filePath),
10069
+ this.getCanonicalPath(this.projectRoot)
10070
+ );
9964
10071
  }
9965
10072
  clearScopedFileHashCache(roots) {
9966
10073
  for (const filePath of Array.from(this.fileHashCache.keys())) {
@@ -10361,7 +10468,10 @@ var Indexer = class _Indexer {
10361
10468
  const intent = isLikelyImplementationPath2(candidate.metadata.filePath) ? "implementation" : "doc_or_test";
10362
10469
  parts.push(`intent_hint: ${intent}`);
10363
10470
  try {
10364
- const fileContent = await fsPromises3.readFile(candidate.metadata.filePath, "utf-8");
10471
+ const fileContent = await fsPromises3.readFile(
10472
+ this.toMaterializedFilePath(candidate.metadata.filePath),
10473
+ "utf-8"
10474
+ );
10365
10475
  const lines = fileContent.split("\n");
10366
10476
  const snippetStartLine = Math.max(1, candidate.metadata.startLine);
10367
10477
  const snippetEndLine = Math.min(lines.length, candidate.metadata.endLine);
@@ -10430,7 +10540,7 @@ var Indexer = class _Indexer {
10430
10540
  if (this.config.scope === "global") {
10431
10541
  return "Shared vector index could not be read. Restore or repair the complete fingerprinted shared vector artifacts; automatic reset is disabled for global scope.";
10432
10542
  }
10433
- if (!this.isLocalProjectIndexPath()) {
10543
+ if (!this.isProjectOwnedIndexPath()) {
10434
10544
  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.";
10435
10545
  }
10436
10546
  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.";
@@ -10439,7 +10549,7 @@ var Indexer = class _Indexer {
10439
10549
  if (this.config.scope === "global") {
10440
10550
  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.";
10441
10551
  }
10442
- if (!this.isLocalProjectIndexPath()) {
10552
+ if (!this.isProjectOwnedIndexPath()) {
10443
10553
  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.";
10444
10554
  }
10445
10555
  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.";
@@ -10448,10 +10558,10 @@ var Indexer = class _Indexer {
10448
10558
  if (this.config.scope === "global") {
10449
10559
  return "Shared index database could not be read. Restore or repair the shared SQLite database; automatic reset is disabled for global scope.";
10450
10560
  }
10451
- if (!this.isLocalProjectIndexPath()) {
10561
+ if (!this.isProjectOwnedIndexPath()) {
10452
10562
  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.";
10453
10563
  }
10454
- return "Index database could not be read. Run index_codebase after the active writer finishes to repair or migrate it under the writer lease.";
10564
+ 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.";
10455
10565
  }
10456
10566
  getReaderFileFingerprint(filePath, identityOnly = false) {
10457
10567
  try {
@@ -10631,7 +10741,7 @@ var Indexer = class _Indexer {
10631
10741
  const readerArtifactFingerprint = mode === "reader" ? this.captureReaderArtifactFingerprint() : null;
10632
10742
  if (mode === "writer") {
10633
10743
  await fsPromises3.mkdir(this.indexPath, { recursive: true });
10634
- if (recoveredOwners.length > 0 && this.config.scope === "project" && !this.isLocalProjectIndexPath()) {
10744
+ if (recoveredOwners.length > 0 && this.config.scope === "project" && !this.isProjectOwnedIndexPath()) {
10635
10745
  throw new Error(
10636
10746
  "Interrupted indexing recovery is unsafe while using an inherited worktree index. Run index_codebase with force=true to create a local project index boundary."
10637
10747
  );
@@ -10732,6 +10842,7 @@ var Indexer = class _Indexer {
10732
10842
  this.baseBranch = "default";
10733
10843
  this.logger.branch("debug", "Not a git repository, using default branch");
10734
10844
  }
10845
+ this.refreshRuntimeArtifactPaths();
10735
10846
  if (mode === "writer" && recoveredOwners.length > 0) {
10736
10847
  await this.recoverFromInterruptedIndexingUnlocked(recoveredOwners);
10737
10848
  }
@@ -10887,6 +10998,14 @@ var Indexer = class _Indexer {
10887
10998
  }
10888
10999
  return `Detected a corrupted local SQLite index at ${dbPath} and reset the local index. Run index_codebase to rebuild search data.`;
10889
11000
  }
11001
+ async removeProjectRuntimeStateArtifacts() {
11002
+ if (!existsSync10(this.indexPath)) return;
11003
+ const names = await fsPromises3.readdir(this.indexPath);
11004
+ const runtimeStatePattern = /^(?:file-hashes|failed-batches)(?:\.[a-f0-9]{16})?\.json$/;
11005
+ await Promise.all(
11006
+ names.filter((name) => runtimeStatePattern.test(name)).map((name) => fsPromises3.rm(path18.join(this.indexPath, name), { force: true }))
11007
+ );
11008
+ }
10890
11009
  async resetLocalIndexArtifacts() {
10891
11010
  this.store = null;
10892
11011
  this.invertedIndex = null;
@@ -10906,11 +11025,10 @@ var Indexer = class _Indexer {
10906
11025
  path18.join(this.indexPath, "vectors"),
10907
11026
  path18.join(this.indexPath, "vectors.usearch"),
10908
11027
  path18.join(this.indexPath, "vectors.meta.json"),
10909
- path18.join(this.indexPath, "inverted-index.json"),
10910
- path18.join(this.indexPath, "file-hashes.json"),
10911
- path18.join(this.indexPath, "failed-batches.json")
11028
+ path18.join(this.indexPath, "inverted-index.json")
10912
11029
  ];
10913
11030
  await Promise.all(resetPaths.map((targetPath) => fsPromises3.rm(targetPath, { recursive: true, force: true })));
11031
+ await this.removeProjectRuntimeStateArtifacts();
10914
11032
  await fsPromises3.mkdir(this.indexPath, { recursive: true });
10915
11033
  }
10916
11034
  async tryResetCorruptedIndex(stage, error) {
@@ -10960,12 +11078,20 @@ var Indexer = class _Indexer {
10960
11078
  }
10961
11079
  this.database.addChunksToBranchBatch(this.getBranchCatalogKey(), chunkIds);
10962
11080
  }
11081
+ getExpectedPathStorageVersion() {
11082
+ return this.config.scope === "project" ? PROJECT_PATH_STORAGE_VERSION : GLOBAL_PATH_STORAGE_VERSION;
11083
+ }
11084
+ hasStoredIndexData() {
11085
+ const stats = this.database?.getStats();
11086
+ return (this.store?.count() ?? 0) > 0 || (stats?.chunkCount ?? 0) > 0 || (stats?.symbolCount ?? 0) > 0 || this.fileHashCache.size > 0;
11087
+ }
10963
11088
  loadIndexMetadata() {
10964
11089
  if (!this.database) return null;
10965
11090
  const version = this.database.getMetadata("index.version");
10966
11091
  if (!version) return null;
10967
11092
  return {
10968
11093
  indexVersion: version,
11094
+ pathStorageVersion: this.database.getMetadata("index.pathStorageVersion") ?? GLOBAL_PATH_STORAGE_VERSION,
10969
11095
  embeddingProvider: this.database.getMetadata("index.embeddingProvider") ?? "",
10970
11096
  embeddingModel: this.database.getMetadata("index.embeddingModel") ?? "",
10971
11097
  embeddingDimensions: parseInt(this.database.getMetadata("index.embeddingDimensions") ?? "0", 10),
@@ -10980,6 +11106,7 @@ var Indexer = class _Indexer {
10980
11106
  const existingCreatedAt = this.database.getMetadata("index.createdAt");
10981
11107
  const completeProjectEmbeddingStrategyReset = !this.hasProjectForceReembedPending();
10982
11108
  this.database.setMetadata("index.version", INDEX_METADATA_VERSION);
11109
+ this.database.setMetadata("index.pathStorageVersion", this.getExpectedPathStorageVersion());
10983
11110
  this.database.setMetadata("index.embeddingProvider", provider.provider);
10984
11111
  this.database.setMetadata("index.embeddingModel", provider.modelInfo.model);
10985
11112
  this.database.setMetadata("index.embeddingDimensions", provider.modelInfo.dimensions.toString());
@@ -11002,6 +11129,16 @@ var Indexer = class _Indexer {
11002
11129
  }
11003
11130
  validateIndexCompatibility(provider) {
11004
11131
  const storedMetadata = this.loadIndexMetadata();
11132
+ const storedPathStorageVersion = this.database?.getMetadata("index.pathStorageVersion") ?? GLOBAL_PATH_STORAGE_VERSION;
11133
+ const expectedPathStorageVersion = this.getExpectedPathStorageVersion();
11134
+ if (this.hasStoredIndexData() && storedPathStorageVersion !== expectedPathStorageVersion) {
11135
+ return {
11136
+ compatible: false,
11137
+ code: "PATH_STORAGE_MISMATCH" /* PATH_STORAGE_MISMATCH */,
11138
+ 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.`,
11139
+ storedMetadata: storedMetadata ?? void 0
11140
+ };
11141
+ }
11005
11142
  if (!storedMetadata) {
11006
11143
  return { compatible: true };
11007
11144
  }
@@ -11053,6 +11190,7 @@ var Indexer = class _Indexer {
11053
11190
  return this.indexCompatibility;
11054
11191
  }
11055
11192
  async ensureInitialized() {
11193
+ this.refreshBranchInfo();
11056
11194
  let initializedReader = false;
11057
11195
  while (true) {
11058
11196
  if (this.initializationPromise) {
@@ -11160,8 +11298,8 @@ var Indexer = class _Indexer {
11160
11298
  }
11161
11299
  const branchKey = this.getBranchCatalogKey();
11162
11300
  const alreadyIndexed = database.getBranchChunkIds(branchKey).length > 0 && database.getBranchSymbolIds(branchKey).length > 0;
11163
- const symbolsCurrent = database.getMetadata(this.getSymbolExtractorVersionMetadataKey()) === SYMBOL_EXTRACTOR_VERSION;
11164
- if (alreadyIndexed && symbolsCurrent && this.getStoredBranchCommit(database) === normalizedCommit) {
11301
+ const migrationsCurrent = this.areBranchMigrationVersionsCurrent(database);
11302
+ if (alreadyIndexed && migrationsCurrent && this.getStoredBranchCommit(database) === normalizedCommit) {
11165
11303
  return { prepared: false };
11166
11304
  }
11167
11305
  const stats = await this.indexUnlocked(onProgress, [], true);
@@ -11255,21 +11393,21 @@ var Indexer = class _Indexer {
11255
11393
  const currentFileHashes = /* @__PURE__ */ new Map();
11256
11394
  const needsCallGraphResolutionMigration = database.getMetadata(this.getCallGraphResolutionMetadataKey()) !== CALL_GRAPH_RESOLUTION_VERSION;
11257
11395
  for (const f of files) {
11258
- const canonicalPath = this.toCanonicalFilePath(f.path);
11396
+ const storedPath = this.toStoredFilePath(f.path);
11259
11397
  const currentHash = hashFile(f.path);
11260
- currentFileHashes.set(canonicalPath, currentHash);
11261
- const cachedHashMatches = this.fileHashCache.get(canonicalPath) === currentHash;
11262
- const needsCallGraphRefresh = cachedHashMatches && needsCallGraphResolutionMigration && database.getChunksByFile(canonicalPath).some(
11398
+ currentFileHashes.set(storedPath, currentHash);
11399
+ const cachedHashMatches = this.fileHashCache.get(storedPath) === currentHash;
11400
+ const needsCallGraphRefresh = cachedHashMatches && needsCallGraphResolutionMigration && database.getChunksByFile(storedPath).some(
11263
11401
  (chunk) => chunk.language === "php" || chunk.language === "c" || chunk.language === "cpp"
11264
11402
  );
11265
- const requiresSwiftParserUpgrade = reparseCachedSwiftFiles && path18.extname(canonicalPath).toLowerCase() === ".swift";
11266
- const requiresMetalParserUpgrade = reparseCachedMetalFiles && path18.extname(canonicalPath).toLowerCase() === ".metal";
11403
+ const requiresSwiftParserUpgrade = reparseCachedSwiftFiles && path18.extname(storedPath).toLowerCase() === ".swift";
11404
+ const requiresMetalParserUpgrade = reparseCachedMetalFiles && path18.extname(storedPath).toLowerCase() === ".metal";
11267
11405
  if (cachedHashMatches && !needsCallGraphRefresh && !requiresSwiftParserUpgrade && !requiresMetalParserUpgrade && !refreshCachedSymbols) {
11268
- unchangedFilePaths.add(canonicalPath);
11406
+ unchangedFilePaths.add(storedPath);
11269
11407
  this.logger.recordCacheHit();
11270
11408
  } else {
11271
11409
  const content = await fsPromises3.readFile(f.path, "utf-8");
11272
- changedFiles.push({ path: canonicalPath, content, hash: currentHash });
11410
+ changedFiles.push({ path: storedPath, content, hash: currentHash });
11273
11411
  this.logger.recordCacheMiss();
11274
11412
  }
11275
11413
  }
@@ -11374,8 +11512,7 @@ var Indexer = class _Indexer {
11374
11512
  for (const parsed of parsedFiles) {
11375
11513
  currentFilePaths.add(parsed.path);
11376
11514
  if (parsed.chunks.length === 0) {
11377
- const relativePath = path18.relative(this.projectRoot, parsed.path);
11378
- stats.parseFailures.push(relativePath);
11515
+ stats.parseFailures.push(path18.isAbsolute(parsed.path) ? path18.relative(this.projectRoot, parsed.path) : parsed.path);
11379
11516
  }
11380
11517
  let chunksToProcess = parsed.chunks;
11381
11518
  if (this.config.indexing.fallbackToTextOnMaxChunks && chunksToProcess.length > this.config.indexing.maxChunksPerFile) {
@@ -12016,6 +12153,43 @@ var Indexer = class _Indexer {
12016
12153
  const union = a.size + b.size - intersection;
12017
12154
  return intersection / union;
12018
12155
  }
12156
+ getBranchPrefilterState(database, branchChunkIds) {
12157
+ const hasInitializedBranchCatalog = branchChunkIds !== null && database.getAllBranches().length > 0;
12158
+ return {
12159
+ hasInitializedBranchCatalog,
12160
+ shouldPrefilterByBranch: branchChunkIds !== null && (this.config.scope === "global" || hasInitializedBranchCatalog)
12161
+ };
12162
+ }
12163
+ searchCandidatesWithBranchPrefilter(initialLimit, totalCount, branchChunkIds, shouldPrefilterByBranch, search, getChunkId) {
12164
+ const normalizedLimit = Math.max(0, Math.floor(initialLimit));
12165
+ if (normalizedLimit === 0) return [];
12166
+ if (!shouldPrefilterByBranch || !branchChunkIds) {
12167
+ return search(normalizedLimit);
12168
+ }
12169
+ const targetCount = Math.min(normalizedLimit, branchChunkIds.size);
12170
+ if (targetCount === 0 || totalCount === 0) return [];
12171
+ let requestedLimit = Math.min(normalizedLimit, totalCount);
12172
+ while (true) {
12173
+ const results = search(requestedLimit);
12174
+ const branchResults = results.filter((candidate) => branchChunkIds.has(getChunkId(candidate)));
12175
+ if (branchResults.length >= targetCount || results.length < requestedLimit || requestedLimit >= totalCount) {
12176
+ return branchResults;
12177
+ }
12178
+ const nextLimit = Math.min(totalCount, Math.max(requestedLimit + 1, requestedLimit * 2));
12179
+ if (nextLimit === requestedLimit) return branchResults;
12180
+ requestedLimit = nextLimit;
12181
+ }
12182
+ }
12183
+ searchSemanticCandidates(store, embedding, initialLimit, branchChunkIds, shouldPrefilterByBranch) {
12184
+ return this.searchCandidatesWithBranchPrefilter(
12185
+ initialLimit,
12186
+ store.count(),
12187
+ branchChunkIds,
12188
+ shouldPrefilterByBranch,
12189
+ (requestedLimit) => store.search(embedding, requestedLimit),
12190
+ (candidate) => candidate.id
12191
+ );
12192
+ }
12019
12193
  async search(query, limit, options) {
12020
12194
  const { store, provider, invertedIndex, database, readIssues, compatibility } = await this.ensureInitialized();
12021
12195
  this.requireReadableComponents(readIssues, "vectors", "database");
@@ -12060,12 +12234,7 @@ var Indexer = class _Indexer {
12060
12234
  });
12061
12235
  }
12062
12236
  const embeddingMs = performance2.now() - embeddingStartTime;
12063
- const vectorStartTime = performance2.now();
12064
- const semanticResults = embedding ? store.search(embedding, maxResults * 4) : [];
12065
- const vectorMs = performance2.now() - vectorStartTime;
12066
- const keywordStartTime = performance2.now();
12067
- const keywordResults = await this.keywordSearch(query, maxResults * 4, store, invertedIndex);
12068
- const keywordMs = performance2.now() - keywordStartTime;
12237
+ const prefilterStartTime = performance2.now();
12069
12238
  let branchChunkIds = null;
12070
12239
  let branchSymbolIds = null;
12071
12240
  if (filterByBranch && (this.config.scope === "global" || this.currentBranch !== "default")) {
@@ -12073,35 +12242,38 @@ var Indexer = class _Indexer {
12073
12242
  branchChunkIds = new Set(branchCatalogKeys.flatMap((branchKey) => database.getBranchChunkIds(branchKey)));
12074
12243
  branchSymbolIds = new Set(branchCatalogKeys.flatMap((branchKey) => database.getBranchSymbolIds(branchKey)));
12075
12244
  }
12076
- const prefilterStartTime = performance2.now();
12077
- const shouldPrefilterByBranch = branchChunkIds !== null && (this.config.scope === "global" || branchChunkIds.size > 0);
12078
- const allowBranchPrefilterFallback = this.config.scope !== "global";
12079
- const prefilteredSemantic = shouldPrefilterByBranch && branchChunkIds ? semanticResults.filter((r) => branchChunkIds.has(r.id)) : semanticResults;
12080
- const prefilteredKeyword = shouldPrefilterByBranch && branchChunkIds ? keywordResults.filter((r) => branchChunkIds.has(r.id)) : keywordResults;
12081
- const semanticCandidates = allowBranchPrefilterFallback && shouldPrefilterByBranch && semanticResults.length > 0 && prefilteredSemantic.length === 0 ? semanticResults : prefilteredSemantic;
12082
- const keywordCandidates = allowBranchPrefilterFallback && shouldPrefilterByBranch && keywordResults.length > 0 && prefilteredKeyword.length === 0 ? keywordResults : prefilteredKeyword;
12245
+ const { hasInitializedBranchCatalog, shouldPrefilterByBranch } = this.getBranchPrefilterState(database, branchChunkIds);
12246
+ const prefilterMs = performance2.now() - prefilterStartTime;
12247
+ const vectorStartTime = performance2.now();
12248
+ const semanticCandidates = embedding ? this.searchSemanticCandidates(
12249
+ store,
12250
+ embedding,
12251
+ maxResults * 4,
12252
+ branchChunkIds,
12253
+ shouldPrefilterByBranch
12254
+ ) : [];
12255
+ const vectorMs = performance2.now() - vectorStartTime;
12256
+ const keywordStartTime = performance2.now();
12257
+ const keywordCandidates = await this.keywordSearch(
12258
+ query,
12259
+ maxResults * 4,
12260
+ store,
12261
+ invertedIndex,
12262
+ branchChunkIds,
12263
+ shouldPrefilterByBranch
12264
+ );
12265
+ const keywordMs = performance2.now() - keywordStartTime;
12083
12266
  const scopedSemanticCandidates = semanticCandidates.filter(
12084
- (candidate) => matchesHardSearchFilters(candidate, options)
12267
+ (candidate) => matchesHardSearchFilters(candidate, options, this.projectRoot)
12085
12268
  );
12086
12269
  const scopedKeywordCandidates = keywordCandidates.filter(
12087
- (candidate) => matchesHardSearchFilters(candidate, options)
12270
+ (candidate) => matchesHardSearchFilters(candidate, options, this.projectRoot)
12088
12271
  );
12089
- const prefilterMs = performance2.now() - prefilterStartTime;
12090
- if (this.config.scope !== "global" && branchChunkIds && branchChunkIds.size === 0) {
12272
+ if (this.config.scope !== "global" && branchChunkIds && !hasInitializedBranchCatalog) {
12091
12273
  this.logger.search("warn", "Branch prefilter skipped because branch catalog is empty", {
12092
12274
  branch: this.currentBranch
12093
12275
  });
12094
12276
  }
12095
- if (allowBranchPrefilterFallback && shouldPrefilterByBranch && semanticResults.length > 0 && prefilteredSemantic.length === 0) {
12096
- this.logger.search("warn", "Branch prefilter produced no semantic overlap, using unfiltered semantic candidates", {
12097
- branch: this.currentBranch
12098
- });
12099
- }
12100
- if (allowBranchPrefilterFallback && shouldPrefilterByBranch && keywordResults.length > 0 && prefilteredKeyword.length === 0) {
12101
- this.logger.search("warn", "Branch prefilter produced no keyword overlap, using unfiltered keyword candidates", {
12102
- branch: this.currentBranch
12103
- });
12104
- }
12105
12277
  const fusionStartTime = performance2.now();
12106
12278
  const rankingHybridWeight = embedding === void 0 && fusionStrategy === "weighted" ? 1 : effectiveHybridWeight;
12107
12279
  const combined = rankHybridResults(query, scopedSemanticCandidates, scopedKeywordCandidates, {
@@ -12152,12 +12324,14 @@ var Indexer = class _Indexer {
12152
12324
  const primaryLane = mergeTieredResults(prePrimaryLane, symbolLane, maxResults * 4);
12153
12325
  const tiered = mergeTieredResults(primaryLane, rescued, maxResults * 4);
12154
12326
  const hasCodeHints = extractCodeTermHints(query).length > 0 || identifierHints.length > 0;
12155
- const baseFiltered = tiered.filter((r) => matchesSearchFilters(r, options, this.config.search.minScore));
12327
+ const baseFiltered = tiered.filter(
12328
+ (r) => matchesSearchFilters(r, options, this.config.search.minScore, this.projectRoot)
12329
+ );
12156
12330
  const implementationOnly = baseFiltered.filter(
12157
12331
  (r) => isLikelyImplementationPath2(r.metadata.filePath) && isImplementationChunkType(r.metadata.chunkType)
12158
12332
  );
12159
12333
  const filtered = (sourceIntent && hasCodeHints && implementationOnly.length > 0 ? implementationOnly : baseFiltered).slice(0, maxResults);
12160
- 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) : [];
12334
+ 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) : [];
12161
12335
  const finalResults = filtered.length > 0 ? filtered : identifierFallback;
12162
12336
  const totalSearchMs = performance2.now() - searchStartTime;
12163
12337
  this.logger.recordSearch(totalSearchMs, {
@@ -12182,10 +12356,11 @@ var Indexer = class _Indexer {
12182
12356
  let content = "";
12183
12357
  let contextStartLine = r.metadata.startLine;
12184
12358
  let contextEndLine = r.metadata.endLine;
12359
+ const resolvedFilePath = this.resolveStoredFilePath(r.metadata.filePath);
12185
12360
  if (!metadataOnly && this.config.search.includeContext) {
12186
12361
  try {
12187
12362
  const fileContent = await fsPromises3.readFile(
12188
- r.metadata.filePath,
12363
+ resolvedFilePath,
12189
12364
  "utf-8"
12190
12365
  );
12191
12366
  const lines = fileContent.split("\n");
@@ -12198,7 +12373,7 @@ var Indexer = class _Indexer {
12198
12373
  }
12199
12374
  }
12200
12375
  return {
12201
- filePath: r.metadata.filePath,
12376
+ filePath: resolvedFilePath,
12202
12377
  startLine: contextStartLine,
12203
12378
  endLine: contextEndLine,
12204
12379
  content,
@@ -12210,8 +12385,18 @@ var Indexer = class _Indexer {
12210
12385
  })
12211
12386
  );
12212
12387
  }
12213
- async keywordSearch(query, limit, store, invertedIndex) {
12214
- const scores = invertedIndex.search(query);
12388
+ async keywordSearch(query, limit, store, invertedIndex, branchChunkIds = null, shouldPrefilterByBranch = false) {
12389
+ const normalizedLimit = Math.max(0, Math.floor(limit));
12390
+ if (normalizedLimit === 0) return [];
12391
+ const scoreEntries = this.searchCandidatesWithBranchPrefilter(
12392
+ normalizedLimit,
12393
+ invertedIndex.getDocumentCount(),
12394
+ branchChunkIds,
12395
+ shouldPrefilterByBranch,
12396
+ (requestedLimit) => Array.from(invertedIndex.search(query, requestedLimit)),
12397
+ ([chunkId]) => chunkId
12398
+ );
12399
+ const scores = new Map(scoreEntries);
12215
12400
  if (scores.size === 0) {
12216
12401
  return [];
12217
12402
  }
@@ -12225,7 +12410,7 @@ var Indexer = class _Indexer {
12225
12410
  }
12226
12411
  }
12227
12412
  results.sort((a, b) => b.score - a.score);
12228
- return results.slice(0, limit);
12413
+ return results.slice(0, normalizedLimit);
12229
12414
  }
12230
12415
  async getStatus() {
12231
12416
  const { store, configuredProviderInfo, database, readIssues, compatibility } = await this.ensureInitialized();
@@ -12292,7 +12477,7 @@ var Indexer = class _Indexer {
12292
12477
  );
12293
12478
  const currentFileHashes = /* @__PURE__ */ new Map();
12294
12479
  for (const file of files) {
12295
- currentFileHashes.set(this.toCanonicalFilePath(file.path), hashFile(file.path));
12480
+ currentFileHashes.set(this.toStoredFilePath(file.path), hashFile(file.path));
12296
12481
  }
12297
12482
  const scopedRoots = this.config.scope === "global" ? this.getScopedRoots() : null;
12298
12483
  const cachedFileHashes = scopedRoots ? new Map(Array.from(this.fileHashCache).filter(([filePath]) => this.isFileInCurrentScope(filePath, scopedRoots))) : this.fileHashCache;
@@ -12304,17 +12489,7 @@ var Indexer = class _Indexer {
12304
12489
  return { readable: true, current: false, reason: "files-changed" };
12305
12490
  }
12306
12491
  }
12307
- const hasSwiftFiles = Array.from(currentFileHashes.keys()).some(
12308
- (filePath) => path18.extname(filePath).toLowerCase() === ".swift"
12309
- );
12310
- const hasMetalFiles = Array.from(currentFileHashes.keys()).some(
12311
- (filePath) => path18.extname(filePath).toLowerCase() === ".metal"
12312
- );
12313
- const hasCallGraphMigrationFiles = Array.from(currentFileHashes.keys()).some((filePath) => {
12314
- const extension = path18.extname(filePath).toLowerCase();
12315
- return extension === ".php" || extension === ".c" || extension === ".cc" || extension === ".cpp" || extension === ".cxx";
12316
- });
12317
- 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) {
12492
+ if (!this.areBranchMigrationVersionsCurrent(database)) {
12318
12493
  return { readable: true, current: false, reason: "migration-required" };
12319
12494
  }
12320
12495
  if (isGitRepo(this.materializedProjectRoot)) {
@@ -12374,6 +12549,7 @@ var Indexer = class _Indexer {
12374
12549
  this.deleteBranchCommitMetadata(database, clearedBranchKeys2);
12375
12550
  this.saveFailedBatches([]);
12376
12551
  database.deleteMetadata("index.version");
12552
+ database.deleteMetadata("index.pathStorageVersion");
12377
12553
  database.deleteMetadata("index.embeddingProvider");
12378
12554
  database.deleteMetadata("index.embeddingModel");
12379
12555
  database.deleteMetadata("index.embeddingDimensions");
@@ -12392,7 +12568,7 @@ var Indexer = class _Indexer {
12392
12568
  this.indexCompatibility = compatibility;
12393
12569
  return;
12394
12570
  }
12395
- if (!this.isLocalProjectIndexPath()) {
12571
+ if (!this.isProjectOwnedIndexPath()) {
12396
12572
  throw new Error(
12397
12573
  "Project-scoped force rebuild is unsafe while using an inherited worktree index. Create a local project config boundary before clearing the index."
12398
12574
  );
@@ -12403,11 +12579,11 @@ var Indexer = class _Indexer {
12403
12579
  invertedIndex.clear();
12404
12580
  this.saveInvertedIndex(invertedIndex);
12405
12581
  this.fileHashCache.clear();
12406
- this.saveFileHashCache();
12582
+ await this.removeProjectRuntimeStateArtifacts();
12407
12583
  database.clearAllIndexedData();
12408
12584
  this.deleteBranchCommitMetadata(database, clearedBranchKeys);
12409
- this.saveFailedBatches([]);
12410
12585
  database.deleteMetadata("index.version");
12586
+ database.deleteMetadata("index.pathStorageVersion");
12411
12587
  database.deleteMetadata("index.embeddingProvider");
12412
12588
  database.deleteMetadata("index.embeddingModel");
12413
12589
  database.deleteMetadata("index.embeddingDimensions");
@@ -12435,32 +12611,46 @@ var Indexer = class _Indexer {
12435
12611
  existing.push(key);
12436
12612
  filePathsToChunkKeys.set(metadata.filePath, existing);
12437
12613
  }
12438
- const removedFilePaths = [];
12439
- const removedChunkKeys = [];
12614
+ const missingStoredFilePaths = [];
12615
+ const missingChunkKeys = [];
12440
12616
  const chunkKeysByRemovedFile = /* @__PURE__ */ new Map();
12441
12617
  for (const [filePath, chunkKeys] of filePathsToChunkKeys) {
12442
- if (!existsSync10(filePath)) {
12618
+ if (!existsSync10(this.toMaterializedFilePath(filePath))) {
12443
12619
  chunkKeysByRemovedFile.set(filePath, chunkKeys);
12444
12620
  for (const key of chunkKeys) {
12445
- removedChunkKeys.push(key);
12621
+ missingChunkKeys.push(key);
12446
12622
  }
12447
- removedFilePaths.push(filePath);
12623
+ missingStoredFilePaths.push(filePath);
12448
12624
  }
12449
12625
  }
12626
+ const branchCatalogKeys = this.getBranchCatalogKeys();
12627
+ for (const branchKey of branchCatalogKeys) {
12628
+ database.deleteBranchChunksForBranch(branchKey, missingChunkKeys);
12629
+ }
12630
+ const referencedChunkKeys = new Set(database.getReferencedChunkIds(missingChunkKeys));
12631
+ const removedChunkKeys = missingChunkKeys.filter((key) => !referencedChunkKeys.has(key));
12450
12632
  if (removedChunkKeys.length > 0) {
12451
12633
  this.rebuildVectorStoreExcludingChunkIds(store, database, removedChunkKeys);
12452
12634
  for (const key of removedChunkKeys) {
12453
12635
  invertedIndex.removeChunk(key);
12454
12636
  }
12637
+ database.deleteChunksByIds(removedChunkKeys);
12455
12638
  }
12456
- for (const filePath of removedFilePaths) {
12457
- const fileChunkKeys = chunkKeysByRemovedFile.get(filePath) ?? [];
12458
- if (fileChunkKeys.length > 0) {
12459
- database.deleteChunksByIds(fileChunkKeys);
12460
- }
12461
- database.deleteCallEdgesByFile(filePath);
12462
- database.deleteSymbolsByFile(filePath);
12463
- }
12639
+ const missingSymbolIds = Array.from(new Set(
12640
+ missingStoredFilePaths.flatMap(
12641
+ (filePath) => database.getSymbolsByFile(filePath).map((symbol) => symbol.id)
12642
+ )
12643
+ ));
12644
+ for (const branchKey of branchCatalogKeys) {
12645
+ database.deleteBranchSymbolsForBranch(branchKey, missingSymbolIds);
12646
+ }
12647
+ const referencedSymbolIds = new Set(database.getReferencedSymbolIds(missingSymbolIds));
12648
+ const removedSymbolIds = missingSymbolIds.filter((symbolId) => !referencedSymbolIds.has(symbolId));
12649
+ database.clearCallEdgeTargetsForSymbols(removedSymbolIds);
12650
+ const removedChunkKeySet = new Set(removedChunkKeys);
12651
+ const removedStoredFilePaths = missingStoredFilePaths.filter(
12652
+ (filePath) => (chunkKeysByRemovedFile.get(filePath) ?? []).some((key) => removedChunkKeySet.has(key))
12653
+ );
12464
12654
  const removedCount = removedChunkKeys.length;
12465
12655
  if (removedCount > 0) {
12466
12656
  store.save();
@@ -12496,9 +12686,16 @@ var Indexer = class _Indexer {
12496
12686
  removedStale: removedCount,
12497
12687
  orphanEmbeddings: gcOrphanEmbeddings,
12498
12688
  orphanChunks: gcOrphanChunks,
12499
- removedFiles: removedFilePaths.length
12689
+ removedFiles: removedStoredFilePaths.length
12500
12690
  });
12501
- return { removed: removedCount, filePaths: removedFilePaths, gcOrphanEmbeddings, gcOrphanChunks, gcOrphanSymbols, gcOrphanCallEdges };
12691
+ return {
12692
+ removed: removedCount,
12693
+ filePaths: removedStoredFilePaths.map((filePath) => this.resolveStoredFilePath(filePath)),
12694
+ gcOrphanEmbeddings,
12695
+ gcOrphanChunks,
12696
+ gcOrphanSymbols,
12697
+ gcOrphanCallEdges
12698
+ };
12502
12699
  }
12503
12700
  async retryFailedBatches() {
12504
12701
  return this.withIndexMutationLease("retry-failed-batches", async (recoveredOwners) => {
@@ -12693,9 +12890,18 @@ var Indexer = class _Indexer {
12693
12890
  return this.baseBranch;
12694
12891
  }
12695
12892
  refreshBranchInfo() {
12893
+ const previousBranch = this.currentBranch;
12696
12894
  if (isGitRepo(this.materializedProjectRoot)) {
12697
12895
  this.currentBranch = this.branchNameOverride ?? getBranchOrDefault(this.materializedProjectRoot);
12698
12896
  this.baseBranch = getBaseBranch(this.materializedProjectRoot);
12897
+ } else {
12898
+ this.currentBranch = "default";
12899
+ this.baseBranch = "default";
12900
+ }
12901
+ if (this.currentBranch !== previousBranch) {
12902
+ this.refreshRuntimeArtifactPaths();
12903
+ this.fileHashCache.clear();
12904
+ this.loadFileHashCache();
12699
12905
  }
12700
12906
  }
12701
12907
  async getDatabaseStats() {
@@ -12720,6 +12926,7 @@ var Indexer = class _Indexer {
12720
12926
  return [];
12721
12927
  }
12722
12928
  const filterByBranch = options?.filterByBranch ?? true;
12929
+ const excludedStoredFile = options?.excludeFile ? this.toStoredFilePath(options.excludeFile) : void 0;
12723
12930
  this.logger.search("debug", "Starting find similar", {
12724
12931
  codeLength: code.length,
12725
12932
  limit,
@@ -12729,31 +12936,29 @@ var Indexer = class _Indexer {
12729
12936
  const { embedding, tokensUsed } = await provider.embedDocument(code);
12730
12937
  const embeddingMs = performance2.now() - embeddingStartTime;
12731
12938
  this.logger.recordEmbeddingApiCall(tokensUsed);
12732
- const vectorStartTime = performance2.now();
12733
- const semanticResults = store.search(embedding, limit * 2);
12734
- const vectorMs = performance2.now() - vectorStartTime;
12939
+ const prefilterStartTime = performance2.now();
12735
12940
  let branchChunkIds = null;
12736
12941
  if (filterByBranch && (this.config.scope === "global" || this.currentBranch !== "default")) {
12737
12942
  branchChunkIds = new Set(
12738
12943
  this.getBranchCatalogKeys().flatMap((branchKey) => database.getBranchChunkIds(branchKey))
12739
12944
  );
12740
12945
  }
12741
- const prefilterStartTime = performance2.now();
12742
- const shouldPrefilterByBranch = branchChunkIds !== null && (this.config.scope === "global" || branchChunkIds.size > 0);
12743
- const allowBranchPrefilterFallback = this.config.scope !== "global";
12744
- const prefilteredSemantic = shouldPrefilterByBranch && branchChunkIds ? semanticResults.filter((r) => branchChunkIds.has(r.id)) : semanticResults;
12745
- const semanticCandidates = allowBranchPrefilterFallback && shouldPrefilterByBranch && semanticResults.length > 0 && prefilteredSemantic.length === 0 ? semanticResults : prefilteredSemantic;
12946
+ const { hasInitializedBranchCatalog, shouldPrefilterByBranch } = this.getBranchPrefilterState(database, branchChunkIds);
12746
12947
  const prefilterMs = performance2.now() - prefilterStartTime;
12747
- if (this.config.scope !== "global" && branchChunkIds && branchChunkIds.size === 0) {
12948
+ const vectorStartTime = performance2.now();
12949
+ const semanticCandidates = this.searchSemanticCandidates(
12950
+ store,
12951
+ embedding,
12952
+ limit * 2,
12953
+ branchChunkIds,
12954
+ shouldPrefilterByBranch
12955
+ );
12956
+ const vectorMs = performance2.now() - vectorStartTime;
12957
+ if (this.config.scope !== "global" && branchChunkIds && !hasInitializedBranchCatalog) {
12748
12958
  this.logger.search("warn", "Branch prefilter skipped because branch catalog is empty", {
12749
12959
  branch: this.currentBranch
12750
12960
  });
12751
12961
  }
12752
- if (allowBranchPrefilterFallback && shouldPrefilterByBranch && semanticResults.length > 0 && prefilteredSemantic.length === 0) {
12753
- this.logger.search("warn", "Branch prefilter produced no semantic overlap, using unfiltered semantic candidates", {
12754
- branch: this.currentBranch
12755
- });
12756
- }
12757
12962
  const rerankTopN = this.config.search.rerankTopN;
12758
12963
  const ranked = rankSemanticOnlyResults(code, semanticCandidates, {
12759
12964
  rerankTopN,
@@ -12762,21 +12967,10 @@ var Indexer = class _Indexer {
12762
12967
  });
12763
12968
  const filtered = ranked.filter((r) => {
12764
12969
  if (r.score < this.config.search.minScore) return false;
12765
- if (options?.excludeFile) {
12766
- if (r.metadata.filePath === options.excludeFile) return false;
12767
- }
12768
- if (options?.fileType) {
12769
- const ext = r.metadata.filePath.split(".").pop()?.toLowerCase();
12770
- if (ext !== options.fileType.toLowerCase().replace(/^\./, "")) return false;
12970
+ if (excludedStoredFile) {
12971
+ if (r.metadata.filePath === excludedStoredFile) return false;
12771
12972
  }
12772
- if (options?.directory) {
12773
- const normalizedDir = options.directory.replace(/^\/|\/$/g, "");
12774
- if (!r.metadata.filePath.includes(`/${normalizedDir}/`) && !r.metadata.filePath.includes(`${normalizedDir}/`)) return false;
12775
- }
12776
- if (options?.chunkType) {
12777
- if (r.metadata.chunkType !== options.chunkType) return false;
12778
- }
12779
- return true;
12973
+ return matchesHardSearchFilters(r, options, this.projectRoot);
12780
12974
  }).slice(0, limit);
12781
12975
  const totalSearchMs = performance2.now() - searchStartTime;
12782
12976
  this.logger.recordSearch(totalSearchMs, {
@@ -12796,10 +12990,11 @@ var Indexer = class _Indexer {
12796
12990
  return Promise.all(
12797
12991
  filtered.map(async (r) => {
12798
12992
  let content = "";
12993
+ const resolvedFilePath = this.resolveStoredFilePath(r.metadata.filePath);
12799
12994
  if (this.config.search.includeContext) {
12800
12995
  try {
12801
12996
  const fileContent = await fsPromises3.readFile(
12802
- r.metadata.filePath,
12997
+ resolvedFilePath,
12803
12998
  "utf-8"
12804
12999
  );
12805
13000
  const lines = fileContent.split("\n");
@@ -12809,7 +13004,7 @@ var Indexer = class _Indexer {
12809
13004
  }
12810
13005
  }
12811
13006
  return {
12812
- filePath: r.metadata.filePath,
13007
+ filePath: resolvedFilePath,
12813
13008
  startLine: r.metadata.startLine,
12814
13009
  endLine: r.metadata.endLine,
12815
13010
  content,
@@ -12830,7 +13025,7 @@ var Indexer = class _Indexer {
12830
13025
  for (const edge of database.getCallersWithContext(targetName, branchKey, callTypeFilter)) {
12831
13026
  if (!seen.has(edge.id)) {
12832
13027
  seen.add(edge.id);
12833
- results.push(edge);
13028
+ results.push(this.resolveCallEdgeFilePath(edge));
12834
13029
  }
12835
13030
  }
12836
13031
  }
@@ -12849,7 +13044,7 @@ var Indexer = class _Indexer {
12849
13044
  const safelyMatchesUnresolvedSymbol = includeUnresolved && !edge.toSymbolId;
12850
13045
  if (!matchesResolvedSymbol && !safelyMatchesUnresolvedSymbol || seen.has(edge.id)) continue;
12851
13046
  seen.add(edge.id);
12852
- results.push(edge);
13047
+ results.push(this.resolveCallEdgeFilePath(edge));
12853
13048
  }
12854
13049
  }
12855
13050
  return results;
@@ -12863,7 +13058,7 @@ var Indexer = class _Indexer {
12863
13058
  for (const edge of database.getCallees(symbolId, branchKey, callTypeFilter)) {
12864
13059
  if (!seen.has(edge.id)) {
12865
13060
  seen.add(edge.id);
12866
- results.push(edge);
13061
+ results.push(this.resolveCallEdgeFilePath(edge));
12867
13062
  }
12868
13063
  }
12869
13064
  }
@@ -12879,7 +13074,7 @@ var Indexer = class _Indexer {
12879
13074
  shortest = path20;
12880
13075
  }
12881
13076
  }
12882
- return shortest;
13077
+ return shortest.map((hop) => this.resolveFilePathRecord(hop));
12883
13078
  }
12884
13079
  async findCallPathBySymbolIds(fromSymbolId, toSymbolId, maxDepth = 10) {
12885
13080
  const { database, readIssues } = await this.ensureInitialized();
@@ -12945,7 +13140,7 @@ var Indexer = class _Indexer {
12945
13140
  shortest = path20;
12946
13141
  }
12947
13142
  }
12948
- return shortest;
13143
+ return shortest.map((hop) => this.resolveFilePathRecord(hop));
12949
13144
  }
12950
13145
  async getCallGraphSymbols() {
12951
13146
  const { database, readIssues } = await this.ensureInitialized();
@@ -12953,7 +13148,7 @@ var Indexer = class _Indexer {
12953
13148
  const symbols = /* @__PURE__ */ new Map();
12954
13149
  for (const branchKey of this.getBranchCatalogKeys()) {
12955
13150
  for (const symbol of database.getSymbolsForBranch(branchKey)) {
12956
- symbols.set(symbol.id, symbol);
13151
+ symbols.set(symbol.id, this.resolveFilePathRecord(symbol));
12957
13152
  }
12958
13153
  }
12959
13154
  return [...symbols.values()];
@@ -12962,31 +13157,32 @@ var Indexer = class _Indexer {
12962
13157
  const { database, readIssues } = await this.ensureInitialized();
12963
13158
  this.requireReadableComponents(readIssues, "database");
12964
13159
  const resolvedBranch = branch ?? this.getBranchCatalogKey();
12965
- return database.getSymbolsForBranch(resolvedBranch);
13160
+ return database.getSymbolsForBranch(resolvedBranch).map((symbol) => this.resolveFilePathRecord(symbol));
12966
13161
  }
12967
13162
  async getSymbolsForFiles(filePaths, branch) {
12968
13163
  const { database, readIssues } = await this.ensureInitialized();
12969
13164
  this.requireReadableComponents(readIssues, "database");
12970
13165
  const resolvedBranch = branch ?? this.getBranchCatalogKey();
12971
- return database.getSymbolsForFiles(filePaths, resolvedBranch);
13166
+ const storedFilePaths = filePaths.map((filePath) => this.toStoredFilePath(filePath));
13167
+ return database.getSymbolsForFiles(storedFilePaths, resolvedBranch).map((symbol) => this.resolveFilePathRecord(symbol));
12972
13168
  }
12973
13169
  async getTransitiveReachability(rootSymbolIds, direction, maxDepth) {
12974
13170
  const { database, readIssues } = await this.ensureInitialized();
12975
13171
  this.requireReadableComponents(readIssues, "database");
12976
13172
  const branch = this.getBranchCatalogKey();
12977
- return database.getTransitiveReachability(rootSymbolIds, branch, direction, maxDepth);
13173
+ return database.getTransitiveReachability(rootSymbolIds, branch, direction, maxDepth).map((entry) => this.resolveFilePathRecord(entry));
12978
13174
  }
12979
13175
  async detectCommunities(branch, symbolIds) {
12980
13176
  const { database, readIssues } = await this.ensureInitialized();
12981
13177
  this.requireReadableComponents(readIssues, "database");
12982
13178
  const resolvedBranch = branch ?? this.getBranchCatalogKey();
12983
- return database.detectCommunities(resolvedBranch, symbolIds);
13179
+ return database.detectCommunities(resolvedBranch, symbolIds).map((entry) => this.resolveFilePathRecord(entry));
12984
13180
  }
12985
13181
  async computeCentrality(branch) {
12986
13182
  const { database, readIssues } = await this.ensureInitialized();
12987
13183
  this.requireReadableComponents(readIssues, "database");
12988
13184
  const resolvedBranch = branch ?? this.getBranchCatalogKey();
12989
- return database.computeCentrality(resolvedBranch);
13185
+ return database.computeCentrality(resolvedBranch).map((entry) => this.resolveFilePathRecord(entry));
12990
13186
  }
12991
13187
  async getPrImpact(opts, onPreparationProgress) {
12992
13188
  const initialState = await this.ensureInitialized();
@@ -13022,10 +13218,8 @@ var Indexer = class _Indexer {
13022
13218
  const requestedRef = opts.pr !== void 0 ? expectedCommit : headRefName ?? resolvedBranch;
13023
13219
  const storedCommit = this.getStoredBranchCommit(database, catalogIdentity);
13024
13220
  const catalogIdentityMatches = storedCommit === expectedCommit;
13025
- const symbolsCurrent = database.getMetadata(
13026
- this.getSymbolExtractorVersionMetadataKey(catalogIdentity)
13027
- ) === SYMBOL_EXTRACTOR_VERSION;
13028
- if (branchSymbols.length === 0 || !catalogIdentityMatches || !symbolsCurrent) {
13221
+ const migrationsCurrent = this.areBranchMigrationVersionsCurrent(database, catalogIdentity);
13222
+ if (branchSymbols.length === 0 || !catalogIdentityMatches || !migrationsCurrent) {
13029
13223
  if (!resolvedBranch || resolvedBranch === "default") {
13030
13224
  throw new Error("Run index_codebase first to build the call graph and symbol index for this project.");
13031
13225
  }
@@ -13081,8 +13275,9 @@ var Indexer = class _Indexer {
13081
13275
  );
13082
13276
  }
13083
13277
  }
13084
- const absoluteChangedFiles = changedFiles.map((f) => path18.resolve(this.projectRoot, f));
13085
- const directSymbols = database.getSymbolsForFiles(absoluteChangedFiles, branchKey);
13278
+ const toStoredChangedFiles = (filePaths) => filePaths.map((filePath) => this.toStoredFilePath(path18.resolve(this.projectRoot, filePath)));
13279
+ const storedChangedFiles = toStoredChangedFiles(changedFiles);
13280
+ const directSymbols = database.getSymbolsForFiles(storedChangedFiles, branchKey);
13086
13281
  const directIds = directSymbols.map((s) => s.id);
13087
13282
  const direction = opts.direction ?? "both";
13088
13283
  const maxDepth = opts.maxDepth ?? 5;
@@ -13124,7 +13319,7 @@ var Indexer = class _Indexer {
13124
13319
  id: c.symbolId,
13125
13320
  name: c.symbolName,
13126
13321
  callerCount: c.callerCount,
13127
- filePath: c.filePath
13322
+ filePath: this.resolveStoredFilePath(c.filePath)
13128
13323
  }));
13129
13324
  const totalAffected = allAffectedIds.length;
13130
13325
  let riskLevel;
@@ -13164,9 +13359,9 @@ var Indexer = class _Indexer {
13164
13359
  projectRoot: this.projectRoot,
13165
13360
  baseBranch: this.baseBranch
13166
13361
  });
13167
- const otherAbsolute = otherChanged.files.map((f) => path18.resolve(this.projectRoot, f));
13362
+ const otherStored = toStoredChangedFiles(otherChanged.files);
13168
13363
  const prBranchKey = this.getBranchCatalogKeyFor(otherChanged.catalogIdentity);
13169
- const otherSymbols = database.getSymbolsForFiles(otherAbsolute, prBranchKey);
13364
+ const otherSymbols = database.getSymbolsForFiles(otherStored, prBranchKey);
13170
13365
  const otherLabels = /* @__PURE__ */ new Set();
13171
13366
  for (const sym of otherSymbols) {
13172
13367
  const label = symbolToCommunity.get(structuralKey(sym.filePath, sym.name));
@@ -13197,12 +13392,12 @@ var Indexer = class _Indexer {
13197
13392
  id: s.id,
13198
13393
  name: s.name,
13199
13394
  kind: s.kind,
13200
- filePath: s.filePath
13395
+ filePath: this.resolveStoredFilePath(s.filePath)
13201
13396
  })),
13202
13397
  transitiveCallers: transitiveCallers.map((c) => ({
13203
13398
  id: c.symbolId,
13204
13399
  name: c.symbolName,
13205
- filePath: c.filePath,
13400
+ filePath: this.resolveStoredFilePath(c.filePath),
13206
13401
  depth: c.depth
13207
13402
  })),
13208
13403
  totalAffected,
@@ -13232,7 +13427,7 @@ var Indexer = class _Indexer {
13232
13427
  const absoluteDirectoryFilter = directory ? path18.resolve(this.projectRoot, directory) : void 0;
13233
13428
  for (const filePath of filePaths) {
13234
13429
  if (directory) {
13235
- const absoluteFilePath = path18.resolve(filePath);
13430
+ const absoluteFilePath = this.resolveStoredFilePath(filePath);
13236
13431
  const matchesRelative = filePath === directory || filePath.startsWith(directory + "/");
13237
13432
  const matchesProjectRelative = absoluteDirectoryFilter !== void 0 && (absoluteFilePath === absoluteDirectoryFilter || absoluteFilePath.startsWith(absoluteDirectoryFilter + path18.sep));
13238
13433
  if (!matchesRelative && !matchesProjectRelative) {
@@ -13241,14 +13436,14 @@ var Indexer = class _Indexer {
13241
13436
  }
13242
13437
  for (const sym of database.getSymbolsByFile(filePath)) {
13243
13438
  if (symbolIdSet.has(sym.id) && !seenSymbols.has(sym.id)) {
13244
- seenSymbols.set(sym.id, sym);
13439
+ seenSymbols.set(sym.id, this.resolveFilePathRecord(sym));
13245
13440
  }
13246
13441
  }
13247
13442
  }
13248
13443
  for (const symbolId of seenSymbols.keys()) {
13249
13444
  for (const edge of database.getCallees(symbolId, branchKey)) {
13250
13445
  if (!seenEdges.has(edge.id)) {
13251
- seenEdges.set(edge.id, edge);
13446
+ seenEdges.set(edge.id, this.resolveCallEdgeFilePath(edge));
13252
13447
  }
13253
13448
  }
13254
13449
  }
@@ -13355,7 +13550,7 @@ function getOrCreateIndexer(projectRoot3, host) {
13355
13550
  configureAutoIndex(projectRoot3, host, config, () => getOrCreateIndexer(projectRoot3, host));
13356
13551
  return indexer;
13357
13552
  }
13358
- function getIndexerForProject(projectRoot3, host = "opencode") {
13553
+ function getIndexerForProject(projectRoot3, host) {
13359
13554
  const root = getProjectRoot(projectRoot3, host);
13360
13555
  return getOrCreateIndexer(root, host);
13361
13556
  }
@@ -13363,7 +13558,7 @@ function recordToolEffectiveness(projectRoot3, host, event) {
13363
13558
  if (!isToolEffectivenessEnabled(projectRoot3, host)) return;
13364
13559
  safelyRecordToolEffectiveness(event);
13365
13560
  }
13366
- function refreshIndexerForDirectory(projectRoot3, host = "opencode", config = parseConfig(loadRuntimeConfig(projectRoot3, host))) {
13561
+ function refreshIndexerForDirectory(projectRoot3, host, config = parseConfig(loadRuntimeConfig(projectRoot3, host))) {
13367
13562
  const key = getIndexerCacheKey(projectRoot3, host);
13368
13563
  configCache.set(key, config);
13369
13564
  indexerCache.set(key, new Indexer(projectRoot3, config, host));
@@ -14473,8 +14668,86 @@ async function resolveCodebaseContext(projectRoot3, host, input) {
14473
14668
  }
14474
14669
  }
14475
14670
 
14476
- // src/pi-call-graph.ts
14671
+ // src/adapters/pi/call-graph.ts
14477
14672
  import { Type } from "typebox";
14673
+
14674
+ // src/tools/tool-names.ts
14675
+ var TOOL_NAME = {
14676
+ CODEBASE_CONTEXT: "codebase_context",
14677
+ CODEBASE_SEARCH: "codebase_search",
14678
+ CODEBASE_PEEK: "codebase_peek",
14679
+ FIND_SIMILAR: "find_similar",
14680
+ IMPLEMENTATION_LOOKUP: "implementation_lookup",
14681
+ INDEX_CODEBASE: "index_codebase",
14682
+ INDEX_STATUS: "index_status",
14683
+ INDEX_HEALTH_CHECK: "index_health_check",
14684
+ INDEX_METRICS: "index_metrics",
14685
+ INDEX_LOGS: "index_logs",
14686
+ CALL_GRAPH: "call_graph",
14687
+ CALL_GRAPH_PATH: "call_graph_path",
14688
+ PR_IMPACT: "pr_impact",
14689
+ ADD_KNOWLEDGE_BASE: "add_knowledge_base",
14690
+ LIST_KNOWLEDGE_BASES: "list_knowledge_bases",
14691
+ REMOVE_KNOWLEDGE_BASE: "remove_knowledge_base",
14692
+ PI_KNOWLEDGE_BASE_ADD: "knowledge_base_add",
14693
+ PI_KNOWLEDGE_BASE_LIST: "knowledge_base_list",
14694
+ PI_KNOWLEDGE_BASE_REMOVE: "knowledge_base_remove",
14695
+ INDEX_VISUALIZE: "index_visualize"
14696
+ };
14697
+ var PORTABLE_TOOL_NAMES = [
14698
+ TOOL_NAME.CODEBASE_CONTEXT,
14699
+ TOOL_NAME.CODEBASE_SEARCH,
14700
+ TOOL_NAME.CODEBASE_PEEK,
14701
+ TOOL_NAME.INDEX_CODEBASE,
14702
+ TOOL_NAME.INDEX_STATUS,
14703
+ TOOL_NAME.INDEX_HEALTH_CHECK,
14704
+ TOOL_NAME.INDEX_METRICS,
14705
+ TOOL_NAME.INDEX_LOGS,
14706
+ TOOL_NAME.FIND_SIMILAR,
14707
+ TOOL_NAME.IMPLEMENTATION_LOOKUP,
14708
+ TOOL_NAME.CALL_GRAPH,
14709
+ TOOL_NAME.CALL_GRAPH_PATH,
14710
+ TOOL_NAME.PR_IMPACT
14711
+ ];
14712
+ var OPENCODE_TOOL_NAMES = [
14713
+ TOOL_NAME.CODEBASE_CONTEXT,
14714
+ TOOL_NAME.CODEBASE_SEARCH,
14715
+ TOOL_NAME.CODEBASE_PEEK,
14716
+ TOOL_NAME.INDEX_CODEBASE,
14717
+ TOOL_NAME.INDEX_STATUS,
14718
+ TOOL_NAME.INDEX_HEALTH_CHECK,
14719
+ TOOL_NAME.INDEX_METRICS,
14720
+ TOOL_NAME.INDEX_LOGS,
14721
+ TOOL_NAME.FIND_SIMILAR,
14722
+ TOOL_NAME.CALL_GRAPH,
14723
+ TOOL_NAME.CALL_GRAPH_PATH,
14724
+ TOOL_NAME.IMPLEMENTATION_LOOKUP,
14725
+ TOOL_NAME.ADD_KNOWLEDGE_BASE,
14726
+ TOOL_NAME.LIST_KNOWLEDGE_BASES,
14727
+ TOOL_NAME.REMOVE_KNOWLEDGE_BASE,
14728
+ TOOL_NAME.PR_IMPACT,
14729
+ TOOL_NAME.INDEX_VISUALIZE
14730
+ ];
14731
+ var PI_TOOL_NAMES = [
14732
+ TOOL_NAME.CODEBASE_CONTEXT,
14733
+ TOOL_NAME.CODEBASE_SEARCH,
14734
+ TOOL_NAME.CODEBASE_PEEK,
14735
+ TOOL_NAME.FIND_SIMILAR,
14736
+ TOOL_NAME.IMPLEMENTATION_LOOKUP,
14737
+ TOOL_NAME.INDEX_CODEBASE,
14738
+ TOOL_NAME.INDEX_STATUS,
14739
+ TOOL_NAME.INDEX_HEALTH_CHECK,
14740
+ TOOL_NAME.INDEX_METRICS,
14741
+ TOOL_NAME.INDEX_LOGS,
14742
+ TOOL_NAME.CALL_GRAPH,
14743
+ TOOL_NAME.CALL_GRAPH_PATH,
14744
+ TOOL_NAME.PR_IMPACT,
14745
+ TOOL_NAME.PI_KNOWLEDGE_BASE_LIST,
14746
+ TOOL_NAME.PI_KNOWLEDGE_BASE_ADD,
14747
+ TOOL_NAME.PI_KNOWLEDGE_BASE_REMOVE
14748
+ ];
14749
+
14750
+ // src/adapters/pi/call-graph.ts
14478
14751
  var HOST = "pi";
14479
14752
  var RelationshipType = Type.Union([
14480
14753
  Type.Literal("Call"),
@@ -14492,7 +14765,7 @@ function projectRoot(ctx) {
14492
14765
  }
14493
14766
  function registerPiCallGraphTools(pi) {
14494
14767
  pi.registerTool({
14495
- name: "call_graph",
14768
+ name: TOOL_NAME.CALL_GRAPH,
14496
14769
  label: "Call Graph",
14497
14770
  description: "Find callers or callees by function or method name. Unique names resolve automatically; use filePath when duplicate names are reported.",
14498
14771
  parameters: Type.Object({
@@ -14508,7 +14781,7 @@ function registerPiCallGraphTools(pi) {
14508
14781
  }
14509
14782
  });
14510
14783
  pi.registerTool({
14511
- name: "call_graph_path",
14784
+ name: TOOL_NAME.CALL_GRAPH_PATH,
14512
14785
  label: "Call Graph Path",
14513
14786
  description: "Find a call path between two named functions or methods. Use fromFilePath or toFilePath when duplicate endpoints are reported.",
14514
14787
  parameters: Type.Object({
@@ -14533,7 +14806,7 @@ function registerPiCallGraphTools(pi) {
14533
14806
  });
14534
14807
  }
14535
14808
 
14536
- // src/pi-extension.ts
14809
+ // src/adapters/pi/extension.ts
14537
14810
  var HOST2 = "pi";
14538
14811
  var ChunkType = Type2.Union([
14539
14812
  Type2.Literal("function"),
@@ -14552,7 +14825,7 @@ function projectRoot2(ctx) {
14552
14825
  }
14553
14826
  function codebaseIndexPiExtension(pi) {
14554
14827
  pi.registerTool({
14555
- name: "codebase_context",
14828
+ name: TOOL_NAME.CODEBASE_CONTEXT,
14556
14829
  label: "Codebase Context",
14557
14830
  description: "PREFERRED FIRST TOOL for any repository question. Returns a deduplicated, file-diverse evidence pack within tokenBudget. Check index_status when freshness is unknown, then use this tool for low-token location discovery and dependency flow. Use fromFilePath/toFilePath only when duplicate path endpoints are reported.",
14558
14831
  parameters: Type2.Object({
@@ -14586,7 +14859,7 @@ function codebaseIndexPiExtension(pi) {
14586
14859
  }
14587
14860
  });
14588
14861
  pi.registerTool({
14589
- name: "codebase_search",
14862
+ name: TOOL_NAME.CODEBASE_SEARCH,
14590
14863
  label: "Codebase Search",
14591
14864
  description: "Use this after codebase_context when you need semantic content, not just locations. Describe behavior, not syntax.",
14592
14865
  parameters: Type2.Object({
@@ -14611,7 +14884,7 @@ function codebaseIndexPiExtension(pi) {
14611
14884
  }
14612
14885
  });
14613
14886
  pi.registerTool({
14614
- name: "codebase_peek",
14887
+ name: TOOL_NAME.CODEBASE_PEEK,
14615
14888
  label: "Codebase Peek",
14616
14889
  description: "LOW-TOKEN location-first retrieval. Prefer codebase_context first, then use this for cheap conceptual lookup.",
14617
14890
  parameters: Type2.Object({
@@ -14635,7 +14908,7 @@ function codebaseIndexPiExtension(pi) {
14635
14908
  }
14636
14909
  });
14637
14910
  pi.registerTool({
14638
- name: "find_similar",
14911
+ name: TOOL_NAME.FIND_SIMILAR,
14639
14912
  label: "Find Similar Code",
14640
14913
  description: "Find code similar to a snippet for duplicate detection, pattern discovery, and refactor planning.",
14641
14914
  parameters: Type2.Object({
@@ -14652,7 +14925,7 @@ function codebaseIndexPiExtension(pi) {
14652
14925
  }
14653
14926
  });
14654
14927
  pi.registerTool({
14655
- name: "implementation_lookup",
14928
+ name: TOOL_NAME.IMPLEMENTATION_LOOKUP,
14656
14929
  label: "Implementation Lookup",
14657
14930
  description: "Find likely symbol definitions or implementations after codebase_context identifies a symbol.",
14658
14931
  parameters: Type2.Object({
@@ -14667,7 +14940,7 @@ function codebaseIndexPiExtension(pi) {
14667
14940
  }
14668
14941
  });
14669
14942
  pi.registerTool({
14670
- name: "index_codebase",
14943
+ name: TOOL_NAME.INDEX_CODEBASE,
14671
14944
  label: "Index Codebase",
14672
14945
  description: "Build or refresh the semantic codebase index. Run index_status when freshness is unknown.",
14673
14946
  parameters: Type2.Object({
@@ -14684,7 +14957,7 @@ function codebaseIndexPiExtension(pi) {
14684
14957
  }
14685
14958
  });
14686
14959
  pi.registerTool({
14687
- name: "index_status",
14960
+ name: TOOL_NAME.INDEX_STATUS,
14688
14961
  label: "Index Status",
14689
14962
  description: "Check index health and current status.",
14690
14963
  parameters: Type2.Object({}),
@@ -14694,7 +14967,7 @@ function codebaseIndexPiExtension(pi) {
14694
14967
  }
14695
14968
  });
14696
14969
  pi.registerTool({
14697
- name: "index_health_check",
14970
+ name: TOOL_NAME.INDEX_HEALTH_CHECK,
14698
14971
  label: "Index Health Check",
14699
14972
  description: "Garbage collect orphaned embeddings/chunks and report index health status.",
14700
14973
  parameters: Type2.Object({}),
@@ -14705,7 +14978,7 @@ function codebaseIndexPiExtension(pi) {
14705
14978
  }
14706
14979
  });
14707
14980
  pi.registerTool({
14708
- name: "index_metrics",
14981
+ name: TOOL_NAME.INDEX_METRICS,
14709
14982
  label: "Index Metrics",
14710
14983
  description: "Return operational metrics and opt-in memory-only privacy-safe effectiveness counters.",
14711
14984
  parameters: Type2.Object({
@@ -14717,7 +14990,7 @@ function codebaseIndexPiExtension(pi) {
14717
14990
  }
14718
14991
  });
14719
14992
  pi.registerTool({
14720
- name: "index_logs",
14993
+ name: TOOL_NAME.INDEX_LOGS,
14721
14994
  label: "Index Logs",
14722
14995
  description: "Return recent debug logs when debug logging is enabled.",
14723
14996
  parameters: Type2.Object({
@@ -14747,7 +15020,7 @@ Check index_status first when index readiness is unknown. For repository questio
14747
15020
  await stopAutoIndex(projectRoot2(ctx), HOST2);
14748
15021
  });
14749
15022
  pi.registerTool({
14750
- name: "pr_impact",
15023
+ name: TOOL_NAME.PR_IMPACT,
14751
15024
  label: "PR Impact",
14752
15025
  description: "Analyze PR or branch impact through changed symbols and call graph neighborhoods.",
14753
15026
  parameters: Type2.Object({
@@ -14764,7 +15037,7 @@ Check index_status first when index readiness is unknown. For repository questio
14764
15037
  }
14765
15038
  });
14766
15039
  pi.registerTool({
14767
- name: "knowledge_base_list",
15040
+ name: TOOL_NAME.PI_KNOWLEDGE_BASE_LIST,
14768
15041
  label: "List Knowledge Bases",
14769
15042
  description: "List configured knowledge-base paths included in the index.",
14770
15043
  parameters: Type2.Object({}),
@@ -14773,7 +15046,7 @@ Check index_status first when index readiness is unknown. For repository questio
14773
15046
  }
14774
15047
  });
14775
15048
  pi.registerTool({
14776
- name: "knowledge_base_add",
15049
+ name: TOOL_NAME.PI_KNOWLEDGE_BASE_ADD,
14777
15050
  label: "Add Knowledge Base",
14778
15051
  description: "Add a knowledge-base path to the codebase index config.",
14779
15052
  parameters: Type2.Object({ path: Type2.String({ description: "File or directory path to add" }) }),
@@ -14782,7 +15055,7 @@ Check index_status first when index readiness is unknown. For repository questio
14782
15055
  }
14783
15056
  });
14784
15057
  pi.registerTool({
14785
- name: "knowledge_base_remove",
15058
+ name: TOOL_NAME.PI_KNOWLEDGE_BASE_REMOVE,
14786
15059
  label: "Remove Knowledge Base",
14787
15060
  description: "Remove a knowledge-base path from the codebase index config.",
14788
15061
  parameters: Type2.Object({ path: Type2.String({ description: "File or directory path to remove" }) }),