opencode-codebase-index 0.17.0 → 0.18.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.
@@ -6,13 +6,7 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
6
  var __getOwnPropNames = Object.getOwnPropertyNames;
7
7
  var __getProtoOf = Object.getPrototypeOf;
8
8
  var __hasOwnProp = Object.prototype.hasOwnProperty;
9
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
10
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
11
- }) : x)(function(x) {
12
- if (typeof require !== "undefined") return require.apply(this, arguments);
13
- throw Error('Dynamic require of "' + x + '" is not supported');
14
- });
15
- var __commonJS = (cb, mod) => function __require2() {
9
+ var __commonJS = (cb, mod) => function __require() {
16
10
  try {
17
11
  return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
18
12
  } catch (e) {
@@ -656,467 +650,6 @@ var require_ignore = __commonJS({
656
650
  }
657
651
  });
658
652
 
659
- // node_modules/tiktoken/tiktoken_bg.cjs
660
- var require_tiktoken_bg = __commonJS({
661
- "node_modules/tiktoken/tiktoken_bg.cjs"(exports, module2) {
662
- "use strict";
663
- var wasm;
664
- module2.exports.__wbg_set_wasm = function(val) {
665
- wasm = val;
666
- };
667
- var lTextDecoder = typeof TextDecoder === "undefined" ? (0, module2.require)("util").TextDecoder : TextDecoder;
668
- var cachedTextDecoder = new lTextDecoder("utf-8", { ignoreBOM: true, fatal: true });
669
- cachedTextDecoder.decode();
670
- var cachedUint8ArrayMemory0 = null;
671
- function getUint8ArrayMemory0() {
672
- if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {
673
- cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);
674
- }
675
- return cachedUint8ArrayMemory0;
676
- }
677
- function getStringFromWasm0(ptr, len) {
678
- ptr = ptr >>> 0;
679
- return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));
680
- }
681
- var heap = new Array(128).fill(void 0);
682
- heap.push(void 0, null, true, false);
683
- var heap_next = heap.length;
684
- function addHeapObject(obj) {
685
- if (heap_next === heap.length) heap.push(heap.length + 1);
686
- const idx = heap_next;
687
- heap_next = heap[idx];
688
- heap[idx] = obj;
689
- return idx;
690
- }
691
- function handleError(f, args) {
692
- try {
693
- return f.apply(this, args);
694
- } catch (e) {
695
- wasm.__wbindgen_export_0(addHeapObject(e));
696
- }
697
- }
698
- function getObject(idx) {
699
- return heap[idx];
700
- }
701
- function dropObject(idx) {
702
- if (idx < 132) return;
703
- heap[idx] = heap_next;
704
- heap_next = idx;
705
- }
706
- function takeObject(idx) {
707
- const ret = getObject(idx);
708
- dropObject(idx);
709
- return ret;
710
- }
711
- var WASM_VECTOR_LEN = 0;
712
- var lTextEncoder = typeof TextEncoder === "undefined" ? (0, module2.require)("util").TextEncoder : TextEncoder;
713
- var cachedTextEncoder = new lTextEncoder("utf-8");
714
- var encodeString = typeof cachedTextEncoder.encodeInto === "function" ? function(arg, view) {
715
- return cachedTextEncoder.encodeInto(arg, view);
716
- } : function(arg, view) {
717
- const buf = cachedTextEncoder.encode(arg);
718
- view.set(buf);
719
- return {
720
- read: arg.length,
721
- written: buf.length
722
- };
723
- };
724
- function passStringToWasm0(arg, malloc, realloc) {
725
- if (realloc === void 0) {
726
- const buf = cachedTextEncoder.encode(arg);
727
- const ptr2 = malloc(buf.length, 1) >>> 0;
728
- getUint8ArrayMemory0().subarray(ptr2, ptr2 + buf.length).set(buf);
729
- WASM_VECTOR_LEN = buf.length;
730
- return ptr2;
731
- }
732
- let len = arg.length;
733
- let ptr = malloc(len, 1) >>> 0;
734
- const mem = getUint8ArrayMemory0();
735
- let offset = 0;
736
- for (; offset < len; offset++) {
737
- const code = arg.charCodeAt(offset);
738
- if (code > 127) break;
739
- mem[ptr + offset] = code;
740
- }
741
- if (offset !== len) {
742
- if (offset !== 0) {
743
- arg = arg.slice(offset);
744
- }
745
- ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;
746
- const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len);
747
- const ret = encodeString(arg, view);
748
- offset += ret.written;
749
- ptr = realloc(ptr, len, offset, 1) >>> 0;
750
- }
751
- WASM_VECTOR_LEN = offset;
752
- return ptr;
753
- }
754
- function isLikeNone(x) {
755
- return x === void 0 || x === null;
756
- }
757
- var cachedDataViewMemory0 = null;
758
- function getDataViewMemory0() {
759
- if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || cachedDataViewMemory0.buffer.detached === void 0 && cachedDataViewMemory0.buffer !== wasm.memory.buffer) {
760
- cachedDataViewMemory0 = new DataView(wasm.memory.buffer);
761
- }
762
- return cachedDataViewMemory0;
763
- }
764
- var cachedUint32ArrayMemory0 = null;
765
- function getUint32ArrayMemory0() {
766
- if (cachedUint32ArrayMemory0 === null || cachedUint32ArrayMemory0.byteLength === 0) {
767
- cachedUint32ArrayMemory0 = new Uint32Array(wasm.memory.buffer);
768
- }
769
- return cachedUint32ArrayMemory0;
770
- }
771
- function getArrayU32FromWasm0(ptr, len) {
772
- ptr = ptr >>> 0;
773
- return getUint32ArrayMemory0().subarray(ptr / 4, ptr / 4 + len);
774
- }
775
- function passArray8ToWasm0(arg, malloc) {
776
- const ptr = malloc(arg.length * 1, 1) >>> 0;
777
- getUint8ArrayMemory0().set(arg, ptr / 1);
778
- WASM_VECTOR_LEN = arg.length;
779
- return ptr;
780
- }
781
- function passArray32ToWasm0(arg, malloc) {
782
- const ptr = malloc(arg.length * 4, 4) >>> 0;
783
- getUint32ArrayMemory0().set(arg, ptr / 4);
784
- WASM_VECTOR_LEN = arg.length;
785
- return ptr;
786
- }
787
- function getArrayU8FromWasm0(ptr, len) {
788
- ptr = ptr >>> 0;
789
- return getUint8ArrayMemory0().subarray(ptr / 1, ptr / 1 + len);
790
- }
791
- module2.exports.get_encoding = function(encoding, extend_special_tokens) {
792
- if (wasm == null) throw new Error("tiktoken: WASM binary has not been propery initialized.");
793
- try {
794
- const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
795
- const ptr0 = passStringToWasm0(encoding, wasm.__wbindgen_export_1, wasm.__wbindgen_export_2);
796
- const len0 = WASM_VECTOR_LEN;
797
- wasm.get_encoding(retptr, ptr0, len0, addHeapObject(extend_special_tokens));
798
- var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
799
- var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
800
- var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
801
- if (r2) {
802
- throw takeObject(r1);
803
- }
804
- return Tiktoken.__wrap(r0);
805
- } finally {
806
- wasm.__wbindgen_add_to_stack_pointer(16);
807
- }
808
- };
809
- module2.exports.encoding_for_model = function(model, extend_special_tokens) {
810
- if (wasm == null) throw new Error("tiktoken: WASM binary has not been propery initialized.");
811
- try {
812
- const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
813
- const ptr0 = passStringToWasm0(model, wasm.__wbindgen_export_1, wasm.__wbindgen_export_2);
814
- const len0 = WASM_VECTOR_LEN;
815
- wasm.encoding_for_model(retptr, ptr0, len0, addHeapObject(extend_special_tokens));
816
- var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
817
- var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
818
- var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
819
- if (r2) {
820
- throw takeObject(r1);
821
- }
822
- return Tiktoken.__wrap(r0);
823
- } finally {
824
- wasm.__wbindgen_add_to_stack_pointer(16);
825
- }
826
- };
827
- module2.exports.get_encoding_name_for_model = function(model) {
828
- if (wasm == null) throw new Error("tiktoken: WASM binary has not been propery initialized.");
829
- let deferred3_0;
830
- let deferred3_1;
831
- try {
832
- const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
833
- const ptr0 = passStringToWasm0(model, wasm.__wbindgen_export_1, wasm.__wbindgen_export_2);
834
- const len0 = WASM_VECTOR_LEN;
835
- wasm.get_encoding_name_for_model(retptr, ptr0, len0);
836
- var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
837
- var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
838
- var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
839
- var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
840
- var ptr2 = r0;
841
- var len2 = r1;
842
- if (r3) {
843
- ptr2 = 0;
844
- len2 = 0;
845
- throw takeObject(r2);
846
- }
847
- deferred3_0 = ptr2;
848
- deferred3_1 = len2;
849
- return getStringFromWasm0(ptr2, len2);
850
- } finally {
851
- wasm.__wbindgen_add_to_stack_pointer(16);
852
- wasm.__wbindgen_export_3(deferred3_0, deferred3_1, 1);
853
- }
854
- };
855
- var TiktokenFinalization = typeof FinalizationRegistry === "undefined" ? { register: () => {
856
- }, unregister: () => {
857
- } } : new FinalizationRegistry((ptr) => wasm.__wbg_tiktoken_free(ptr >>> 0, 1));
858
- var Tiktoken = class _Tiktoken {
859
- /**
860
- * @param {string} tiktoken_bfe
861
- * @param {any} special_tokens
862
- * @param {string} pat_str
863
- */
864
- constructor(tiktoken_bfe, special_tokens, pat_str) {
865
- if (wasm == null) throw new Error("tiktoken: WASM binary has not been propery initialized.");
866
- const ptr0 = passStringToWasm0(tiktoken_bfe, wasm.__wbindgen_export_1, wasm.__wbindgen_export_2);
867
- const len0 = WASM_VECTOR_LEN;
868
- const ptr1 = passStringToWasm0(pat_str, wasm.__wbindgen_export_1, wasm.__wbindgen_export_2);
869
- const len1 = WASM_VECTOR_LEN;
870
- const ret = wasm.tiktoken_new(ptr0, len0, addHeapObject(special_tokens), ptr1, len1);
871
- this.__wbg_ptr = ret >>> 0;
872
- TiktokenFinalization.register(this, this.__wbg_ptr, this);
873
- return this;
874
- }
875
- /** @returns {string | undefined} */
876
- get name() {
877
- try {
878
- const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
879
- wasm.tiktoken_name(retptr, this.__wbg_ptr);
880
- var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
881
- var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
882
- let v1;
883
- if (r0 !== 0) {
884
- v1 = getStringFromWasm0(r0, r1).slice();
885
- wasm.__wbindgen_export_3(r0, r1 * 1, 1);
886
- }
887
- return v1;
888
- } finally {
889
- wasm.__wbindgen_add_to_stack_pointer(16);
890
- }
891
- }
892
- static __wrap(ptr) {
893
- ptr = ptr >>> 0;
894
- const obj = Object.create(_Tiktoken.prototype);
895
- obj.__wbg_ptr = ptr;
896
- TiktokenFinalization.register(obj, obj.__wbg_ptr, obj);
897
- return obj;
898
- }
899
- __destroy_into_raw() {
900
- const ptr = this.__wbg_ptr;
901
- this.__wbg_ptr = 0;
902
- TiktokenFinalization.unregister(this);
903
- return ptr;
904
- }
905
- free() {
906
- if (wasm == null) throw new Error("tiktoken: WASM binary has not been propery initialized.");
907
- const ptr = this.__destroy_into_raw();
908
- wasm.__wbg_tiktoken_free(ptr, 0);
909
- }
910
- /**
911
- * @param {string} text
912
- * @param {any} allowed_special
913
- * @param {any} disallowed_special
914
- * @returns {Uint32Array}
915
- */
916
- encode(text3, allowed_special, disallowed_special) {
917
- if (wasm == null) throw new Error("tiktoken: WASM binary has not been propery initialized.");
918
- try {
919
- const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
920
- const ptr0 = passStringToWasm0(text3, wasm.__wbindgen_export_1, wasm.__wbindgen_export_2);
921
- const len0 = WASM_VECTOR_LEN;
922
- wasm.tiktoken_encode(retptr, this.__wbg_ptr, ptr0, len0, addHeapObject(allowed_special), addHeapObject(disallowed_special));
923
- var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
924
- var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
925
- var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
926
- var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
927
- if (r3) {
928
- throw takeObject(r2);
929
- }
930
- var v2 = getArrayU32FromWasm0(r0, r1).slice();
931
- wasm.__wbindgen_export_3(r0, r1 * 4, 4);
932
- return v2;
933
- } finally {
934
- wasm.__wbindgen_add_to_stack_pointer(16);
935
- }
936
- }
937
- /**
938
- * @param {string} text
939
- * @returns {Uint32Array}
940
- */
941
- encode_ordinary(text3) {
942
- if (wasm == null) throw new Error("tiktoken: WASM binary has not been propery initialized.");
943
- try {
944
- const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
945
- const ptr0 = passStringToWasm0(text3, wasm.__wbindgen_export_1, wasm.__wbindgen_export_2);
946
- const len0 = WASM_VECTOR_LEN;
947
- wasm.tiktoken_encode_ordinary(retptr, this.__wbg_ptr, ptr0, len0);
948
- var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
949
- var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
950
- var v2 = getArrayU32FromWasm0(r0, r1).slice();
951
- wasm.__wbindgen_export_3(r0, r1 * 4, 4);
952
- return v2;
953
- } finally {
954
- wasm.__wbindgen_add_to_stack_pointer(16);
955
- }
956
- }
957
- /**
958
- * @param {string} text
959
- * @param {any} allowed_special
960
- * @param {any} disallowed_special
961
- * @returns {any}
962
- */
963
- encode_with_unstable(text3, allowed_special, disallowed_special) {
964
- if (wasm == null) throw new Error("tiktoken: WASM binary has not been propery initialized.");
965
- try {
966
- const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
967
- const ptr0 = passStringToWasm0(text3, wasm.__wbindgen_export_1, wasm.__wbindgen_export_2);
968
- const len0 = WASM_VECTOR_LEN;
969
- wasm.tiktoken_encode_with_unstable(retptr, this.__wbg_ptr, ptr0, len0, addHeapObject(allowed_special), addHeapObject(disallowed_special));
970
- var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
971
- var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
972
- var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
973
- if (r2) {
974
- throw takeObject(r1);
975
- }
976
- return takeObject(r0);
977
- } finally {
978
- wasm.__wbindgen_add_to_stack_pointer(16);
979
- }
980
- }
981
- /**
982
- * @param {Uint8Array} bytes
983
- * @returns {number}
984
- */
985
- encode_single_token(bytes) {
986
- if (wasm == null) throw new Error("tiktoken: WASM binary has not been propery initialized.");
987
- const ptr0 = passArray8ToWasm0(bytes, wasm.__wbindgen_export_1);
988
- const len0 = WASM_VECTOR_LEN;
989
- const ret = wasm.tiktoken_encode_single_token(this.__wbg_ptr, ptr0, len0);
990
- return ret >>> 0;
991
- }
992
- /**
993
- * @param {Uint32Array} tokens
994
- * @returns {Uint8Array}
995
- */
996
- decode(tokens) {
997
- if (wasm == null) throw new Error("tiktoken: WASM binary has not been propery initialized.");
998
- try {
999
- const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
1000
- const ptr0 = passArray32ToWasm0(tokens, wasm.__wbindgen_export_1);
1001
- const len0 = WASM_VECTOR_LEN;
1002
- wasm.tiktoken_decode(retptr, this.__wbg_ptr, ptr0, len0);
1003
- var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
1004
- var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
1005
- var v2 = getArrayU8FromWasm0(r0, r1).slice();
1006
- wasm.__wbindgen_export_3(r0, r1 * 1, 1);
1007
- return v2;
1008
- } finally {
1009
- wasm.__wbindgen_add_to_stack_pointer(16);
1010
- }
1011
- }
1012
- /**
1013
- * @param {number} token
1014
- * @returns {Uint8Array}
1015
- */
1016
- decode_single_token_bytes(token) {
1017
- if (wasm == null) throw new Error("tiktoken: WASM binary has not been propery initialized.");
1018
- try {
1019
- const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
1020
- wasm.tiktoken_decode_single_token_bytes(retptr, this.__wbg_ptr, token);
1021
- var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
1022
- var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
1023
- var v1 = getArrayU8FromWasm0(r0, r1).slice();
1024
- wasm.__wbindgen_export_3(r0, r1 * 1, 1);
1025
- return v1;
1026
- } finally {
1027
- wasm.__wbindgen_add_to_stack_pointer(16);
1028
- }
1029
- }
1030
- /** @returns {any} */
1031
- token_byte_values() {
1032
- if (wasm == null) throw new Error("tiktoken: WASM binary has not been propery initialized.");
1033
- const ret = wasm.tiktoken_token_byte_values(this.__wbg_ptr);
1034
- return takeObject(ret);
1035
- }
1036
- };
1037
- module2.exports.Tiktoken = Tiktoken;
1038
- module2.exports.__wbg_parse_def2e24ef1252aff = function() {
1039
- return handleError(function(arg0, arg1) {
1040
- const ret = JSON.parse(getStringFromWasm0(arg0, arg1));
1041
- return addHeapObject(ret);
1042
- }, arguments);
1043
- };
1044
- module2.exports.__wbg_stringify_f7ed6987935b4a24 = function() {
1045
- return handleError(function(arg0) {
1046
- const ret = JSON.stringify(getObject(arg0));
1047
- return addHeapObject(ret);
1048
- }, arguments);
1049
- };
1050
- module2.exports.__wbindgen_error_new = function(arg0, arg1) {
1051
- const ret = new Error(getStringFromWasm0(arg0, arg1));
1052
- return addHeapObject(ret);
1053
- };
1054
- module2.exports.__wbindgen_is_undefined = function(arg0) {
1055
- const ret = getObject(arg0) === void 0;
1056
- return ret;
1057
- };
1058
- module2.exports.__wbindgen_object_drop_ref = function(arg0) {
1059
- takeObject(arg0);
1060
- };
1061
- module2.exports.__wbindgen_string_get = function(arg0, arg1) {
1062
- if (wasm == null) throw new Error("tiktoken: WASM binary has not been propery initialized.");
1063
- const obj = getObject(arg1);
1064
- const ret = typeof obj === "string" ? obj : void 0;
1065
- var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_export_1, wasm.__wbindgen_export_2);
1066
- var len1 = WASM_VECTOR_LEN;
1067
- getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
1068
- getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
1069
- };
1070
- module2.exports.__wbindgen_throw = function(arg0, arg1) {
1071
- throw new Error(getStringFromWasm0(arg0, arg1));
1072
- };
1073
- }
1074
- });
1075
-
1076
- // node_modules/tiktoken/tiktoken.cjs
1077
- var require_tiktoken = __commonJS({
1078
- "node_modules/tiktoken/tiktoken.cjs"(exports) {
1079
- "use strict";
1080
- var wasm = require_tiktoken_bg();
1081
- var imports = {};
1082
- imports["./tiktoken_bg.js"] = wasm;
1083
- var path17 = __require("path");
1084
- var fs = __require("fs");
1085
- var candidates = __dirname.split(path17.sep).reduce((memo, _, index, array) => {
1086
- const prefix = array.slice(0, index + 1).join(path17.sep) + path17.sep;
1087
- if (!prefix.includes("node_modules" + path17.sep)) {
1088
- memo.unshift(
1089
- path17.join(
1090
- prefix,
1091
- "node_modules",
1092
- "tiktoken",
1093
- "",
1094
- "./tiktoken_bg.wasm"
1095
- )
1096
- );
1097
- }
1098
- return memo;
1099
- }, []);
1100
- candidates.unshift(path17.join(__dirname, "./tiktoken_bg.wasm"));
1101
- var bytes = null;
1102
- for (const candidate of candidates) {
1103
- try {
1104
- bytes = fs.readFileSync(candidate);
1105
- break;
1106
- } catch {
1107
- }
1108
- }
1109
- if (bytes == null) throw new Error("Missing tiktoken_bg.wasm");
1110
- var wasmModule = new WebAssembly.Module(bytes);
1111
- var wasmInstance = new WebAssembly.Instance(wasmModule, imports);
1112
- wasm.__wbg_set_wasm(wasmInstance.exports);
1113
- exports["get_encoding"] = wasm["get_encoding"];
1114
- exports["encoding_for_model"] = wasm["encoding_for_model"];
1115
- exports["get_encoding_name_for_model"] = wasm["get_encoding_name_for_model"];
1116
- exports["Tiktoken"] = wasm["Tiktoken"];
1117
- }
1118
- });
1119
-
1120
653
  // src/pi-extension.ts
1121
654
  import { Type as Type2 } from "typebox";
1122
655
 
@@ -1135,7 +668,8 @@ var DEFAULT_INCLUDE = [
1135
668
  "**/*.{sh,bash,zsh}",
1136
669
  "**/*.{txt,html,htm}",
1137
670
  "**/*.zig",
1138
- "**/*.gd"
671
+ "**/*.gd",
672
+ "**/*.metal"
1139
673
  ];
1140
674
  var DEFAULT_EXCLUDE = [
1141
675
  "**/node_modules/**",
@@ -1326,6 +860,9 @@ function isValidProvider(value) {
1326
860
  return typeof value === "string" && Object.keys(EMBEDDING_MODELS).includes(value);
1327
861
  }
1328
862
  function isValidModel(value, provider) {
863
+ if (typeof value === "string" && provider === "ollama" && value.trim().length > 0) {
864
+ return true;
865
+ }
1329
866
  return typeof value === "string" && Object.keys(EMBEDDING_MODELS[provider]).includes(value);
1330
867
  }
1331
868
  function isValidScope(value) {
@@ -1525,6 +1062,9 @@ function loadOpenCodeAuth() {
1525
1062
  return {};
1526
1063
  }
1527
1064
  async function detectEmbeddingProvider(preferredProvider, model) {
1065
+ if (preferredProvider === "ollama") {
1066
+ return detectOllamaProvider(model);
1067
+ }
1528
1068
  const credentials = await getProviderCredentials(preferredProvider);
1529
1069
  if (credentials) {
1530
1070
  if (!model) {
@@ -1540,10 +1080,16 @@ async function detectEmbeddingProvider(preferredProvider, model) {
1540
1080
  );
1541
1081
  }
1542
1082
  const providerModels = EMBEDDING_MODELS[preferredProvider];
1083
+ const modelInfo = Object.values(providerModels).find((candidate) => candidate.model === model);
1084
+ if (!modelInfo) {
1085
+ throw new Error(
1086
+ `Model '${model}' is not supported by provider '${preferredProvider}'`
1087
+ );
1088
+ }
1543
1089
  return {
1544
1090
  provider: preferredProvider,
1545
1091
  credentials,
1546
- modelInfo: providerModels[model]
1092
+ modelInfo
1547
1093
  };
1548
1094
  }
1549
1095
  throw new Error(
@@ -1552,6 +1098,13 @@ async function detectEmbeddingProvider(preferredProvider, model) {
1552
1098
  }
1553
1099
  async function tryDetectProvider() {
1554
1100
  for (const provider of autoDetectProviders) {
1101
+ if (provider === "ollama") {
1102
+ const ollamaProvider = await tryDetectOllamaProvider();
1103
+ if (ollamaProvider) {
1104
+ return ollamaProvider;
1105
+ }
1106
+ continue;
1107
+ }
1555
1108
  const credentials = await getProviderCredentials(provider);
1556
1109
  if (credentials) {
1557
1110
  return {
@@ -1619,32 +1172,105 @@ function getGoogleCredentials() {
1619
1172
  }
1620
1173
  return null;
1621
1174
  }
1622
- async function getOllamaCredentials() {
1623
- const baseUrl = process.env.OLLAMA_HOST || "http://localhost:11434";
1175
+ async function fetchOllama(url, init) {
1176
+ const controller = new AbortController();
1177
+ const timeoutId = setTimeout(() => controller.abort(), 2e3);
1624
1178
  try {
1625
- const controller = new AbortController();
1626
- const timeoutId = setTimeout(() => controller.abort(), 2e3);
1627
- const response = await fetch(`${baseUrl}/api/tags`, {
1628
- signal: controller.signal
1629
- });
1179
+ return await fetch(url, { ...init, signal: controller.signal });
1180
+ } finally {
1630
1181
  clearTimeout(timeoutId);
1182
+ }
1183
+ }
1184
+ async function getOllamaCredentials() {
1185
+ const baseUrl = (process.env.OLLAMA_HOST || "http://localhost:11434").replace(/\/+$/, "");
1186
+ try {
1187
+ const response = await fetchOllama(`${baseUrl}/api/tags`);
1631
1188
  if (response.ok) {
1632
- const data = await response.json();
1633
- const hasEmbeddingModel = data.models?.some(
1634
- (m) => m.name.includes("nomic-embed") || m.name.includes("mxbai-embed") || m.name.includes("all-minilm")
1635
- );
1636
- if (hasEmbeddingModel) {
1637
- return {
1638
- provider: "ollama",
1639
- baseUrl
1640
- };
1641
- }
1189
+ return {
1190
+ provider: "ollama",
1191
+ baseUrl
1192
+ };
1642
1193
  }
1643
1194
  } catch {
1644
1195
  return null;
1645
1196
  }
1646
1197
  return null;
1647
1198
  }
1199
+ function findCatalogOllamaModel(model) {
1200
+ const stableName = model.endsWith(":latest") ? model.slice(0, -":latest".length) : model;
1201
+ return Object.values(EMBEDDING_MODELS.ollama).find((candidate) => candidate.model === stableName) ?? null;
1202
+ }
1203
+ function getPositiveIntegerMetadata(modelInfo, suffix) {
1204
+ const values = Object.entries(modelInfo).filter(([key]) => key.endsWith(suffix)).map(([, value]) => value).filter((value) => typeof value === "number" && Number.isInteger(value) && value > 0);
1205
+ return values.length === 1 ? values[0] : null;
1206
+ }
1207
+ async function fetchOllamaModelInfo(credentials, model) {
1208
+ const response = await fetchOllama(`${credentials.baseUrl}/api/show`, {
1209
+ method: "POST",
1210
+ headers: { "Content-Type": "application/json" },
1211
+ body: JSON.stringify({ model })
1212
+ });
1213
+ if (!response.ok) {
1214
+ return null;
1215
+ }
1216
+ const data = await response.json();
1217
+ if (!data.capabilities?.includes("embedding") || !data.model_info) {
1218
+ return null;
1219
+ }
1220
+ const dimensions = getPositiveIntegerMetadata(data.model_info, ".embedding_length");
1221
+ const maxTokens = getPositiveIntegerMetadata(data.model_info, ".context_length");
1222
+ if (!dimensions || !maxTokens) {
1223
+ return null;
1224
+ }
1225
+ return {
1226
+ provider: "ollama",
1227
+ model,
1228
+ dimensions,
1229
+ maxTokens,
1230
+ costPer1MTokens: 0
1231
+ };
1232
+ }
1233
+ async function listOllamaModels(credentials) {
1234
+ const response = await fetchOllama(`${credentials.baseUrl}/api/tags`);
1235
+ if (!response.ok) {
1236
+ return [];
1237
+ }
1238
+ const data = await response.json();
1239
+ return [...new Set((data.models ?? []).map((entry) => entry.name ?? entry.model).filter((name) => typeof name === "string" && name.trim().length > 0))];
1240
+ }
1241
+ async function detectOllamaProvider(model) {
1242
+ const credentials = await getOllamaCredentials();
1243
+ if (!credentials) {
1244
+ throw new Error("Preferred provider 'ollama' is not configured or authenticated");
1245
+ }
1246
+ const requestedModel = model?.trim();
1247
+ if (requestedModel) {
1248
+ const catalogModel = findCatalogOllamaModel(requestedModel);
1249
+ if (catalogModel) {
1250
+ return { provider: "ollama", credentials, modelInfo: catalogModel };
1251
+ }
1252
+ }
1253
+ const candidates = requestedModel ? [requestedModel] : await listOllamaModels(credentials);
1254
+ for (const candidate of candidates) {
1255
+ const modelInfo = await fetchOllamaModelInfo(credentials, candidate);
1256
+ if (modelInfo) {
1257
+ return {
1258
+ provider: "ollama",
1259
+ credentials,
1260
+ modelInfo: findCatalogOllamaModel(candidate) ?? modelInfo
1261
+ };
1262
+ }
1263
+ }
1264
+ const detail = model ? `Model '${model}' is not installed or is not embedding-capable` : "No installed embedding-capable Ollama model was found";
1265
+ throw new Error(detail);
1266
+ }
1267
+ async function tryDetectOllamaProvider() {
1268
+ try {
1269
+ return await detectOllamaProvider();
1270
+ } catch {
1271
+ return null;
1272
+ }
1273
+ }
1648
1274
  function getProviderDisplayName(provider) {
1649
1275
  switch (provider) {
1650
1276
  case "github-copilot":
@@ -1797,10 +1423,6 @@ function formatPrImpact(result) {
1797
1423
  import { existsSync as existsSync10, realpathSync as realpathSync2, statSync as statSync4 } from "fs";
1798
1424
  import * as path16 from "path";
1799
1425
 
1800
- // src/config/merger.ts
1801
- import { existsSync as existsSync5, mkdirSync, readFileSync as readFileSync4, writeFileSync } from "fs";
1802
- import * as path7 from "path";
1803
-
1804
1426
  // src/config/paths.ts
1805
1427
  import { existsSync as existsSync4 } from "fs";
1806
1428
  import * as os2 from "os";
@@ -1973,16 +1595,6 @@ function resolveWorktreeFallbackPath(projectRoot3, relativePath) {
1973
1595
  const fallbackPath = path4.join(mainRepoRoot, relativePath);
1974
1596
  return existsSync4(fallbackPath) ? fallbackPath : null;
1975
1597
  }
1976
- function resolveWorktreeFallbackProjectIndexPath(projectRoot3, host) {
1977
- const inheritedHostPath = resolveWorktreeFallbackPath(projectRoot3, getProjectIndexRelativePath(host));
1978
- if (inheritedHostPath) {
1979
- return inheritedHostPath;
1980
- }
1981
- if (host !== "opencode") {
1982
- return resolveWorktreeFallbackPath(projectRoot3, OPENCODE_PROJECT_INDEX_RELATIVE_PATH);
1983
- }
1984
- return null;
1985
- }
1986
1598
  function getHostProjectConfigRelativePath(host) {
1987
1599
  return getProjectConfigRelativePath(host);
1988
1600
  }
@@ -2087,6 +1699,9 @@ function resolveProjectIndexPath(projectRoot3, scope, host = "opencode") {
2087
1699
  if (hasHostProjectConfig(projectRoot3, host)) {
2088
1700
  return localIndexPath;
2089
1701
  }
1702
+ if (resolveWorktreeMainRepoRoot(projectRoot3)) {
1703
+ return localIndexPath;
1704
+ }
2090
1705
  const hostFallback = resolveWorktreeFallbackPath(projectRoot3, getProjectIndexRelativePath(host));
2091
1706
  if (hostFallback) {
2092
1707
  return hostFallback;
@@ -2100,210 +1715,9 @@ function resolveProjectIndexPath(projectRoot3, scope, host = "opencode") {
2100
1715
  return localIndexPath;
2101
1716
  }
2102
1717
 
2103
- // src/config/rebase.ts
2104
- import * as path6 from "path";
2105
-
2106
- // src/utils/paths.ts
2107
- import * as path5 from "path";
2108
- function normalizePathSeparators(value) {
2109
- return value.replace(/\\/g, "/");
2110
- }
2111
- function isHiddenPathSegment(part) {
2112
- return part.startsWith(".") && part !== "." && part !== "..";
2113
- }
2114
- function isBuildPathSegment(part) {
2115
- return part.toLowerCase().includes("build");
2116
- }
2117
-
2118
- // src/config/rebase.ts
2119
- function isWithinRoot(rootDir, targetPath) {
2120
- const relativePath = path6.relative(rootDir, targetPath);
2121
- return relativePath === "" || !relativePath.startsWith("..") && !path6.isAbsolute(relativePath);
2122
- }
2123
- function resolveInheritedKnowledgeBaseEntries(values, sourceRoot, targetRoot) {
2124
- if (!Array.isArray(values)) {
2125
- return [];
2126
- }
2127
- return values.filter((value) => typeof value === "string").map((value) => {
2128
- const trimmed = value.trim();
2129
- if (!trimmed) {
2130
- return trimmed;
2131
- }
2132
- if (path6.isAbsolute(trimmed)) {
2133
- if (isWithinRoot(sourceRoot, trimmed)) {
2134
- return normalizePathSeparators(path6.normalize(path6.relative(sourceRoot, trimmed) || "."));
2135
- }
2136
- return path6.normalize(trimmed);
2137
- }
2138
- const resolvedFromSource = path6.resolve(sourceRoot, trimmed);
2139
- if (isWithinRoot(sourceRoot, resolvedFromSource)) {
2140
- return normalizePathSeparators(path6.normalize(trimmed));
2141
- }
2142
- return normalizePathSeparators(path6.normalize(path6.relative(targetRoot, resolvedFromSource)));
2143
- }).filter(Boolean);
2144
- }
2145
-
2146
- // src/config/merger.ts
2147
- var PROJECT_OVERRIDE_KEYS = [
2148
- "embeddingProvider",
2149
- "customProvider",
2150
- "embeddingModel",
2151
- "reranker",
2152
- "include",
2153
- "exclude",
2154
- "indexing",
2155
- "search",
2156
- "debug",
2157
- "scope"
2158
- ];
2159
- var MERGE_ARRAY_KEYS = ["knowledgeBases", "additionalInclude"];
2160
- function isRecord(value) {
2161
- return typeof value === "object" && value !== null && !Array.isArray(value);
2162
- }
2163
- function isStringArray2(value) {
2164
- return Array.isArray(value) && value.every((item) => typeof item === "string");
2165
- }
2166
- function applyProjectOverride(merged, normalizedProjectConfig, globalConfig, key) {
2167
- if (key in normalizedProjectConfig) {
2168
- merged[key] = normalizedProjectConfig[key];
2169
- return;
2170
- }
2171
- if (key in globalConfig) {
2172
- merged[key] = globalConfig[key];
2173
- }
2174
- }
2175
- function mergeUniqueStringArray(values) {
2176
- return [...new Set(values.map((value) => String(value).trim()))];
2177
- }
2178
- function normalizeKnowledgeBasePath(value) {
2179
- let normalized = path7.normalize(String(value).trim());
2180
- const root = path7.parse(normalized).root;
2181
- while (normalized.length > root.length && /[\\/]$/.test(normalized)) {
2182
- normalized = normalized.slice(0, -1);
2183
- }
2184
- return normalized;
2185
- }
2186
- function mergeKnowledgeBasePaths(values) {
2187
- return [...new Set(values.map((value) => normalizeKnowledgeBasePath(value)).filter((value) => value.length > 0))];
2188
- }
2189
- function validateConfigLayerShape(rawConfig, filePath) {
2190
- if (!isRecord(rawConfig)) {
2191
- throw new Error(`Config file ${filePath} must contain a JSON object at the root.`);
2192
- }
2193
- if (rawConfig.knowledgeBases !== void 0 && !isStringArray2(rawConfig.knowledgeBases)) {
2194
- throw new Error(`Config file ${filePath} field 'knowledgeBases' must be an array of strings.`);
2195
- }
2196
- if (rawConfig.additionalInclude !== void 0 && !isStringArray2(rawConfig.additionalInclude)) {
2197
- throw new Error(`Config file ${filePath} field 'additionalInclude' must be an array of strings.`);
2198
- }
2199
- if (rawConfig.include !== void 0 && !isStringArray2(rawConfig.include)) {
2200
- throw new Error(`Config file ${filePath} field 'include' must be an array of strings.`);
2201
- }
2202
- if (rawConfig.exclude !== void 0 && !isStringArray2(rawConfig.exclude)) {
2203
- throw new Error(`Config file ${filePath} field 'exclude' must be an array of strings.`);
2204
- }
2205
- for (const section of ["customProvider", "indexing", "search", "debug", "reranker"]) {
2206
- const value = rawConfig[section];
2207
- if (value !== void 0 && !isRecord(value)) {
2208
- throw new Error(`Config file ${filePath} field '${section}' must be an object.`);
2209
- }
2210
- }
2211
- return rawConfig;
2212
- }
2213
- function loadJsonFile(filePath) {
2214
- if (!existsSync5(filePath)) {
2215
- return null;
2216
- }
2217
- try {
2218
- const content = readFileSync4(filePath, "utf-8");
2219
- return validateConfigLayerShape(JSON.parse(content), filePath);
2220
- } catch (error) {
2221
- if (error instanceof Error && error.message.startsWith("Config file ")) {
2222
- throw error;
2223
- }
2224
- const message = error instanceof Error ? error.message : String(error);
2225
- throw new Error(`Failed to load config file ${filePath}: ${message}`);
2226
- }
2227
- }
2228
- function materializeLocalProjectConfig(projectRoot3, config, host = "opencode") {
2229
- const localConfigPath = resolveWritableProjectConfigPath(projectRoot3, host);
2230
- mkdirSync(path7.dirname(localConfigPath), { recursive: true });
2231
- writeFileSync(localConfigPath, JSON.stringify(config, null, 2), "utf-8");
2232
- return localConfigPath;
2233
- }
2234
- function loadProjectConfigLayer(projectRoot3, host = "opencode") {
2235
- const projectConfigPath = resolveProjectConfigPath(projectRoot3, host);
2236
- const projectConfig = loadJsonFile(projectConfigPath);
2237
- if (!projectConfig) {
2238
- return {};
2239
- }
2240
- const normalizedConfig = { ...projectConfig };
2241
- const projectConfigBaseDir = path7.dirname(path7.dirname(projectConfigPath));
2242
- if (Array.isArray(normalizedConfig.knowledgeBases)) {
2243
- normalizedConfig.knowledgeBases = resolveInheritedKnowledgeBaseEntries(
2244
- normalizedConfig.knowledgeBases,
2245
- projectConfigBaseDir,
2246
- projectRoot3
2247
- );
2248
- }
2249
- return normalizedConfig;
2250
- }
2251
- function loadMergedConfig(projectRoot3, host = "opencode") {
2252
- const globalConfigPath = resolveGlobalConfigPath(host);
2253
- const projectConfigPath = resolveProjectConfigPath(projectRoot3, host);
2254
- let globalConfig = null;
2255
- let globalConfigError = null;
2256
- try {
2257
- globalConfig = loadJsonFile(globalConfigPath);
2258
- } catch (error) {
2259
- globalConfigError = error instanceof Error ? error : new Error(String(error));
2260
- }
2261
- const projectConfig = loadJsonFile(projectConfigPath);
2262
- const normalizedProjectConfig = loadProjectConfigLayer(projectRoot3, host);
2263
- if (globalConfigError) {
2264
- if (!projectConfig) {
2265
- throw globalConfigError;
2266
- }
2267
- globalConfig = null;
2268
- }
2269
- if (!globalConfig && !projectConfig) {
2270
- return {};
2271
- }
2272
- if (!projectConfig && globalConfig) {
2273
- return globalConfig;
2274
- }
2275
- if (!globalConfig && projectConfig) {
2276
- return normalizedProjectConfig;
2277
- }
2278
- if (!globalConfig || !projectConfig) {
2279
- return globalConfig ?? normalizedProjectConfig;
2280
- }
2281
- const merged = { ...globalConfig };
2282
- for (const key of PROJECT_OVERRIDE_KEYS) {
2283
- applyProjectOverride(merged, normalizedProjectConfig, globalConfig, key);
2284
- }
2285
- if (projectConfig) {
2286
- for (const key of Object.keys(projectConfig)) {
2287
- if (PROJECT_OVERRIDE_KEYS.includes(key) || MERGE_ARRAY_KEYS.includes(key)) {
2288
- continue;
2289
- }
2290
- merged[key] = normalizedProjectConfig[key];
2291
- }
2292
- }
2293
- const globalKbs = globalConfig && Array.isArray(globalConfig.knowledgeBases) ? globalConfig.knowledgeBases : [];
2294
- const projectKbs = projectConfig ? Array.isArray(normalizedProjectConfig.knowledgeBases) ? normalizedProjectConfig.knowledgeBases : [] : [];
2295
- const allKbs = [...globalKbs, ...projectKbs];
2296
- merged.knowledgeBases = mergeKnowledgeBasePaths(allKbs);
2297
- const globalAdditional = globalConfig && Array.isArray(globalConfig.additionalInclude) ? globalConfig.additionalInclude : [];
2298
- const projectAdditional = projectConfig && Array.isArray(projectConfig.additionalInclude) ? projectConfig.additionalInclude : [];
2299
- const allAdditional = [...globalAdditional, ...projectAdditional];
2300
- merged.additionalInclude = mergeUniqueStringArray(allAdditional);
2301
- return merged;
2302
- }
2303
-
2304
1718
  // src/indexer/index.ts
2305
- import { existsSync as existsSync8, readFileSync as readFileSync7, statSync as statSync3, writeFileSync as writeFileSync3, renameSync as renameSync2, unlinkSync, mkdirSync as mkdirSync3, promises as fsPromises2 } from "fs";
2306
- import * as path13 from "path";
1719
+ import { existsSync as existsSync7, readFileSync as readFileSync6, statSync as statSync3, writeFileSync as writeFileSync2, renameSync as renameSync2, unlinkSync, mkdirSync as mkdirSync2, promises as fsPromises2 } from "fs";
1720
+ import * as path11 from "path";
2307
1721
  import { performance as performance2 } from "perf_hooks";
2308
1722
  import { execFile as execFile3 } from "child_process";
2309
1723
  import { promisify as promisify3 } from "util";
@@ -3654,6 +3068,7 @@ var GoogleEmbeddingProvider = class _GoogleEmbeddingProvider extends BaseEmbeddi
3654
3068
  // src/embeddings/providers/ollama.ts
3655
3069
  var OllamaEmbeddingProvider = class _OllamaEmbeddingProvider extends BaseEmbeddingProvider {
3656
3070
  static MIN_TRUNCATION_CHARS = 512;
3071
+ static REQUEST_TIMEOUT_MS = 12e4;
3657
3072
  constructor(credentials, modelInfo) {
3658
3073
  super(credentials, modelInfo);
3659
3074
  }
@@ -3728,22 +3143,45 @@ var OllamaEmbeddingProvider = class _OllamaEmbeddingProvider extends BaseEmbeddi
3728
3143
  }
3729
3144
  }
3730
3145
  async embedSingle(text3) {
3731
- const response = await fetch(`${this.credentials.baseUrl}/api/embeddings`, {
3732
- method: "POST",
3733
- headers: {
3734
- "Content-Type": "application/json"
3735
- },
3736
- body: JSON.stringify({
3737
- model: this.modelInfo.model,
3738
- prompt: text3,
3739
- truncate: false
3740
- })
3741
- });
3146
+ const controller = new AbortController();
3147
+ const timeout = setTimeout(
3148
+ () => controller.abort(),
3149
+ _OllamaEmbeddingProvider.REQUEST_TIMEOUT_MS
3150
+ );
3151
+ let response;
3152
+ try {
3153
+ response = await fetch(`${this.credentials.baseUrl}/api/embeddings`, {
3154
+ method: "POST",
3155
+ headers: {
3156
+ "Content-Type": "application/json"
3157
+ },
3158
+ body: JSON.stringify({
3159
+ model: this.modelInfo.model,
3160
+ prompt: text3,
3161
+ truncate: false
3162
+ }),
3163
+ signal: controller.signal
3164
+ });
3165
+ } catch (error) {
3166
+ if (error instanceof Error && error.name === "AbortError") {
3167
+ throw new Error(
3168
+ `Ollama embedding request timed out after ${_OllamaEmbeddingProvider.REQUEST_TIMEOUT_MS}ms`
3169
+ );
3170
+ }
3171
+ throw error;
3172
+ } finally {
3173
+ clearTimeout(timeout);
3174
+ }
3742
3175
  if (!response.ok) {
3743
3176
  const error = (await response.text()).slice(0, 500);
3744
3177
  throw new Error(`Ollama embedding API error: ${response.status} - ${error}`);
3745
3178
  }
3746
3179
  const data = await response.json();
3180
+ if (!Array.isArray(data.embedding) || data.embedding.length !== this.modelInfo.dimensions || data.embedding.some((value) => typeof value !== "number" || !Number.isFinite(value))) {
3181
+ throw new Error(
3182
+ `Ollama returned an invalid embedding; expected ${this.modelInfo.dimensions} finite dimensions`
3183
+ );
3184
+ }
3747
3185
  return {
3748
3186
  embedding: data.embedding,
3749
3187
  tokensUsed: this.estimateTokens(text3)
@@ -3890,9 +3328,23 @@ var SiliconFlowReranker = class {
3890
3328
  };
3891
3329
 
3892
3330
  // src/utils/files.ts
3893
- var import_ignore = __toESM(require_ignore(), 1);
3894
- import { existsSync as existsSync6, readFileSync as readFileSync5, promises as fsPromises } from "fs";
3895
- import * as path8 from "path";
3331
+ var import_ignore = __toESM(require_ignore(), 1);
3332
+ import { existsSync as existsSync5, readFileSync as readFileSync4, promises as fsPromises } from "fs";
3333
+ import * as path6 from "path";
3334
+
3335
+ // src/utils/paths.ts
3336
+ import * as path5 from "path";
3337
+ function normalizePathSeparators(value) {
3338
+ return value.replace(/\\/g, "/");
3339
+ }
3340
+ function isHiddenPathSegment(part) {
3341
+ return part.startsWith(".") && part !== "." && part !== "..";
3342
+ }
3343
+ function isBuildPathSegment(part) {
3344
+ return part.toLowerCase().includes("build");
3345
+ }
3346
+
3347
+ // src/utils/files.ts
3896
3348
  function createIgnoreFilter(projectRoot3) {
3897
3349
  const ig = (0, import_ignore.default)();
3898
3350
  const defaultIgnores = [
@@ -3914,9 +3366,9 @@ function createIgnoreFilter(projectRoot3) {
3914
3366
  "**/*build*/**"
3915
3367
  ];
3916
3368
  ig.add(defaultIgnores);
3917
- const gitignorePath = path8.join(projectRoot3, ".gitignore");
3918
- if (existsSync6(gitignorePath)) {
3919
- const gitignoreContent = readFileSync5(gitignorePath, "utf-8");
3369
+ const gitignorePath = path6.join(projectRoot3, ".gitignore");
3370
+ if (existsSync5(gitignorePath)) {
3371
+ const gitignoreContent = readFileSync4(gitignorePath, "utf-8");
3920
3372
  ig.add(gitignoreContent);
3921
3373
  }
3922
3374
  return ig;
@@ -3941,8 +3393,8 @@ async function* walkDirectory(dir, projectRoot3, includePatterns, excludePattern
3941
3393
  const filesInDir = [];
3942
3394
  const subdirs = [];
3943
3395
  for (const entry of entries) {
3944
- const fullPath = path8.join(dir, entry.name);
3945
- const relativePath = path8.relative(projectRoot3, fullPath);
3396
+ const fullPath = path6.join(dir, entry.name);
3397
+ const relativePath = path6.relative(projectRoot3, fullPath);
3946
3398
  if (isHiddenPathSegment(entry.name)) {
3947
3399
  if (entry.isDirectory()) {
3948
3400
  skipped.push({ path: relativePath, reason: "excluded" });
@@ -3991,7 +3443,7 @@ async function* walkDirectory(dir, projectRoot3, includePatterns, excludePattern
3991
3443
  yield f;
3992
3444
  }
3993
3445
  for (let i = options.maxFilesPerDirectory; i < filesInDir.length; i++) {
3994
- skipped.push({ path: path8.relative(projectRoot3, filesInDir[i].path), reason: "excluded" });
3446
+ skipped.push({ path: path6.relative(projectRoot3, filesInDir[i].path), reason: "excluded" });
3995
3447
  }
3996
3448
  const canRecurse = options.maxDepth === -1 || currentDepth < options.maxDepth;
3997
3449
  if (canRecurse) {
@@ -4031,8 +3483,8 @@ async function collectFiles(projectRoot3, includePatterns, excludePatterns, maxF
4031
3483
  if (additionalRoots && additionalRoots.length > 0) {
4032
3484
  const normalizedRoots = /* @__PURE__ */ new Set();
4033
3485
  for (const kbRoot of additionalRoots) {
4034
- const resolved = path8.normalize(
4035
- path8.isAbsolute(kbRoot) ? kbRoot : path8.resolve(projectRoot3, kbRoot)
3486
+ const resolved = path6.normalize(
3487
+ path6.isAbsolute(kbRoot) ? kbRoot : path6.resolve(projectRoot3, kbRoot)
4036
3488
  );
4037
3489
  normalizedRoots.add(resolved);
4038
3490
  }
@@ -4379,7 +3831,7 @@ function initializeLogger(config) {
4379
3831
  }
4380
3832
 
4381
3833
  // src/native/index.ts
4382
- import * as path9 from "path";
3834
+ import * as path7 from "path";
4383
3835
  import * as os3 from "os";
4384
3836
  import * as module from "module";
4385
3837
  import { fileURLToPath } from "url";
@@ -4403,19 +3855,19 @@ function getNativeBinding() {
4403
3855
  let currentDir;
4404
3856
  let requireTarget;
4405
3857
  if (typeof import.meta !== "undefined" && import.meta.url) {
4406
- currentDir = path9.dirname(fileURLToPath(import.meta.url));
3858
+ currentDir = path7.dirname(fileURLToPath(import.meta.url));
4407
3859
  requireTarget = import.meta.url;
4408
3860
  } else if (typeof __dirname !== "undefined") {
4409
3861
  currentDir = __dirname;
4410
3862
  requireTarget = __filename;
4411
3863
  } else {
4412
3864
  currentDir = process.cwd();
4413
- requireTarget = path9.join(currentDir, "index.js");
3865
+ requireTarget = path7.join(currentDir, "index.js");
4414
3866
  }
4415
3867
  const normalizedDir = currentDir.replace(/\\/g, "/");
4416
- const isDevMode = normalizedDir.includes("/src/native") || currentDir.includes(path9.join("src", "native"));
4417
- const packageRoot = isDevMode ? path9.resolve(currentDir, "../..") : path9.resolve(currentDir, "..");
4418
- const nativePath = path9.join(packageRoot, "native", bindingName);
3868
+ const isDevMode = normalizedDir.includes("/src/native") || currentDir.includes(path7.join("src", "native"));
3869
+ const packageRoot = isDevMode ? path7.resolve(currentDir, "../..") : path7.resolve(currentDir, "..");
3870
+ const nativePath = path7.join(packageRoot, "native", bindingName);
4419
3871
  const require2 = module.createRequire(requireTarget);
4420
3872
  return require2(nativePath);
4421
3873
  }
@@ -4501,7 +3953,9 @@ function mapChunk(c) {
4501
3953
  return {
4502
3954
  content: c.content,
4503
3955
  startLine: c.startLine ?? c.start_line,
3956
+ startCol: c.startCol ?? c.start_col,
4504
3957
  endLine: c.endLine ?? c.end_line,
3958
+ endCol: c.endCol ?? c.end_col,
4505
3959
  chunkType: c.chunkType ?? c.chunk_type,
4506
3960
  name: c.name ?? void 0,
4507
3961
  language: c.language
@@ -4622,6 +4076,7 @@ function getEmbeddingHeaderParts(chunk, filePath) {
4622
4076
  javascript: "JavaScript",
4623
4077
  python: "Python",
4624
4078
  rust: "Rust",
4079
+ swift: "Swift",
4625
4080
  go: "Go",
4626
4081
  java: "Java"
4627
4082
  };
@@ -4630,7 +4085,16 @@ function getEmbeddingHeaderParts(chunk, filePath) {
4630
4085
  function: "function",
4631
4086
  arrow_function: "arrow function",
4632
4087
  method_definition: "method",
4088
+ method_declaration: "method",
4089
+ protocol_function_declaration: "protocol requirement",
4090
+ init_declaration: "initializer",
4091
+ deinit_declaration: "deinitializer",
4092
+ subscript_declaration: "subscript",
4633
4093
  class_declaration: "class",
4094
+ actor_declaration: "actor",
4095
+ extension_declaration: "extension",
4096
+ protocol_declaration: "protocol",
4097
+ struct_declaration: "struct",
4634
4098
  interface_declaration: "interface",
4635
4099
  type_alias_declaration: "type alias",
4636
4100
  enum_declaration: "enum",
@@ -5148,7 +4612,7 @@ var Database = class _Database {
5148
4612
  };
5149
4613
 
5150
4614
  // src/tools/changed-files.ts
5151
- import * as path10 from "path";
4615
+ import * as path8 from "path";
5152
4616
  import { execFile } from "child_process";
5153
4617
  import { promisify } from "util";
5154
4618
  var execFileAsync = promisify(execFile);
@@ -5236,8 +4700,8 @@ function normalizeFiles(rawFiles, projectRoot3) {
5236
4700
  for (const raw of rawFiles) {
5237
4701
  const trimmed = raw.trim();
5238
4702
  if (!trimmed) continue;
5239
- const absolute = path10.resolve(projectRoot3, trimmed);
5240
- const relative7 = path10.relative(projectRoot3, absolute);
4703
+ const absolute = path8.resolve(projectRoot3, trimmed);
4704
+ const relative7 = path8.relative(projectRoot3, absolute);
5241
4705
  const cleaned = relative7.startsWith("./") ? relative7.slice(2) : relative7;
5242
4706
  if (!seen.has(cleaned)) {
5243
4707
  seen.add(cleaned);
@@ -5249,7 +4713,7 @@ function normalizeFiles(rawFiles, projectRoot3) {
5249
4713
 
5250
4714
  // src/indexer/git-blame.ts
5251
4715
  import { execFile as execFile2 } from "child_process";
5252
- import * as path11 from "path";
4716
+ import * as path9 from "path";
5253
4717
  import { promisify as promisify2 } from "util";
5254
4718
  var execFileAsync2 = promisify2(execFile2);
5255
4719
  function parseGitBlamePorcelain(output) {
@@ -5287,7 +4751,7 @@ function parseGitBlamePorcelain(output) {
5287
4751
  return Array.from(commits.values()).filter((commit) => commit.lines > 0).sort((a, b) => b.lines - a.lines || b.committedAt - a.committedAt)[0];
5288
4752
  }
5289
4753
  async function getChunkGitBlame(projectRoot3, filePath, startLine, endLine) {
5290
- const relativePath = path11.relative(projectRoot3, filePath);
4754
+ const relativePath = path9.relative(projectRoot3, filePath);
5291
4755
  try {
5292
4756
  const { stdout } = await execFileAsync2(
5293
4757
  "git",
@@ -5303,18 +4767,18 @@ async function getChunkGitBlame(projectRoot3, filePath, startLine, endLine) {
5303
4767
  // src/indexer/index-lock.ts
5304
4768
  import { randomUUID } from "crypto";
5305
4769
  import {
5306
- existsSync as existsSync7,
4770
+ existsSync as existsSync6,
5307
4771
  lstatSync,
5308
- mkdirSync as mkdirSync2,
5309
- readFileSync as readFileSync6,
4772
+ mkdirSync,
4773
+ readFileSync as readFileSync5,
5310
4774
  readdirSync as readdirSync2,
5311
4775
  realpathSync,
5312
4776
  renameSync,
5313
4777
  rmSync,
5314
- writeFileSync as writeFileSync2
4778
+ writeFileSync
5315
4779
  } from "fs";
5316
4780
  import * as os4 from "os";
5317
- import * as path12 from "path";
4781
+ import * as path10 from "path";
5318
4782
  var OWNER_FILE_NAME = "owner.json";
5319
4783
  var RECLAIM_DIRECTORY_NAME = "reclaiming";
5320
4784
  var RECOVERY_MARKER_PREFIX = "indexing.lock.recovery.";
@@ -5371,7 +4835,7 @@ function parseReclaimOwner(value) {
5371
4835
  }
5372
4836
  function readJsonDirectory(directoryPath, parser) {
5373
4837
  try {
5374
- return parser(JSON.parse(readFileSync6(path12.join(directoryPath, OWNER_FILE_NAME), "utf-8")));
4838
+ return parser(JSON.parse(readFileSync5(path10.join(directoryPath, OWNER_FILE_NAME), "utf-8")));
5375
4839
  } catch {
5376
4840
  return null;
5377
4841
  }
@@ -5387,7 +4851,7 @@ function readRecoveryOwner(markerPath) {
5387
4851
  }
5388
4852
  function readLegacyOwner(lockPath) {
5389
4853
  try {
5390
- const parsed = JSON.parse(readFileSync6(lockPath, "utf-8"));
4854
+ const parsed = JSON.parse(readFileSync5(lockPath, "utf-8"));
5391
4855
  if (!Number.isInteger(parsed.pid) || Number(parsed.pid) <= 0) return null;
5392
4856
  if (typeof parsed.startedAt !== "string" || Number.isNaN(Date.parse(parsed.startedAt))) return null;
5393
4857
  return {
@@ -5422,23 +4886,23 @@ function sameReclaimOwner(left, right) {
5422
4886
  function publishJsonDirectory(finalPath, value) {
5423
4887
  const candidatePath = `${finalPath}.candidate.${process.pid}.${randomUUID()}`;
5424
4888
  try {
5425
- mkdirSync2(candidatePath, { mode: 448 });
4889
+ mkdirSync(candidatePath, { mode: 448 });
5426
4890
  } catch (error) {
5427
4891
  if (getErrorCode(error) === "ENOENT") return false;
5428
4892
  throw error;
5429
4893
  }
5430
4894
  try {
5431
- writeFileSync2(path12.join(candidatePath, OWNER_FILE_NAME), JSON.stringify(value), {
4895
+ writeFileSync(path10.join(candidatePath, OWNER_FILE_NAME), JSON.stringify(value), {
5432
4896
  encoding: "utf-8",
5433
4897
  flag: "wx",
5434
4898
  mode: 384
5435
4899
  });
5436
- if (existsSync7(finalPath)) return false;
4900
+ if (existsSync6(finalPath)) return false;
5437
4901
  try {
5438
4902
  renameSync(candidatePath, finalPath);
5439
4903
  return true;
5440
4904
  } catch (error) {
5441
- if (existsSync7(finalPath)) return false;
4905
+ if (existsSync6(finalPath)) return false;
5442
4906
  if (getErrorCode(error) === "ENOENT") return false;
5443
4907
  throw error;
5444
4908
  }
@@ -5446,7 +4910,7 @@ function publishJsonDirectory(finalPath, value) {
5446
4910
  if (getErrorCode(error) === "ENOENT") return false;
5447
4911
  throw error;
5448
4912
  } finally {
5449
- if (existsSync7(candidatePath)) rmSync(candidatePath, { recursive: true, force: true });
4913
+ if (existsSync6(candidatePath)) rmSync(candidatePath, { recursive: true, force: true });
5450
4914
  }
5451
4915
  }
5452
4916
  function createOwner(operation) {
@@ -5459,7 +4923,7 @@ function createOwner(operation) {
5459
4923
  };
5460
4924
  }
5461
4925
  function recoveryMarkerPath(indexPath, owner) {
5462
- return path12.join(indexPath, `${RECOVERY_MARKER_PREFIX}${owner.token}`);
4926
+ return path10.join(indexPath, `${RECOVERY_MARKER_PREFIX}${owner.token}`);
5463
4927
  }
5464
4928
  function publishRecoveryMarker(indexPath, owner) {
5465
4929
  const markerPath = recoveryMarkerPath(indexPath, owner);
@@ -5478,7 +4942,7 @@ function getPendingRecoveries(indexPath) {
5478
4942
  return UUID_PATTERN.test(name.slice(RECOVERY_MARKER_PREFIX.length));
5479
4943
  }).sort();
5480
4944
  for (const markerName of markerNames) {
5481
- const markerPath = path12.join(indexPath, markerName);
4945
+ const markerPath = path10.join(indexPath, markerName);
5482
4946
  const markerToken = markerName.slice(RECOVERY_MARKER_PREFIX.length);
5483
4947
  let markerStats;
5484
4948
  try {
@@ -5510,11 +4974,11 @@ function cleanupDeadPublicationCandidates(indexPath) {
5510
4974
  const pid = Number(match[1]);
5511
4975
  if (!Number.isInteger(pid) || pid <= 0) continue;
5512
4976
  if (getOwnerLiveness({ pid, hostname: os4.hostname() }) !== "dead") continue;
5513
- rmSync(path12.join(indexPath, entry), { recursive: true, force: true });
4977
+ rmSync(path10.join(indexPath, entry), { recursive: true, force: true });
5514
4978
  }
5515
4979
  }
5516
4980
  function removeDeadReclaimMarker(lockPath, expectedOwner) {
5517
- const markerPath = path12.join(lockPath, RECLAIM_DIRECTORY_NAME);
4981
+ const markerPath = path10.join(lockPath, RECLAIM_DIRECTORY_NAME);
5518
4982
  const marker = readReclaimOwner(markerPath);
5519
4983
  if (!marker || marker.expectedOwnerToken !== expectedOwner.token || getOwnerLiveness(marker) !== "dead") {
5520
4984
  return false;
@@ -5533,7 +4997,7 @@ function removeDeadReclaimMarker(lockPath, expectedOwner) {
5533
4997
  const claimedMarker = readReclaimOwner(claimedMarkerPath);
5534
4998
  const ownerAfterClaim = readDirectoryOwner(lockPath);
5535
4999
  if (!claimedMarker || !sameReclaimOwner(claimedMarker, marker) || !ownerAfterClaim || !sameOwner(ownerAfterClaim, expectedOwner) || getOwnerLiveness(ownerAfterClaim) !== "dead") {
5536
- if (!existsSync7(markerPath) && existsSync7(claimedMarkerPath)) {
5000
+ if (!existsSync6(markerPath) && existsSync6(claimedMarkerPath)) {
5537
5001
  renameSync(claimedMarkerPath, markerPath);
5538
5002
  }
5539
5003
  return false;
@@ -5542,7 +5006,7 @@ function removeDeadReclaimMarker(lockPath, expectedOwner) {
5542
5006
  return true;
5543
5007
  }
5544
5008
  function reclaimDeadOwner(indexPath, lockPath, expectedOwner) {
5545
- const reclaimPath = path12.join(lockPath, RECLAIM_DIRECTORY_NAME);
5009
+ const reclaimPath = path10.join(lockPath, RECLAIM_DIRECTORY_NAME);
5546
5010
  const reclaimOwner = {
5547
5011
  pid: process.pid,
5548
5012
  hostname: os4.hostname(),
@@ -5594,9 +5058,9 @@ function isIndexLockContentionError(error) {
5594
5058
  return error instanceof IndexLockContentionError || typeof error === "object" && error !== null && "code" in error && error.code === "INDEX_BUSY";
5595
5059
  }
5596
5060
  function acquireIndexLock(indexPath, operation) {
5597
- mkdirSync2(indexPath, { recursive: true });
5061
+ mkdirSync(indexPath, { recursive: true });
5598
5062
  const canonicalIndexPath = realpathSync.native(indexPath);
5599
- const lockPath = path12.join(canonicalIndexPath, "indexing.lock");
5063
+ const lockPath = path10.join(canonicalIndexPath, "indexing.lock");
5600
5064
  cleanupDeadPublicationCandidates(canonicalIndexPath);
5601
5065
  for (let attempt = 0; attempt < 6; attempt += 1) {
5602
5066
  const owner = createOwner(operation);
@@ -5652,7 +5116,7 @@ function releaseIndexLock(lease) {
5652
5116
  }
5653
5117
  const claimedOwner = readDirectoryOwner(releasePath);
5654
5118
  if (!claimedOwner || !sameOwner(claimedOwner, lease.owner)) {
5655
- if (!existsSync7(lease.lockPath) && existsSync7(releasePath)) {
5119
+ if (!existsSync6(lease.lockPath) && existsSync6(releasePath)) {
5656
5120
  renameSync(releasePath, lease.lockPath);
5657
5121
  }
5658
5122
  return false;
@@ -5664,59 +5128,25 @@ function releaseIndexLock(lease) {
5664
5128
  }
5665
5129
  return true;
5666
5130
  }
5667
- async function withIndexLock(indexPath, operation, callback, options = {}) {
5668
- const lease = acquireIndexLock(indexPath, operation);
5669
- let result;
5670
- let callbackError;
5671
- let callbackFailed = false;
5672
- try {
5673
- result = await callback(lease);
5674
- } catch (error) {
5675
- callbackFailed = true;
5676
- callbackError = error;
5677
- }
5678
- if (!callbackFailed && options.completeRecoveries !== false) {
5679
- try {
5680
- completeLeaseRecovery(lease);
5681
- } catch (error) {
5682
- callbackFailed = true;
5683
- callbackError = error;
5684
- }
5685
- }
5686
- let releaseError;
5687
- try {
5688
- if (!releaseIndexLock(lease)) {
5689
- releaseError = new Error(`Lost ownership of index mutation lease ${lease.owner.token}`);
5690
- }
5691
- } catch (error) {
5692
- releaseError = error;
5693
- }
5694
- if (releaseError !== void 0) {
5695
- if (callbackFailed) throw new AggregateError([callbackError, releaseError], "Index mutation and lease release both failed");
5696
- throw releaseError;
5697
- }
5698
- if (callbackFailed) throw callbackError;
5699
- return result;
5700
- }
5701
5131
  function createLeaseTemporaryPath(targetPath, owner, kind = "tmp") {
5702
5132
  if (kind === "bak") return `${targetPath}.bak.${owner.pid}.${owner.token}`;
5703
5133
  temporaryCounter += 1;
5704
5134
  return `${targetPath}.tmp.${owner.pid}.${owner.token}.${temporaryCounter}`;
5705
5135
  }
5706
5136
  function removeLeaseTemporaryPath(temporaryPath) {
5707
- if (existsSync7(temporaryPath)) rmSync(temporaryPath, { recursive: true, force: true });
5137
+ if (existsSync6(temporaryPath)) rmSync(temporaryPath, { recursive: true, force: true });
5708
5138
  }
5709
5139
  function recoverLeaseArtifacts(indexPath, owner, backupTargets) {
5710
5140
  for (const targetPath of backupTargets) {
5711
5141
  const backupPath = createLeaseTemporaryPath(targetPath, owner, "bak");
5712
- if (!existsSync7(backupPath)) continue;
5713
- if (existsSync7(targetPath)) rmSync(targetPath, { recursive: true, force: true });
5142
+ if (!existsSync6(backupPath)) continue;
5143
+ if (existsSync6(targetPath)) rmSync(targetPath, { recursive: true, force: true });
5714
5144
  renameSync(backupPath, targetPath);
5715
5145
  }
5716
5146
  const temporaryOwnerMarker = `.tmp.${owner.pid}.${owner.token}.`;
5717
5147
  for (const entry of readdirSync2(indexPath)) {
5718
5148
  if (!entry.includes(temporaryOwnerMarker)) continue;
5719
- rmSync(path12.join(indexPath, entry), { recursive: true, force: true });
5149
+ rmSync(path10.join(indexPath, entry), { recursive: true, force: true });
5720
5150
  }
5721
5151
  }
5722
5152
  function completeLeaseRecovery(lease) {
@@ -5732,8 +5162,18 @@ function completeLeaseRecovery(lease) {
5732
5162
  }
5733
5163
 
5734
5164
  // src/indexer/index.ts
5735
- var CALL_GRAPH_LANGUAGES = /* @__PURE__ */ new Set(["typescript", "tsx", "javascript", "jsx", "python", "go", "rust", "php", "apex", "zig", "gdscript", "matlab", "bash"]);
5736
- var CASE_INSENSITIVE_LANGUAGES = /* @__PURE__ */ new Set(["apex"]);
5165
+ var CALL_GRAPH_LANGUAGES = /* @__PURE__ */ new Set(["typescript", "tsx", "javascript", "jsx", "python", "go", "rust", "swift", "php", "apex", "zig", "gdscript", "matlab", "bash", "c", "cpp", "metal"]);
5166
+ var CASE_INSENSITIVE_LANGUAGES = /* @__PURE__ */ new Set(["apex", "php"]);
5167
+ var CALL_GRAPH_RESOLUTION_VERSION = "4";
5168
+ var PHP_FUNCTION_SYMBOL_CHUNK_TYPES = /* @__PURE__ */ new Set([
5169
+ "function_declaration",
5170
+ "function",
5171
+ "function_definition"
5172
+ ]);
5173
+ var PHP_CLASS_SYMBOL_CHUNK_TYPES = /* @__PURE__ */ new Set([
5174
+ "class_declaration",
5175
+ "class_definition"
5176
+ ]);
5737
5177
  var CALL_GRAPH_SYMBOL_CHUNK_TYPES = /* @__PURE__ */ new Set([
5738
5178
  "function_declaration",
5739
5179
  "function",
@@ -5746,6 +5186,9 @@ var CALL_GRAPH_SYMBOL_CHUNK_TYPES = /* @__PURE__ */ new Set([
5746
5186
  "enum_declaration",
5747
5187
  "function_definition",
5748
5188
  "class_definition",
5189
+ "class_specifier",
5190
+ "struct_specifier",
5191
+ "namespace_definition",
5749
5192
  "decorated_definition",
5750
5193
  "method_declaration",
5751
5194
  "type_declaration",
@@ -5761,6 +5204,14 @@ var CALL_GRAPH_SYMBOL_CHUNK_TYPES = /* @__PURE__ */ new Set([
5761
5204
  "test_declaration",
5762
5205
  "struct_declaration",
5763
5206
  "union_declaration",
5207
+ // Synthetic Swift declarations or declarations specific to tree-sitter-swift.
5208
+ "actor_declaration",
5209
+ "extension_declaration",
5210
+ "protocol_declaration",
5211
+ "protocol_function_declaration",
5212
+ "init_declaration",
5213
+ "deinit_declaration",
5214
+ "subscript_declaration",
5764
5215
  // GDScript declarations whose names participate in the call graph.
5765
5216
  // `function_definition` and `class_definition` are already in the set
5766
5217
  // above (shared with Python/C/Bash and Python, respectively).
@@ -5770,6 +5221,53 @@ var CALL_GRAPH_SYMBOL_CHUNK_TYPES = /* @__PURE__ */ new Set([
5770
5221
  "const_statement",
5771
5222
  "class_name_statement"
5772
5223
  ]);
5224
+ var C_FAMILY_TYPE_SYMBOL_CHUNK_TYPES = /* @__PURE__ */ new Set(["class_specifier", "struct_specifier"]);
5225
+ function isCompatibleCFamilyCallTarget(language, callType, symbolKind) {
5226
+ if (language !== "c" && language !== "cpp") return true;
5227
+ if (symbolKind === "namespace_definition") return callType === "Import";
5228
+ const isTypeSymbol = C_FAMILY_TYPE_SYMBOL_CHUNK_TYPES.has(symbolKind);
5229
+ if (callType === "Constructor" || callType === "Inherits" || callType === "Implements") {
5230
+ return isTypeSymbol;
5231
+ }
5232
+ return !isTypeSymbol;
5233
+ }
5234
+ var EXECUTABLE_SYMBOL_CHUNK_TYPES = /* @__PURE__ */ new Set([
5235
+ "function_declaration",
5236
+ "function",
5237
+ "arrow_function",
5238
+ "method_definition",
5239
+ "function_definition",
5240
+ "method_declaration",
5241
+ "function_item",
5242
+ "protocol_function_declaration",
5243
+ "init_declaration",
5244
+ "deinit_declaration",
5245
+ "subscript_declaration",
5246
+ "constructor_definition",
5247
+ "trigger_declaration",
5248
+ "test_declaration"
5249
+ ]);
5250
+ function findEnclosingSymbol(symbols, line, column) {
5251
+ let best;
5252
+ for (const symbol of symbols) {
5253
+ if (line < symbol.startLine || line > symbol.endLine) continue;
5254
+ if (column !== void 0 && (line === symbol.startLine && column < symbol.startCol || line === symbol.endLine && column >= symbol.endCol)) {
5255
+ continue;
5256
+ }
5257
+ if (!best) {
5258
+ best = symbol;
5259
+ continue;
5260
+ }
5261
+ const span = symbol.endLine - symbol.startLine;
5262
+ const bestSpan = best.endLine - best.startLine;
5263
+ const isNarrowerPositionRange = column !== void 0 && span === bestSpan && symbol.startLine === best.startLine && symbol.endLine === best.endLine && symbol.startCol >= best.startCol && symbol.endCol <= best.endCol && (symbol.startCol > best.startCol || symbol.endCol < best.endCol);
5264
+ const isMoreSpecificTie = span === bestSpan && symbol.startLine === best.startLine && EXECUTABLE_SYMBOL_CHUNK_TYPES.has(symbol.kind) && !EXECUTABLE_SYMBOL_CHUNK_TYPES.has(best.kind);
5265
+ if (span < bestSpan || span === bestSpan && symbol.startLine > best.startLine || isNarrowerPositionRange || isMoreSpecificTie) {
5266
+ best = symbol;
5267
+ }
5268
+ }
5269
+ return best;
5270
+ }
5773
5271
  function float32ArrayToBuffer(arr) {
5774
5272
  const float32 = new Float32Array(arr);
5775
5273
  return Buffer.from(float32.buffer);
@@ -5854,6 +5352,8 @@ function hasBlameMetadata(metadata) {
5854
5352
  }
5855
5353
  var INDEX_METADATA_VERSION = "1";
5856
5354
  var EMBEDDING_STRATEGY_VERSION = "2";
5355
+ var SWIFT_PARSER_VERSION = "1";
5356
+ var METAL_PARSER_VERSION = "1";
5857
5357
  var RANKING_TOKEN_CACHE_LIMIT = 4096;
5858
5358
  var RANK_HYBRID_CACHE_LIMIT = 256;
5859
5359
  function createPendingChunkStorageText(texts) {
@@ -6010,9 +5510,9 @@ function hasAllEmbeddingParts(parts, expectedPartCount) {
6010
5510
  return true;
6011
5511
  }
6012
5512
  function isPathWithinRoot(filePath, rootPath) {
6013
- const normalizedFilePath = path13.resolve(filePath);
6014
- const normalizedRoot = path13.resolve(rootPath);
6015
- return normalizedFilePath === normalizedRoot || normalizedFilePath.startsWith(`${normalizedRoot}${path13.sep}`);
5513
+ const normalizedFilePath = path11.resolve(filePath);
5514
+ const normalizedRoot = path11.resolve(rootPath);
5515
+ return normalizedFilePath === normalizedRoot || normalizedFilePath.startsWith(`${normalizedRoot}${path11.sep}`);
6016
5516
  }
6017
5517
  var rankingQueryTokenCache = /* @__PURE__ */ new Map();
6018
5518
  var rankingNameTokenCache = /* @__PURE__ */ new Map();
@@ -6176,15 +5676,25 @@ function chunkTypeBoost(chunkType) {
6176
5676
  case "function_declaration":
6177
5677
  case "method":
6178
5678
  case "method_definition":
5679
+ case "method_declaration":
5680
+ case "protocol_function_declaration":
5681
+ case "init_declaration":
5682
+ case "deinit_declaration":
5683
+ case "subscript_declaration":
6179
5684
  case "class":
6180
5685
  case "class_declaration":
5686
+ case "actor_declaration":
5687
+ case "extension_declaration":
6181
5688
  return 0.2;
6182
5689
  case "interface":
6183
5690
  case "type":
6184
5691
  case "enum":
5692
+ case "enum_declaration":
6185
5693
  case "struct":
5694
+ case "struct_declaration":
6186
5695
  case "impl":
6187
5696
  case "trait":
5697
+ case "protocol_declaration":
6188
5698
  case "module":
6189
5699
  return 0.1;
6190
5700
  default:
@@ -6291,11 +5801,21 @@ function isImplementationChunkType(chunkType) {
6291
5801
  "function_declaration",
6292
5802
  "method",
6293
5803
  "method_definition",
5804
+ "method_declaration",
5805
+ "protocol_function_declaration",
5806
+ "init_declaration",
5807
+ "deinit_declaration",
5808
+ "subscript_declaration",
6294
5809
  "class",
6295
5810
  "class_declaration",
5811
+ "actor_declaration",
5812
+ "extension_declaration",
6296
5813
  "interface",
5814
+ "protocol_declaration",
6297
5815
  "type",
6298
5816
  "enum",
5817
+ "enum_declaration",
5818
+ "struct_declaration",
6299
5819
  "module"
6300
5820
  ].includes(chunkType);
6301
5821
  }
@@ -7112,21 +6632,21 @@ var Indexer = class {
7112
6632
  this.config = config;
7113
6633
  this.host = host;
7114
6634
  this.indexPath = this.getIndexPath();
7115
- this.fileHashCachePath = path13.join(this.indexPath, "file-hashes.json");
7116
- this.failedBatchesPath = path13.join(this.indexPath, "failed-batches.json");
6635
+ this.fileHashCachePath = path11.join(this.indexPath, "file-hashes.json");
6636
+ this.failedBatchesPath = path11.join(this.indexPath, "failed-batches.json");
7117
6637
  this.logger = initializeLogger(config.debug);
7118
6638
  }
7119
6639
  getIndexPath() {
7120
6640
  return resolveProjectIndexPath(this.projectRoot, this.config.scope, this.host);
7121
6641
  }
7122
6642
  isLocalProjectIndexPath() {
7123
- const localProjectIndexPaths = [path13.join(this.projectRoot, getHostProjectIndexRelativePath(this.host))];
6643
+ const localProjectIndexPaths = [path11.join(this.projectRoot, getHostProjectIndexRelativePath(this.host))];
7124
6644
  if (this.host !== "opencode") {
7125
- localProjectIndexPaths.push(path13.join(this.projectRoot, getHostProjectIndexRelativePath("opencode")));
6645
+ localProjectIndexPaths.push(path11.join(this.projectRoot, getHostProjectIndexRelativePath("opencode")));
7126
6646
  }
7127
6647
  return localProjectIndexPaths.some((localPath) => {
7128
- if (!existsSync8(localPath) || !existsSync8(this.indexPath)) {
7129
- return path13.resolve(this.indexPath) === path13.resolve(localPath);
6648
+ if (!existsSync7(localPath) || !existsSync7(this.indexPath)) {
6649
+ return path11.resolve(this.indexPath) === path11.resolve(localPath);
7130
6650
  }
7131
6651
  const indexStats = statSync3(this.indexPath);
7132
6652
  const localStats = statSync3(localPath);
@@ -7168,8 +6688,8 @@ var Indexer = class {
7168
6688
  async withIndexMutationLease(operation, callback) {
7169
6689
  const lease = acquireIndexLock(this.indexPath, operation);
7170
6690
  this.indexPath = lease.canonicalIndexPath;
7171
- this.fileHashCachePath = path13.join(this.indexPath, "file-hashes.json");
7172
- this.failedBatchesPath = path13.join(this.indexPath, "failed-batches.json");
6691
+ this.fileHashCachePath = path11.join(this.indexPath, "file-hashes.json");
6692
+ this.failedBatchesPath = path11.join(this.indexPath, "failed-batches.json");
7173
6693
  this.activeIndexLease = lease;
7174
6694
  let result;
7175
6695
  let callbackError;
@@ -7203,7 +6723,7 @@ var Indexer = class {
7203
6723
  } catch (error) {
7204
6724
  releaseError = error;
7205
6725
  this.writerArtifactFingerprint = null;
7206
- if (!existsSync8(lease.lockPath) && this.activeIndexLease?.owner.token === lease.owner.token) {
6726
+ if (!existsSync7(lease.lockPath) && this.activeIndexLease?.owner.token === lease.owner.token) {
7207
6727
  this.activeIndexLease = null;
7208
6728
  }
7209
6729
  }
@@ -7221,11 +6741,11 @@ var Indexer = class {
7221
6741
  return this.activeIndexLease;
7222
6742
  }
7223
6743
  loadFileHashCache() {
7224
- if (!existsSync8(this.fileHashCachePath)) {
6744
+ if (!existsSync7(this.fileHashCachePath)) {
7225
6745
  return;
7226
6746
  }
7227
6747
  try {
7228
- const data = readFileSync7(this.fileHashCachePath, "utf-8");
6748
+ const data = readFileSync6(this.fileHashCachePath, "utf-8");
7229
6749
  const parsed = JSON.parse(data);
7230
6750
  this.fileHashCache = new Map(Object.entries(parsed));
7231
6751
  } catch (error) {
@@ -7247,9 +6767,9 @@ var Indexer = class {
7247
6767
  atomicWriteSync(targetPath, data) {
7248
6768
  const lease = this.requireActiveLease();
7249
6769
  const tempPath = createLeaseTemporaryPath(targetPath, lease.owner, "tmp");
7250
- mkdirSync3(path13.dirname(targetPath), { recursive: true });
6770
+ mkdirSync2(path11.dirname(targetPath), { recursive: true });
7251
6771
  try {
7252
- writeFileSync3(tempPath, data);
6772
+ writeFileSync2(tempPath, data);
7253
6773
  renameSync2(tempPath, targetPath);
7254
6774
  } finally {
7255
6775
  removeLeaseTemporaryPath(tempPath);
@@ -7257,14 +6777,14 @@ var Indexer = class {
7257
6777
  }
7258
6778
  saveInvertedIndex(invertedIndex) {
7259
6779
  this.atomicWriteSync(
7260
- path13.join(this.indexPath, "inverted-index.json"),
6780
+ path11.join(this.indexPath, "inverted-index.json"),
7261
6781
  invertedIndex.serialize()
7262
6782
  );
7263
6783
  }
7264
6784
  getScopedRoots() {
7265
- const roots = /* @__PURE__ */ new Set([path13.resolve(this.projectRoot)]);
6785
+ const roots = /* @__PURE__ */ new Set([path11.resolve(this.projectRoot)]);
7266
6786
  for (const kbRoot of this.config.knowledgeBases) {
7267
- roots.add(path13.resolve(this.projectRoot, kbRoot));
6787
+ roots.add(path11.resolve(this.projectRoot, kbRoot));
7268
6788
  }
7269
6789
  return Array.from(roots);
7270
6790
  }
@@ -7273,31 +6793,54 @@ var Indexer = class {
7273
6793
  if (this.config.scope !== "global") {
7274
6794
  return branchName;
7275
6795
  }
7276
- const projectHash = hashContent(path13.resolve(this.projectRoot)).slice(0, 16);
6796
+ const projectHash = hashContent(path11.resolve(this.projectRoot)).slice(0, 16);
7277
6797
  return `${projectHash}:${branchName}`;
7278
6798
  }
7279
6799
  getBranchCatalogKeyFor(branchName) {
7280
6800
  if (this.config.scope !== "global") {
7281
6801
  return branchName;
7282
6802
  }
7283
- const projectHash = hashContent(path13.resolve(this.projectRoot)).slice(0, 16);
6803
+ const projectHash = hashContent(path11.resolve(this.projectRoot)).slice(0, 16);
7284
6804
  return `${projectHash}:${branchName}`;
7285
6805
  }
7286
6806
  getLegacyBranchCatalogKey() {
7287
6807
  return this.currentBranch || "default";
7288
6808
  }
7289
6809
  getLegacyMigrationMetadataKey() {
7290
- const projectHash = hashContent(path13.resolve(this.projectRoot)).slice(0, 16);
6810
+ const projectHash = hashContent(path11.resolve(this.projectRoot)).slice(0, 16);
7291
6811
  return `index.globalBranchMigration.${projectHash}`;
7292
6812
  }
7293
6813
  getProjectEmbeddingStrategyMetadataKey() {
7294
- const projectHash = hashContent(path13.resolve(this.projectRoot)).slice(0, 16);
6814
+ const projectHash = hashContent(path11.resolve(this.projectRoot)).slice(0, 16);
7295
6815
  return `index.embeddingStrategyVersion.${projectHash}`;
7296
6816
  }
7297
6817
  getProjectForceReembedMetadataKey() {
7298
- const projectHash = hashContent(path13.resolve(this.projectRoot)).slice(0, 16);
6818
+ const projectHash = hashContent(path11.resolve(this.projectRoot)).slice(0, 16);
7299
6819
  return `index.forceReembed.${projectHash}`;
7300
6820
  }
6821
+ getCallGraphResolutionMetadataKey() {
6822
+ if (this.config.scope !== "global") {
6823
+ return "index.callGraphResolutionVersion";
6824
+ }
6825
+ const projectHash = hashContent(path11.resolve(this.projectRoot)).slice(0, 16);
6826
+ return `index.callGraphResolutionVersion.${projectHash}`;
6827
+ }
6828
+ getSwiftParserVersionMetadataKey() {
6829
+ const key = "index.parser.swiftVersion";
6830
+ if (this.config.scope !== "global") {
6831
+ return key;
6832
+ }
6833
+ const projectHash = hashContent(path11.resolve(this.projectRoot)).slice(0, 16);
6834
+ return `${key}.${projectHash}`;
6835
+ }
6836
+ getMetalParserVersionMetadataKey() {
6837
+ const key = "index.parser.metalVersion";
6838
+ if (this.config.scope !== "global") {
6839
+ return key;
6840
+ }
6841
+ const projectHash = hashContent(path11.resolve(this.projectRoot)).slice(0, 16);
6842
+ return `${key}.${projectHash}`;
6843
+ }
7301
6844
  hasProjectForceReembedPending() {
7302
6845
  return this.config.scope === "global" && this.database?.getMetadata(this.getProjectForceReembedMetadataKey()) === "true";
7303
6846
  }
@@ -7389,7 +6932,7 @@ var Indexer = class {
7389
6932
  if (!this.database) {
7390
6933
  return { chunkIds, symbolIds };
7391
6934
  }
7392
- const projectRootPath = path13.resolve(this.projectRoot);
6935
+ const projectRootPath = path11.resolve(this.projectRoot);
7393
6936
  const projectLocalFilePaths = /* @__PURE__ */ new Set([
7394
6937
  ...Array.from(this.fileHashCache.keys()).filter(
7395
6938
  (filePath) => this.isFileInCurrentScope(filePath, roots) && isPathWithinRoot(filePath, projectRootPath)
@@ -7412,7 +6955,7 @@ var Indexer = class {
7412
6955
  if (this.config.scope !== "global") {
7413
6956
  return this.getBranchCatalogCleanupKeys();
7414
6957
  }
7415
- const projectHash = hashContent(path13.resolve(this.projectRoot)).slice(0, 16);
6958
+ const projectHash = hashContent(path11.resolve(this.projectRoot)).slice(0, 16);
7416
6959
  const keys = /* @__PURE__ */ new Set();
7417
6960
  const projectChunkIdSet = new Set(projectChunkIds);
7418
6961
  const projectSymbolIdSet = new Set(projectSymbolIds);
@@ -7496,7 +7039,7 @@ var Indexer = class {
7496
7039
  if (!this.database || this.config.scope !== "global") {
7497
7040
  return false;
7498
7041
  }
7499
- const projectHash = hashContent(path13.resolve(this.projectRoot)).slice(0, 16);
7042
+ const projectHash = hashContent(path11.resolve(this.projectRoot)).slice(0, 16);
7500
7043
  const roots = this.getScopedRoots();
7501
7044
  const { chunkIds: projectLocalChunkIds, symbolIds: projectLocalSymbolIds } = this.getProjectLocalScopedOwnershipIds(roots);
7502
7045
  return this.database.getAllBranches().some(
@@ -7530,7 +7073,7 @@ var Indexer = class {
7530
7073
  ...Array.from(this.fileHashCache.keys()).filter((filePath) => this.isFileInCurrentScope(filePath, roots)),
7531
7074
  ...scopedEntries.map(({ metadata }) => metadata.filePath)
7532
7075
  ]);
7533
- const projectRootPath = path13.resolve(this.projectRoot);
7076
+ const projectRootPath = path11.resolve(this.projectRoot);
7534
7077
  const projectLocalFilePaths = new Set(
7535
7078
  Array.from(filePaths).filter((filePath) => isPathWithinRoot(filePath, projectRootPath))
7536
7079
  );
@@ -7608,7 +7151,7 @@ var Indexer = class {
7608
7151
  });
7609
7152
  }
7610
7153
  if (this.config.scope === "global") {
7611
- if (existsSync8(this.fileHashCachePath)) {
7154
+ if (existsSync7(this.fileHashCachePath)) {
7612
7155
  unlinkSync(this.fileHashCachePath);
7613
7156
  }
7614
7157
  await this.healthCheckUnlocked();
@@ -7628,10 +7171,10 @@ var Indexer = class {
7628
7171
  }
7629
7172
  }
7630
7173
  loadSerializedFailedBatches() {
7631
- if (!existsSync8(this.failedBatchesPath)) {
7174
+ if (!existsSync7(this.failedBatchesPath)) {
7632
7175
  return [];
7633
7176
  }
7634
- const data = readFileSync7(this.failedBatchesPath, "utf-8");
7177
+ const data = readFileSync6(this.failedBatchesPath, "utf-8");
7635
7178
  const parsed = JSON.parse(data);
7636
7179
  return parsed.map((batch) => {
7637
7180
  const chunks = Array.isArray(batch.chunks) ? batch.chunks : [];
@@ -7648,7 +7191,7 @@ var Indexer = class {
7648
7191
  }
7649
7192
  saveFailedBatches(batches) {
7650
7193
  if (batches.length === 0) {
7651
- if (existsSync8(this.failedBatchesPath)) {
7194
+ if (existsSync7(this.failedBatchesPath)) {
7652
7195
  try {
7653
7196
  unlinkSync(this.failedBatchesPath);
7654
7197
  } catch {
@@ -7940,12 +7483,12 @@ var Indexer = class {
7940
7483
  }
7941
7484
  }
7942
7485
  captureReaderArtifactFingerprint() {
7943
- const storePath = path13.join(this.indexPath, "vectors");
7486
+ const storePath = path11.join(this.indexPath, "vectors");
7944
7487
  return {
7945
7488
  vectors: `${this.getReaderFileFingerprint(storePath)}|${this.getReaderFileFingerprint(`${storePath}.meta.json`)}`,
7946
- keyword: this.getReaderFileFingerprint(path13.join(this.indexPath, "inverted-index.json")),
7947
- database: this.getReaderFileFingerprint(path13.join(this.indexPath, "codebase.db")),
7948
- databaseIdentity: this.getReaderFileFingerprint(path13.join(this.indexPath, "codebase.db"), true)
7489
+ keyword: this.getReaderFileFingerprint(path11.join(this.indexPath, "inverted-index.json")),
7490
+ database: this.getReaderFileFingerprint(path11.join(this.indexPath, "codebase.db")),
7491
+ databaseIdentity: this.getReaderFileFingerprint(path11.join(this.indexPath, "codebase.db"), true)
7949
7492
  };
7950
7493
  }
7951
7494
  refreshReaderArtifacts() {
@@ -7970,13 +7513,13 @@ var Indexer = class {
7970
7513
  issues.set(component, this.createReadIssue(component, message));
7971
7514
  this.readerArtifactRetryAfter.set(component, Date.now() + READER_ARTIFACT_RETRY_INTERVAL_MS);
7972
7515
  };
7973
- const storePath = path13.join(this.indexPath, "vectors");
7516
+ const storePath = path11.join(this.indexPath, "vectors");
7974
7517
  const vectorMetadataPath = `${storePath}.meta.json`;
7975
- const invertedIndexPath = path13.join(this.indexPath, "inverted-index.json");
7976
- const dbPath = path13.join(this.indexPath, "codebase.db");
7518
+ const invertedIndexPath = path11.join(this.indexPath, "inverted-index.json");
7519
+ const dbPath = path11.join(this.indexPath, "codebase.db");
7977
7520
  if (vectorsChanged || retryDue("vectors")) {
7978
- const vectorStoreExists = existsSync8(storePath);
7979
- const vectorMetadataExists = existsSync8(vectorMetadataPath);
7521
+ const vectorStoreExists = existsSync7(storePath);
7522
+ const vectorMetadataExists = existsSync7(vectorMetadataPath);
7980
7523
  if (vectorStoreExists && vectorMetadataExists) {
7981
7524
  try {
7982
7525
  const store = new VectorStore(storePath, this.configuredProviderInfo.modelInfo.dimensions);
@@ -7991,8 +7534,8 @@ var Indexer = class {
7991
7534
  setIssue("vectors", this.getVectorReadIssueMessage());
7992
7535
  }
7993
7536
  }
7994
- if (keywordChanged || retryDue("keyword") || !existsSync8(invertedIndexPath) && (this.store?.count() ?? 0) > 0) {
7995
- if (existsSync8(invertedIndexPath)) {
7537
+ if (keywordChanged || retryDue("keyword") || !existsSync7(invertedIndexPath) && (this.store?.count() ?? 0) > 0) {
7538
+ if (existsSync7(invertedIndexPath)) {
7996
7539
  try {
7997
7540
  const invertedIndex = new InvertedIndex(invertedIndexPath);
7998
7541
  invertedIndex.load();
@@ -8007,7 +7550,7 @@ var Indexer = class {
8007
7550
  }
8008
7551
  }
8009
7552
  if (databaseReplaced || databaseChanged && issues.has("database") || retryDue("database")) {
8010
- if (existsSync8(dbPath)) {
7553
+ if (existsSync7(dbPath)) {
8011
7554
  try {
8012
7555
  const database = Database.openReadOnly(dbPath);
8013
7556
  if (this.database) {
@@ -8098,11 +7641,11 @@ var Indexer = class {
8098
7641
  }
8099
7642
  }
8100
7643
  const dimensions = this.configuredProviderInfo.modelInfo.dimensions;
8101
- const storePath = path13.join(this.indexPath, "vectors");
7644
+ const storePath = path11.join(this.indexPath, "vectors");
8102
7645
  const vectorMetadataPath = `${storePath}.meta.json`;
8103
- const invertedIndexPath = path13.join(this.indexPath, "inverted-index.json");
8104
- const dbPath = path13.join(this.indexPath, "codebase.db");
8105
- let dbIsNew = !existsSync8(dbPath);
7646
+ const invertedIndexPath = path11.join(this.indexPath, "inverted-index.json");
7647
+ const dbPath = path11.join(this.indexPath, "codebase.db");
7648
+ let dbIsNew = !existsSync7(dbPath);
8106
7649
  const readerArtifactFingerprint = mode === "reader" ? this.captureReaderArtifactFingerprint() : null;
8107
7650
  if (mode === "writer") {
8108
7651
  await fsPromises2.mkdir(this.indexPath, { recursive: true });
@@ -8121,14 +7664,14 @@ var Indexer = class {
8121
7664
  await this.resetLocalIndexArtifacts();
8122
7665
  }
8123
7666
  this.store = new VectorStore(storePath, dimensions);
8124
- if (existsSync8(storePath) || existsSync8(vectorMetadataPath)) {
7667
+ if (existsSync7(storePath) || existsSync7(vectorMetadataPath)) {
8125
7668
  this.store.load();
8126
7669
  }
8127
7670
  this.invertedIndex = new InvertedIndex(invertedIndexPath);
8128
7671
  try {
8129
7672
  this.invertedIndex.load();
8130
7673
  } catch {
8131
- if (existsSync8(invertedIndexPath)) {
7674
+ if (existsSync7(invertedIndexPath)) {
8132
7675
  await fsPromises2.unlink(invertedIndexPath);
8133
7676
  }
8134
7677
  this.invertedIndex = new InvertedIndex(invertedIndexPath);
@@ -8146,8 +7689,8 @@ var Indexer = class {
8146
7689
  }
8147
7690
  } else {
8148
7691
  this.store = new VectorStore(storePath, dimensions);
8149
- const vectorStoreExists = existsSync8(storePath);
8150
- const vectorMetadataExists = existsSync8(vectorMetadataPath);
7692
+ const vectorStoreExists = existsSync7(storePath);
7693
+ const vectorMetadataExists = existsSync7(vectorMetadataPath);
8151
7694
  const vectorReadFailureMessage = this.getVectorReadIssueMessage();
8152
7695
  if (vectorStoreExists !== vectorMetadataExists) {
8153
7696
  this.recordReadIssue("vectors", vectorReadFailureMessage);
@@ -8160,7 +7703,7 @@ var Indexer = class {
8160
7703
  }
8161
7704
  }
8162
7705
  this.invertedIndex = new InvertedIndex(invertedIndexPath);
8163
- if (existsSync8(invertedIndexPath)) {
7706
+ if (existsSync7(invertedIndexPath)) {
8164
7707
  try {
8165
7708
  this.invertedIndex.load();
8166
7709
  } catch (error) {
@@ -8174,7 +7717,7 @@ var Indexer = class {
8174
7717
  } else if (this.store.count() > 0) {
8175
7718
  this.recordReadIssue("keyword", this.getKeywordReadIssueMessage());
8176
7719
  }
8177
- if (existsSync8(dbPath)) {
7720
+ if (existsSync7(dbPath)) {
8178
7721
  try {
8179
7722
  this.database = Database.openReadOnly(dbPath);
8180
7723
  } catch (error) {
@@ -8265,7 +7808,7 @@ var Indexer = class {
8265
7808
  if (await this.tryResetCorruptedIndex("running automatic orphan garbage collection", error)) {
8266
7809
  return {
8267
7810
  resetCorruptedIndex: true,
8268
- warning: this.getCorruptedIndexWarning(path13.join(this.indexPath, "codebase.db"))
7811
+ warning: this.getCorruptedIndexWarning(path11.join(this.indexPath, "codebase.db"))
8269
7812
  };
8270
7813
  }
8271
7814
  throw error;
@@ -8280,7 +7823,7 @@ var Indexer = class {
8280
7823
  return;
8281
7824
  }
8282
7825
  const retainedEntries = store.getAllMetadata().filter(({ key }) => !excludedSet.has(key));
8283
- const storeBasePath = path13.join(this.indexPath, "vectors");
7826
+ const storeBasePath = path11.join(this.indexPath, "vectors");
8284
7827
  const storeIndexPath = storeBasePath;
8285
7828
  const storeMetadataPath = `${storeBasePath}.meta.json`;
8286
7829
  const lease = this.requireActiveLease();
@@ -8290,18 +7833,18 @@ var Indexer = class {
8290
7833
  let backedUpMetadata = false;
8291
7834
  let rebuiltCount = 0;
8292
7835
  let skippedCount = 0;
8293
- if (existsSync8(backupIndexPath)) {
7836
+ if (existsSync7(backupIndexPath)) {
8294
7837
  unlinkSync(backupIndexPath);
8295
7838
  }
8296
- if (existsSync8(backupMetadataPath)) {
7839
+ if (existsSync7(backupMetadataPath)) {
8297
7840
  unlinkSync(backupMetadataPath);
8298
7841
  }
8299
7842
  try {
8300
- if (existsSync8(storeIndexPath)) {
7843
+ if (existsSync7(storeIndexPath)) {
8301
7844
  renameSync2(storeIndexPath, backupIndexPath);
8302
7845
  backedUpIndex = true;
8303
7846
  }
8304
- if (existsSync8(storeMetadataPath)) {
7847
+ if (existsSync7(storeMetadataPath)) {
8305
7848
  renameSync2(storeMetadataPath, backupMetadataPath);
8306
7849
  backedUpMetadata = true;
8307
7850
  }
@@ -8322,10 +7865,10 @@ var Indexer = class {
8322
7865
  rebuiltCount += 1;
8323
7866
  }
8324
7867
  store.save();
8325
- if (backedUpIndex && existsSync8(backupIndexPath)) {
7868
+ if (backedUpIndex && existsSync7(backupIndexPath)) {
8326
7869
  unlinkSync(backupIndexPath);
8327
7870
  }
8328
- if (backedUpMetadata && existsSync8(backupMetadataPath)) {
7871
+ if (backedUpMetadata && existsSync7(backupMetadataPath)) {
8329
7872
  unlinkSync(backupMetadataPath);
8330
7873
  }
8331
7874
  this.logger.gc("info", "Rebuilt vector store to avoid native remove", {
@@ -8338,16 +7881,16 @@ var Indexer = class {
8338
7881
  store.clear();
8339
7882
  } catch {
8340
7883
  }
8341
- if (existsSync8(storeIndexPath)) {
7884
+ if (existsSync7(storeIndexPath)) {
8342
7885
  unlinkSync(storeIndexPath);
8343
7886
  }
8344
- if (existsSync8(storeMetadataPath)) {
7887
+ if (existsSync7(storeMetadataPath)) {
8345
7888
  unlinkSync(storeMetadataPath);
8346
7889
  }
8347
- if (backedUpIndex && existsSync8(backupIndexPath)) {
7890
+ if (backedUpIndex && existsSync7(backupIndexPath)) {
8348
7891
  renameSync2(backupIndexPath, storeIndexPath);
8349
7892
  }
8350
- if (backedUpMetadata && existsSync8(backupMetadataPath)) {
7893
+ if (backedUpMetadata && existsSync7(backupMetadataPath)) {
8351
7894
  renameSync2(backupMetadataPath, storeMetadataPath);
8352
7895
  }
8353
7896
  if (backedUpIndex || backedUpMetadata) {
@@ -8375,15 +7918,15 @@ var Indexer = class {
8375
7918
  this.readerArtifactRetryAfter.clear();
8376
7919
  this.fileHashCache.clear();
8377
7920
  const resetPaths = [
8378
- path13.join(this.indexPath, "codebase.db"),
8379
- path13.join(this.indexPath, "codebase.db-shm"),
8380
- path13.join(this.indexPath, "codebase.db-wal"),
8381
- path13.join(this.indexPath, "vectors"),
8382
- path13.join(this.indexPath, "vectors.usearch"),
8383
- path13.join(this.indexPath, "vectors.meta.json"),
8384
- path13.join(this.indexPath, "inverted-index.json"),
8385
- path13.join(this.indexPath, "file-hashes.json"),
8386
- path13.join(this.indexPath, "failed-batches.json")
7921
+ path11.join(this.indexPath, "codebase.db"),
7922
+ path11.join(this.indexPath, "codebase.db-shm"),
7923
+ path11.join(this.indexPath, "codebase.db-wal"),
7924
+ path11.join(this.indexPath, "vectors"),
7925
+ path11.join(this.indexPath, "vectors.usearch"),
7926
+ path11.join(this.indexPath, "vectors.meta.json"),
7927
+ path11.join(this.indexPath, "inverted-index.json"),
7928
+ path11.join(this.indexPath, "file-hashes.json"),
7929
+ path11.join(this.indexPath, "failed-batches.json")
8387
7930
  ];
8388
7931
  await Promise.all(resetPaths.map((targetPath) => fsPromises2.rm(targetPath, { recursive: true, force: true })));
8389
7932
  await fsPromises2.mkdir(this.indexPath, { recursive: true });
@@ -8392,7 +7935,7 @@ var Indexer = class {
8392
7935
  if (!isSqliteCorruptionError(error)) {
8393
7936
  return false;
8394
7937
  }
8395
- const dbPath = path13.join(this.indexPath, "codebase.db");
7938
+ const dbPath = path11.join(this.indexPath, "codebase.db");
8396
7939
  const warning = this.getCorruptedIndexWarning(dbPath);
8397
7940
  const errorMessage = getErrorMessage2(error);
8398
7941
  if (this.config.scope === "global") {
@@ -8458,6 +8001,7 @@ var Indexer = class {
8458
8001
  this.database.setMetadata("index.embeddingProvider", provider.provider);
8459
8002
  this.database.setMetadata("index.embeddingModel", provider.modelInfo.model);
8460
8003
  this.database.setMetadata("index.embeddingDimensions", provider.modelInfo.dimensions.toString());
8004
+ this.database.setMetadata(this.getCallGraphResolutionMetadataKey(), CALL_GRAPH_RESOLUTION_VERSION);
8461
8005
  if (this.config.scope === "global") {
8462
8006
  if (completeProjectEmbeddingStrategyReset) {
8463
8007
  this.database.setMetadata(this.getProjectEmbeddingStrategyMetadataKey(), EMBEDDING_STRATEGY_VERSION);
@@ -8645,6 +8189,20 @@ var Indexer = class {
8645
8189
  totalChunks: 0
8646
8190
  });
8647
8191
  this.loadFileHashCache();
8192
+ const swiftParserMetadataKey = this.getSwiftParserVersionMetadataKey();
8193
+ const reparseCachedSwiftFiles = database.getMetadata(swiftParserMetadataKey) !== SWIFT_PARSER_VERSION;
8194
+ const metalParserMetadataKey = this.getMetalParserVersionMetadataKey();
8195
+ const reparseCachedMetalFiles = database.getMetadata(metalParserMetadataKey) !== METAL_PARSER_VERSION;
8196
+ if (reparseCachedSwiftFiles && Array.from(this.fileHashCache.keys()).some(
8197
+ (filePath) => path11.extname(filePath).toLowerCase() === ".swift"
8198
+ )) {
8199
+ this.logger.info("Reindexing cached Swift files for parser support");
8200
+ }
8201
+ if (reparseCachedMetalFiles && Array.from(this.fileHashCache.keys()).some(
8202
+ (filePath) => path11.extname(filePath).toLowerCase() === ".metal"
8203
+ )) {
8204
+ this.logger.info("Reindexing cached Metal files for parser support");
8205
+ }
8648
8206
  const includePatterns = [...this.config.include, ...this.config.additionalInclude];
8649
8207
  const { files, skipped } = await collectFiles(
8650
8208
  this.projectRoot,
@@ -8664,10 +8222,17 @@ var Indexer = class {
8664
8222
  const changedFiles = [];
8665
8223
  const unchangedFilePaths = /* @__PURE__ */ new Set();
8666
8224
  const currentFileHashes = /* @__PURE__ */ new Map();
8225
+ const needsCallGraphResolutionMigration = database.getMetadata(this.getCallGraphResolutionMetadataKey()) !== CALL_GRAPH_RESOLUTION_VERSION;
8667
8226
  for (const f of files) {
8668
8227
  const currentHash = hashFile(f.path);
8669
8228
  currentFileHashes.set(f.path, currentHash);
8670
- if (this.fileHashCache.get(f.path) === currentHash) {
8229
+ const cachedHashMatches = this.fileHashCache.get(f.path) === currentHash;
8230
+ const needsCallGraphRefresh = cachedHashMatches && needsCallGraphResolutionMigration && database.getChunksByFile(f.path).some(
8231
+ (chunk) => chunk.language === "php" || chunk.language === "c" || chunk.language === "cpp"
8232
+ );
8233
+ const requiresSwiftParserUpgrade = reparseCachedSwiftFiles && path11.extname(f.path).toLowerCase() === ".swift";
8234
+ const requiresMetalParserUpgrade = reparseCachedMetalFiles && path11.extname(f.path).toLowerCase() === ".metal";
8235
+ if (cachedHashMatches && !needsCallGraphRefresh && !requiresSwiftParserUpgrade && !requiresMetalParserUpgrade) {
8671
8236
  unchangedFilePaths.add(f.path);
8672
8237
  this.logger.recordCacheHit();
8673
8238
  } else {
@@ -8769,7 +8334,7 @@ var Indexer = class {
8769
8334
  for (const parsed of parsedFiles) {
8770
8335
  currentFilePaths.add(parsed.path);
8771
8336
  if (parsed.chunks.length === 0) {
8772
- const relativePath = path13.relative(this.projectRoot, parsed.path);
8337
+ const relativePath = path11.relative(this.projectRoot, parsed.path);
8773
8338
  stats.parseFailures.push(relativePath);
8774
8339
  }
8775
8340
  let chunksToProcess = parsed.chunks;
@@ -8869,16 +8434,28 @@ var Indexer = class {
8869
8434
  const fileSymbols = [];
8870
8435
  for (const chunk of parsed.chunks) {
8871
8436
  if (!chunk.name || !CALL_GRAPH_SYMBOL_CHUNK_TYPES.has(chunk.chunkType)) continue;
8872
- const symbolId = `sym_${hashContent(parsed.path + ":" + chunk.name + ":" + chunk.chunkType + ":" + chunk.startLine).slice(0, 16)}`;
8437
+ const existingMetalSymbol = chunk.language === "metal" ? fileSymbols.find(
8438
+ (symbol2) => symbol2.name === chunk.name && symbol2.kind === chunk.chunkType && symbol2.startLine <= chunk.endLine && chunk.startLine <= symbol2.endLine
8439
+ ) : void 0;
8440
+ if (existingMetalSymbol) {
8441
+ existingMetalSymbol.startLine = Math.min(existingMetalSymbol.startLine, chunk.startLine);
8442
+ existingMetalSymbol.endLine = Math.max(existingMetalSymbol.endLine, chunk.endLine);
8443
+ existingMetalSymbol.startCol = Math.min(existingMetalSymbol.startCol, chunk.startCol ?? 0);
8444
+ existingMetalSymbol.endCol = Math.max(existingMetalSymbol.endCol, chunk.endCol ?? 0);
8445
+ continue;
8446
+ }
8447
+ const symbolId = `sym_${hashContent(
8448
+ parsed.path + ":" + chunk.name + ":" + chunk.chunkType + ":" + chunk.startLine + ":" + (chunk.startCol ?? 0)
8449
+ ).slice(0, 16)}`;
8873
8450
  const symbol = {
8874
8451
  id: symbolId,
8875
8452
  filePath: parsed.path,
8876
8453
  name: chunk.name,
8877
8454
  kind: chunk.chunkType,
8878
8455
  startLine: chunk.startLine,
8879
- startCol: 0,
8456
+ startCol: chunk.startCol ?? 0,
8880
8457
  endLine: chunk.endLine,
8881
- endCol: 0,
8458
+ endCol: chunk.endCol ?? 0,
8882
8459
  language: chunk.language
8883
8460
  };
8884
8461
  fileSymbols.push(symbol);
@@ -8903,8 +8480,10 @@ var Indexer = class {
8903
8480
  if (callSites.length === 0) continue;
8904
8481
  const edges = [];
8905
8482
  for (const site of callSites) {
8906
- const enclosingSymbol = fileSymbols.find(
8907
- (sym) => site.line >= sym.startLine && site.line <= sym.endLine
8483
+ const enclosingSymbol = findEnclosingSymbol(
8484
+ fileSymbols,
8485
+ site.line,
8486
+ site.column
8908
8487
  );
8909
8488
  if (!enclosingSymbol) continue;
8910
8489
  const edgeId = `edge_${hashContent(enclosingSymbol.id + ":" + site.calleeName + ":" + site.line + ":" + site.column).slice(0, 16)}`;
@@ -8923,7 +8502,21 @@ var Indexer = class {
8923
8502
  if (edges.length > 0) {
8924
8503
  database.upsertCallEdgesBatch(edges);
8925
8504
  for (const edge of edges) {
8926
- const candidates = symbolsByName.get(normalizeSymbolKey(edge.targetName));
8505
+ let candidates = symbolsByName.get(normalizeSymbolKey(edge.targetName));
8506
+ if (fileLanguage === "php" && candidates) {
8507
+ if (edge.callType === "Constructor") {
8508
+ candidates = candidates.filter(
8509
+ (candidate) => PHP_CLASS_SYMBOL_CHUNK_TYPES.has(candidate.kind)
8510
+ );
8511
+ } else if (edge.callType === "Call") {
8512
+ candidates = candidates.filter(
8513
+ (candidate) => PHP_FUNCTION_SYMBOL_CHUNK_TYPES.has(candidate.kind)
8514
+ );
8515
+ }
8516
+ }
8517
+ candidates = candidates?.filter(
8518
+ (symbol) => isCompatibleCFamilyCallTarget(fileLanguage, edge.callType, symbol.kind)
8519
+ );
8927
8520
  if (candidates && candidates.length === 1) {
8928
8521
  database.resolveCallEdge(edge.id, candidates[0].id);
8929
8522
  }
@@ -8965,8 +8558,8 @@ var Indexer = class {
8965
8558
  database.addChunksToBranchBatch(branchCatalogKey, Array.from(currentChunkIds));
8966
8559
  database.clearBranchSymbols(branchCatalogKey);
8967
8560
  database.addSymbolsToBranchBatch(branchCatalogKey, Array.from(allSymbolIds));
8968
- const vectorPath = path13.join(this.indexPath, "vectors");
8969
- const shouldFingerprintLegacyPair = !store.hasFingerprint() && existsSync8(vectorPath) && existsSync8(`${vectorPath}.meta.json`);
8561
+ const vectorPath = path11.join(this.indexPath, "vectors");
8562
+ const shouldFingerprintLegacyPair = !store.hasFingerprint() && existsSync7(vectorPath) && existsSync7(`${vectorPath}.meta.json`);
8970
8563
  if (backfilledBlameMetadata || shouldFingerprintLegacyPair) {
8971
8564
  store.save();
8972
8565
  }
@@ -8978,6 +8571,8 @@ var Indexer = class {
8978
8571
  this.saveFileHashCache();
8979
8572
  this.saveFailedBatches([]);
8980
8573
  }
8574
+ database.setMetadata(swiftParserMetadataKey, SWIFT_PARSER_VERSION);
8575
+ database.setMetadata(metalParserMetadataKey, METAL_PARSER_VERSION);
8981
8576
  this.saveIndexMetadata(configuredProviderInfo);
8982
8577
  this.indexCompatibility = { compatible: true };
8983
8578
  stats.durationMs = Date.now() - startTime;
@@ -9005,6 +8600,8 @@ var Indexer = class {
9005
8600
  this.saveFileHashCache();
9006
8601
  this.saveFailedBatches([]);
9007
8602
  }
8603
+ database.setMetadata(swiftParserMetadataKey, SWIFT_PARSER_VERSION);
8604
+ database.setMetadata(metalParserMetadataKey, METAL_PARSER_VERSION);
9008
8605
  this.saveIndexMetadata(configuredProviderInfo);
9009
8606
  this.indexCompatibility = { compatible: true };
9010
8607
  stats.durationMs = Date.now() - startTime;
@@ -9275,6 +8872,8 @@ var Indexer = class {
9275
8872
  if (forceScopedReembed && failedForcedChunkIds.size === 0) {
9276
8873
  database.deleteMetadata(this.getProjectForceReembedMetadataKey());
9277
8874
  }
8875
+ database.setMetadata(swiftParserMetadataKey, SWIFT_PARSER_VERSION);
8876
+ database.setMetadata(metalParserMetadataKey, METAL_PARSER_VERSION);
9278
8877
  this.saveIndexMetadata(configuredProviderInfo);
9279
8878
  this.indexCompatibility = { compatible: true };
9280
8879
  this.logger.recordIndexingEnd();
@@ -9708,7 +9307,7 @@ var Indexer = class {
9708
9307
  const removedChunkKeys = [];
9709
9308
  const chunkKeysByRemovedFile = /* @__PURE__ */ new Map();
9710
9309
  for (const [filePath, chunkKeys] of filePathsToChunkKeys) {
9711
- if (!existsSync8(filePath)) {
9310
+ if (!existsSync7(filePath)) {
9712
9311
  chunkKeysByRemovedFile.set(filePath, chunkKeys);
9713
9312
  for (const key of chunkKeys) {
9714
9313
  removedChunkKeys.push(key);
@@ -9757,7 +9356,7 @@ var Indexer = class {
9757
9356
  gcOrphanSymbols: 0,
9758
9357
  gcOrphanCallEdges: 0,
9759
9358
  resetCorruptedIndex: true,
9760
- warning: this.getCorruptedIndexWarning(path13.join(this.indexPath, "codebase.db"))
9359
+ warning: this.getCorruptedIndexWarning(path11.join(this.indexPath, "codebase.db"))
9761
9360
  };
9762
9361
  }
9763
9362
  this.logger.recordGc(removedCount, gcOrphanChunks, gcOrphanEmbeddings);
@@ -10187,7 +9786,7 @@ var Indexer = class {
10187
9786
  "Run index_codebase first to build the call graph and symbol index for this branch."
10188
9787
  );
10189
9788
  }
10190
- const absoluteChangedFiles = changedFiles.map((f) => path13.resolve(this.projectRoot, f));
9789
+ const absoluteChangedFiles = changedFiles.map((f) => path11.resolve(this.projectRoot, f));
10191
9790
  const directSymbols = database.getSymbolsForFiles(absoluteChangedFiles, branchKey);
10192
9791
  const directIds = directSymbols.map((s) => s.id);
10193
9792
  const direction = opts.direction ?? "both";
@@ -10270,7 +9869,7 @@ var Indexer = class {
10270
9869
  projectRoot: this.projectRoot,
10271
9870
  baseBranch: this.baseBranch
10272
9871
  });
10273
- const otherAbsolute = otherChanged.files.map((f) => path13.resolve(this.projectRoot, f));
9872
+ const otherAbsolute = otherChanged.files.map((f) => path11.resolve(this.projectRoot, f));
10274
9873
  const otherBranchKey = this.getBranchCatalogKeyFor(openPr.headRefName);
10275
9874
  const otherSymbols = database.getSymbolsForFiles(otherAbsolute, otherBranchKey);
10276
9875
  const otherLabels = /* @__PURE__ */ new Set();
@@ -10334,12 +9933,12 @@ var Indexer = class {
10334
9933
  if (meta.filePath) filePaths.add(meta.filePath);
10335
9934
  }
10336
9935
  const directory = options?.directory?.replace(/\/$/, "");
10337
- const absoluteDirectoryFilter = directory ? path13.resolve(this.projectRoot, directory) : void 0;
9936
+ const absoluteDirectoryFilter = directory ? path11.resolve(this.projectRoot, directory) : void 0;
10338
9937
  for (const filePath of filePaths) {
10339
9938
  if (directory) {
10340
- const absoluteFilePath = path13.resolve(filePath);
9939
+ const absoluteFilePath = path11.resolve(filePath);
10341
9940
  const matchesRelative = filePath === directory || filePath.startsWith(directory + "/");
10342
- const matchesProjectRelative = absoluteDirectoryFilter !== void 0 && (absoluteFilePath === absoluteDirectoryFilter || absoluteFilePath.startsWith(absoluteDirectoryFilter + path13.sep));
9941
+ const matchesProjectRelative = absoluteDirectoryFilter !== void 0 && (absoluteFilePath === absoluteDirectoryFilter || absoluteFilePath.startsWith(absoluteDirectoryFilter + path11.sep));
10343
9942
  if (!matchesRelative && !matchesProjectRelative) {
10344
9943
  continue;
10345
9944
  }
@@ -10382,52 +9981,52 @@ var Indexer = class {
10382
9981
  };
10383
9982
 
10384
9983
  // src/tools/knowledge-base-paths.ts
10385
- import * as path14 from "path";
9984
+ import * as path12 from "path";
10386
9985
  function resolveConfigPathValue(value, baseDir) {
10387
9986
  const trimmed = value.trim();
10388
9987
  if (!trimmed) {
10389
9988
  return trimmed;
10390
9989
  }
10391
- const absolutePath = path14.isAbsolute(trimmed) ? trimmed : path14.resolve(baseDir, trimmed);
10392
- return path14.normalize(absolutePath);
9990
+ const absolutePath = path12.isAbsolute(trimmed) ? trimmed : path12.resolve(baseDir, trimmed);
9991
+ return path12.normalize(absolutePath);
10393
9992
  }
10394
9993
  function serializeConfigPathValue(value, baseDir) {
10395
9994
  const trimmed = value.trim();
10396
9995
  if (!trimmed) {
10397
9996
  return trimmed;
10398
9997
  }
10399
- if (!path14.isAbsolute(trimmed)) {
10400
- return normalizePathSeparators(path14.normalize(trimmed));
9998
+ if (!path12.isAbsolute(trimmed)) {
9999
+ return normalizePathSeparators(path12.normalize(trimmed));
10401
10000
  }
10402
- const relativePath = path14.relative(baseDir, trimmed);
10403
- if (!relativePath || !relativePath.startsWith("..") && !path14.isAbsolute(relativePath)) {
10404
- return normalizePathSeparators(path14.normalize(relativePath || "."));
10001
+ const relativePath = path12.relative(baseDir, trimmed);
10002
+ if (!relativePath || !relativePath.startsWith("..") && !path12.isAbsolute(relativePath)) {
10003
+ return normalizePathSeparators(path12.normalize(relativePath || "."));
10405
10004
  }
10406
- return path14.normalize(trimmed);
10005
+ return path12.normalize(trimmed);
10407
10006
  }
10408
10007
  function resolveKnowledgeBasePath(value, projectRoot3) {
10409
- return path14.isAbsolute(value) ? value : path14.resolve(projectRoot3, value);
10008
+ return path12.isAbsolute(value) ? value : path12.resolve(projectRoot3, value);
10410
10009
  }
10411
- function normalizeKnowledgeBasePath2(value, projectRoot3) {
10412
- return path14.normalize(resolveKnowledgeBasePath(value, projectRoot3));
10010
+ function normalizeKnowledgeBasePath(value, projectRoot3) {
10011
+ return path12.normalize(resolveKnowledgeBasePath(value, projectRoot3));
10413
10012
  }
10414
10013
  function hasMatchingKnowledgeBasePath(knowledgeBases, inputPath, projectRoot3) {
10415
- const normalizedInput = path14.normalize(inputPath);
10416
- return knowledgeBases.some((kb) => normalizeKnowledgeBasePath2(kb, projectRoot3) === normalizedInput);
10014
+ const normalizedInput = path12.normalize(inputPath);
10015
+ return knowledgeBases.some((kb) => normalizeKnowledgeBasePath(kb, projectRoot3) === normalizedInput);
10417
10016
  }
10418
10017
  function findKnowledgeBasePathIndex(knowledgeBases, inputPath, projectRoot3) {
10419
- const normalizedInput = path14.normalize(inputPath);
10018
+ const normalizedInput = path12.normalize(inputPath);
10420
10019
  return knowledgeBases.findIndex(
10421
- (kb) => path14.normalize(kb) === normalizedInput || normalizeKnowledgeBasePath2(kb, projectRoot3) === normalizedInput
10020
+ (kb) => path12.normalize(kb) === normalizedInput || normalizeKnowledgeBasePath(kb, projectRoot3) === normalizedInput
10422
10021
  );
10423
10022
  }
10424
10023
 
10425
10024
  // src/tools/utils.ts
10426
- var import_tiktoken = __toESM(require_tiktoken(), 1);
10025
+ import { get_encoding } from "tiktoken";
10427
10026
  var MIN_CONTEXT_PACK_TOKEN_BUDGET = 128;
10428
10027
  var MAX_CONTEXT_PACK_TOKEN_BUDGET = 4e3;
10429
10028
  var DEFAULT_CONTEXT_PACK_TOKEN_BUDGET = 1200;
10430
- var CONTEXT_TOKENIZER = (0, import_tiktoken.get_encoding)("cl100k_base");
10029
+ var CONTEXT_TOKENIZER = get_encoding("cl100k_base");
10431
10030
  function clampContextPackTokenBudget(tokenBudget) {
10432
10031
  if (tokenBudget === void 0 || !Number.isFinite(tokenBudget)) {
10433
10032
  return DEFAULT_CONTEXT_PACK_TOKEN_BUDGET;
@@ -10818,8 +10417,195 @@ ${truncateContent(r.content)}
10818
10417
  }
10819
10418
 
10820
10419
  // src/tools/config-state.ts
10821
- import { existsSync as existsSync9, mkdirSync as mkdirSync4, writeFileSync as writeFileSync4 } from "fs";
10420
+ import { existsSync as existsSync9, mkdirSync as mkdirSync3, writeFileSync as writeFileSync3 } from "fs";
10822
10421
  import * as path15 from "path";
10422
+
10423
+ // src/config/merger.ts
10424
+ import { existsSync as existsSync8, readFileSync as readFileSync7 } from "fs";
10425
+ import * as path14 from "path";
10426
+
10427
+ // src/config/rebase.ts
10428
+ import * as path13 from "path";
10429
+ function isWithinRoot(rootDir, targetPath) {
10430
+ const relativePath = path13.relative(rootDir, targetPath);
10431
+ return relativePath === "" || !relativePath.startsWith("..") && !path13.isAbsolute(relativePath);
10432
+ }
10433
+ function resolveInheritedKnowledgeBaseEntries(values, sourceRoot, targetRoot) {
10434
+ if (!Array.isArray(values)) {
10435
+ return [];
10436
+ }
10437
+ return values.filter((value) => typeof value === "string").map((value) => {
10438
+ const trimmed = value.trim();
10439
+ if (!trimmed) {
10440
+ return trimmed;
10441
+ }
10442
+ if (path13.isAbsolute(trimmed)) {
10443
+ if (isWithinRoot(sourceRoot, trimmed)) {
10444
+ return normalizePathSeparators(path13.normalize(path13.relative(sourceRoot, trimmed) || "."));
10445
+ }
10446
+ return path13.normalize(trimmed);
10447
+ }
10448
+ const resolvedFromSource = path13.resolve(sourceRoot, trimmed);
10449
+ if (isWithinRoot(sourceRoot, resolvedFromSource)) {
10450
+ return normalizePathSeparators(path13.normalize(trimmed));
10451
+ }
10452
+ return normalizePathSeparators(path13.normalize(path13.relative(targetRoot, resolvedFromSource)));
10453
+ }).filter(Boolean);
10454
+ }
10455
+
10456
+ // src/config/merger.ts
10457
+ var PROJECT_OVERRIDE_KEYS = [
10458
+ "embeddingProvider",
10459
+ "customProvider",
10460
+ "embeddingModel",
10461
+ "reranker",
10462
+ "include",
10463
+ "exclude",
10464
+ "indexing",
10465
+ "search",
10466
+ "debug",
10467
+ "scope"
10468
+ ];
10469
+ var MERGE_ARRAY_KEYS = ["knowledgeBases", "additionalInclude"];
10470
+ function isRecord(value) {
10471
+ return typeof value === "object" && value !== null && !Array.isArray(value);
10472
+ }
10473
+ function isStringArray2(value) {
10474
+ return Array.isArray(value) && value.every((item) => typeof item === "string");
10475
+ }
10476
+ function applyProjectOverride(merged, normalizedProjectConfig, globalConfig, key) {
10477
+ if (key in normalizedProjectConfig) {
10478
+ merged[key] = normalizedProjectConfig[key];
10479
+ return;
10480
+ }
10481
+ if (key in globalConfig) {
10482
+ merged[key] = globalConfig[key];
10483
+ }
10484
+ }
10485
+ function mergeUniqueStringArray(values) {
10486
+ return [...new Set(values.map((value) => String(value).trim()))];
10487
+ }
10488
+ function normalizeKnowledgeBasePath2(value) {
10489
+ let normalized = path14.normalize(String(value).trim());
10490
+ const root = path14.parse(normalized).root;
10491
+ while (normalized.length > root.length && /[\\/]$/.test(normalized)) {
10492
+ normalized = normalized.slice(0, -1);
10493
+ }
10494
+ return normalized;
10495
+ }
10496
+ function mergeKnowledgeBasePaths(values) {
10497
+ return [...new Set(values.map((value) => normalizeKnowledgeBasePath2(value)).filter((value) => value.length > 0))];
10498
+ }
10499
+ function validateConfigLayerShape(rawConfig, filePath) {
10500
+ if (!isRecord(rawConfig)) {
10501
+ throw new Error(`Config file ${filePath} must contain a JSON object at the root.`);
10502
+ }
10503
+ if (rawConfig.knowledgeBases !== void 0 && !isStringArray2(rawConfig.knowledgeBases)) {
10504
+ throw new Error(`Config file ${filePath} field 'knowledgeBases' must be an array of strings.`);
10505
+ }
10506
+ if (rawConfig.additionalInclude !== void 0 && !isStringArray2(rawConfig.additionalInclude)) {
10507
+ throw new Error(`Config file ${filePath} field 'additionalInclude' must be an array of strings.`);
10508
+ }
10509
+ if (rawConfig.include !== void 0 && !isStringArray2(rawConfig.include)) {
10510
+ throw new Error(`Config file ${filePath} field 'include' must be an array of strings.`);
10511
+ }
10512
+ if (rawConfig.exclude !== void 0 && !isStringArray2(rawConfig.exclude)) {
10513
+ throw new Error(`Config file ${filePath} field 'exclude' must be an array of strings.`);
10514
+ }
10515
+ for (const section of ["customProvider", "indexing", "search", "debug", "reranker"]) {
10516
+ const value = rawConfig[section];
10517
+ if (value !== void 0 && !isRecord(value)) {
10518
+ throw new Error(`Config file ${filePath} field '${section}' must be an object.`);
10519
+ }
10520
+ }
10521
+ return rawConfig;
10522
+ }
10523
+ function loadJsonFile(filePath) {
10524
+ if (!existsSync8(filePath)) {
10525
+ return null;
10526
+ }
10527
+ try {
10528
+ const content = readFileSync7(filePath, "utf-8");
10529
+ return validateConfigLayerShape(JSON.parse(content), filePath);
10530
+ } catch (error) {
10531
+ if (error instanceof Error && error.message.startsWith("Config file ")) {
10532
+ throw error;
10533
+ }
10534
+ const message = error instanceof Error ? error.message : String(error);
10535
+ throw new Error(`Failed to load config file ${filePath}: ${message}`);
10536
+ }
10537
+ }
10538
+ function loadProjectConfigLayer(projectRoot3, host = "opencode") {
10539
+ const projectConfigPath = resolveProjectConfigPath(projectRoot3, host);
10540
+ const projectConfig = loadJsonFile(projectConfigPath);
10541
+ if (!projectConfig) {
10542
+ return {};
10543
+ }
10544
+ const normalizedConfig = { ...projectConfig };
10545
+ const projectConfigBaseDir = path14.dirname(path14.dirname(projectConfigPath));
10546
+ if (Array.isArray(normalizedConfig.knowledgeBases)) {
10547
+ normalizedConfig.knowledgeBases = resolveInheritedKnowledgeBaseEntries(
10548
+ normalizedConfig.knowledgeBases,
10549
+ projectConfigBaseDir,
10550
+ projectRoot3
10551
+ );
10552
+ }
10553
+ return normalizedConfig;
10554
+ }
10555
+ function loadMergedConfig(projectRoot3, host = "opencode") {
10556
+ const globalConfigPath = resolveGlobalConfigPath(host);
10557
+ const projectConfigPath = resolveProjectConfigPath(projectRoot3, host);
10558
+ let globalConfig = null;
10559
+ let globalConfigError = null;
10560
+ try {
10561
+ globalConfig = loadJsonFile(globalConfigPath);
10562
+ } catch (error) {
10563
+ globalConfigError = error instanceof Error ? error : new Error(String(error));
10564
+ }
10565
+ const projectConfig = loadJsonFile(projectConfigPath);
10566
+ const normalizedProjectConfig = loadProjectConfigLayer(projectRoot3, host);
10567
+ if (globalConfigError) {
10568
+ if (!projectConfig) {
10569
+ throw globalConfigError;
10570
+ }
10571
+ globalConfig = null;
10572
+ }
10573
+ if (!globalConfig && !projectConfig) {
10574
+ return {};
10575
+ }
10576
+ if (!projectConfig && globalConfig) {
10577
+ return globalConfig;
10578
+ }
10579
+ if (!globalConfig && projectConfig) {
10580
+ return normalizedProjectConfig;
10581
+ }
10582
+ if (!globalConfig || !projectConfig) {
10583
+ return globalConfig ?? normalizedProjectConfig;
10584
+ }
10585
+ const merged = { ...globalConfig };
10586
+ for (const key of PROJECT_OVERRIDE_KEYS) {
10587
+ applyProjectOverride(merged, normalizedProjectConfig, globalConfig, key);
10588
+ }
10589
+ if (projectConfig) {
10590
+ for (const key of Object.keys(projectConfig)) {
10591
+ if (PROJECT_OVERRIDE_KEYS.includes(key) || MERGE_ARRAY_KEYS.includes(key)) {
10592
+ continue;
10593
+ }
10594
+ merged[key] = normalizedProjectConfig[key];
10595
+ }
10596
+ }
10597
+ const globalKbs = globalConfig && Array.isArray(globalConfig.knowledgeBases) ? globalConfig.knowledgeBases : [];
10598
+ const projectKbs = projectConfig ? Array.isArray(normalizedProjectConfig.knowledgeBases) ? normalizedProjectConfig.knowledgeBases : [] : [];
10599
+ const allKbs = [...globalKbs, ...projectKbs];
10600
+ merged.knowledgeBases = mergeKnowledgeBasePaths(allKbs);
10601
+ const globalAdditional = globalConfig && Array.isArray(globalConfig.additionalInclude) ? globalConfig.additionalInclude : [];
10602
+ const projectAdditional = projectConfig && Array.isArray(projectConfig.additionalInclude) ? projectConfig.additionalInclude : [];
10603
+ const allAdditional = [...globalAdditional, ...projectAdditional];
10604
+ merged.additionalInclude = mergeUniqueStringArray(allAdditional);
10605
+ return merged;
10606
+ }
10607
+
10608
+ // src/tools/config-state.ts
10823
10609
  function normalizeKnowledgeBasePaths(config, projectRoot3) {
10824
10610
  const normalized = { ...config };
10825
10611
  if (Array.isArray(normalized.knowledgeBases)) {
@@ -10849,7 +10635,7 @@ function saveConfig(projectRoot3, config, host = "opencode") {
10849
10635
  const configDir = path15.dirname(configPath);
10850
10636
  const configBaseDir = path15.dirname(configDir);
10851
10637
  if (!existsSync9(configDir)) {
10852
- mkdirSync4(configDir, { recursive: true });
10638
+ mkdirSync3(configDir, { recursive: true });
10853
10639
  }
10854
10640
  const serializableConfig = { ...config };
10855
10641
  if (Array.isArray(serializableConfig.knowledgeBases)) {
@@ -10857,7 +10643,7 @@ function saveConfig(projectRoot3, config, host = "opencode") {
10857
10643
  (kb) => serializeConfigPathValue(kb, configBaseDir)
10858
10644
  );
10859
10645
  }
10860
- writeFileSync4(configPath, JSON.stringify(serializableConfig, null, 2) + "\n", "utf-8");
10646
+ writeFileSync3(configPath, JSON.stringify(serializableConfig, null, 2) + "\n", "utf-8");
10861
10647
  }
10862
10648
 
10863
10649
  // src/tools/operations.ts
@@ -10917,15 +10703,6 @@ function refreshIndexerForDirectory(projectRoot3, host = "opencode", config = pa
10917
10703
  indexerCache.set(key, indexer);
10918
10704
  configCache.set(key, config);
10919
10705
  }
10920
- function shouldForceLocalizeProjectIndex(projectRoot3, host = "opencode") {
10921
- const root = getProjectRoot(projectRoot3, host);
10922
- const localIndexPath = path16.join(root, getHostProjectIndexRelativePath(host));
10923
- if (existsSync10(localIndexPath)) {
10924
- return false;
10925
- }
10926
- const inheritedIndexPath = resolveWorktreeFallbackProjectIndexPath(root, host);
10927
- return inheritedIndexPath !== null;
10928
- }
10929
10706
  async function searchCodebase(projectRoot3, host, query, options = {}) {
10930
10707
  const indexer = getIndexerForProject(projectRoot3, host);
10931
10708
  return indexer.search(query, options.limit, {
@@ -10975,9 +10752,7 @@ async function getCallGraphPath(projectRoot3, host, from, to, maxDepth) {
10975
10752
  }
10976
10753
  async function runIndexCodebase(projectRoot3, host, args, onProgress) {
10977
10754
  const root = getProjectRoot(projectRoot3, host);
10978
- const key = getIndexerCacheKey(root, host);
10979
- let indexer = getIndexerForProject(root, host);
10980
- const runtimeConfig = configCache.get(key);
10755
+ const indexer = getIndexerForProject(root, host);
10981
10756
  try {
10982
10757
  if (args.estimateOnly) {
10983
10758
  return { kind: "estimate", estimate: await indexer.estimateCost() };
@@ -10998,19 +10773,7 @@ async function runIndexCodebase(projectRoot3, host, args, onProgress) {
10998
10773
  return Promise.resolve();
10999
10774
  });
11000
10775
  };
11001
- let stats;
11002
- if (args.force && shouldForceLocalizeProjectIndex(root, host)) {
11003
- const inheritedIndexPath = resolveProjectIndexPath(root, runtimeConfig.scope, host);
11004
- stats = await withIndexLock(inheritedIndexPath, "force-index", async () => {
11005
- materializeLocalProjectConfig(root, loadProjectConfigLayer(root, host), host);
11006
- refreshIndexerForDirectory(root, host, runtimeConfig);
11007
- indexer = getIndexerForProject(root, host);
11008
- return runIndex(indexer);
11009
- }, { completeRecoveries: false });
11010
- } else {
11011
- stats = await runIndex(indexer);
11012
- }
11013
- return { kind: "stats", stats };
10776
+ return { kind: "stats", stats: await runIndex(indexer) };
11014
10777
  } catch (error) {
11015
10778
  const busyResult = getIndexBusyResult(error);
11016
10779
  if (!busyResult) throw error;