cgraphx 2.0.2 → 2.0.3

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.
Files changed (680) hide show
  1. package/dist/core/code/engine/cli/analyze-config.js +320 -0
  2. package/dist/core/code/engine/cli/analyze.js +1086 -0
  3. package/dist/core/code/engine/cli/cli-message.js +83 -0
  4. package/dist/core/code/engine/cli/detect-changes-format.js +58 -0
  5. package/dist/core/code/engine/cli/embedding-dims.js +43 -0
  6. package/dist/core/code/engine/cli/format-elapsed.js +12 -0
  7. package/dist/core/code/engine/cli/help-i18n.js +144 -0
  8. package/dist/core/code/engine/cli/i18n/en.js +110 -0
  9. package/dist/core/code/engine/cli/i18n/index.js +47 -0
  10. package/dist/core/code/engine/cli/i18n/resources.js +9 -0
  11. package/dist/core/code/engine/cli/i18n/zh-CN.js +110 -0
  12. package/dist/core/code/engine/cli/lazy-action.js +67 -0
  13. package/dist/core/code/engine/cli/optional-grammars.js +136 -0
  14. package/dist/core/code/engine/cli/resolve-invocation.js +76 -0
  15. package/dist/core/code/engine/cli/status.js +156 -0
  16. package/dist/core/code/engine/cli/tool.js +384 -0
  17. package/dist/core/code/engine/config/ignore-service.js +511 -0
  18. package/dist/core/code/engine/config/supported-languages.js +17 -0
  19. package/dist/core/code/engine/core/analysis-features.js +64 -0
  20. package/dist/core/code/engine/core/analyzer-identity.js +2171 -0
  21. package/dist/core/code/engine/core/git-staleness.js +180 -0
  22. package/dist/core/code/engine/core/graph/graph.js +180 -0
  23. package/dist/core/code/engine/core/graph/import-cycles.js +106 -0
  24. package/dist/core/code/engine/core/graph/types.js +2 -0
  25. package/dist/core/code/engine/core/index-freshness.js +12 -0
  26. package/dist/core/code/engine/core/ingestion/binding-accumulator.js +341 -0
  27. package/dist/core/code/engine/core/ingestion/call-extractors/configs/c-cpp.js +168 -0
  28. package/dist/core/code/engine/core/ingestion/call-extractors/configs/csharp.js +9 -0
  29. package/dist/core/code/engine/core/ingestion/call-extractors/configs/dart.js +8 -0
  30. package/dist/core/code/engine/core/ingestion/call-extractors/configs/go.js +8 -0
  31. package/dist/core/code/engine/core/ingestion/call-extractors/configs/jvm.js +54 -0
  32. package/dist/core/code/engine/core/ingestion/call-extractors/configs/php.js +8 -0
  33. package/dist/core/code/engine/core/ingestion/call-extractors/configs/python.js +8 -0
  34. package/dist/core/code/engine/core/ingestion/call-extractors/configs/ruby.js +8 -0
  35. package/dist/core/code/engine/core/ingestion/call-extractors/configs/rust.js +8 -0
  36. package/dist/core/code/engine/core/ingestion/call-extractors/configs/swift.js +8 -0
  37. package/dist/core/code/engine/core/ingestion/call-extractors/configs/typescript-javascript.js +11 -0
  38. package/dist/core/code/engine/core/ingestion/call-extractors/generic.js +62 -0
  39. package/dist/core/code/engine/core/ingestion/call-processor.js +503 -0
  40. package/dist/core/code/engine/core/ingestion/call-routing.js +98 -0
  41. package/dist/core/code/engine/core/ingestion/call-types.js +3 -0
  42. package/dist/core/code/engine/core/ingestion/cfg/callee-cell-format.js +45 -0
  43. package/dist/core/code/engine/core/ingestion/cfg/cfg-builder.js +202 -0
  44. package/dist/core/code/engine/core/ingestion/cfg/collect.js +81 -0
  45. package/dist/core/code/engine/core/ingestion/cfg/control-dependence.js +185 -0
  46. package/dist/core/code/engine/core/ingestion/cfg/control-flow-context.js +130 -0
  47. package/dist/core/code/engine/core/ingestion/cfg/emit.js +646 -0
  48. package/dist/core/code/engine/core/ingestion/cfg/post-dominators.js +182 -0
  49. package/dist/core/code/engine/core/ingestion/cfg/reaching-def-reason-codec.js +139 -0
  50. package/dist/core/code/engine/core/ingestion/cfg/reaching-defs-graph.js +322 -0
  51. package/dist/core/code/engine/core/ingestion/cfg/reaching-defs.js +792 -0
  52. package/dist/core/code/engine/core/ingestion/cfg/synthetic-escape.js +305 -0
  53. package/dist/core/code/engine/core/ingestion/cfg/traversal-result.js +6 -0
  54. package/dist/core/code/engine/core/ingestion/cfg/types.js +14 -0
  55. package/dist/core/code/engine/core/ingestion/cfg/visitors/c-cpp-harvest.js +545 -0
  56. package/dist/core/code/engine/core/ingestion/cfg/visitors/c-cpp.js +590 -0
  57. package/dist/core/code/engine/core/ingestion/cfg/visitors/call-site-harvest.js +356 -0
  58. package/dist/core/code/engine/core/ingestion/cfg/visitors/csharp-harvest.js +593 -0
  59. package/dist/core/code/engine/core/ingestion/cfg/visitors/csharp.js +871 -0
  60. package/dist/core/code/engine/core/ingestion/cfg/visitors/dart-harvest.js +874 -0
  61. package/dist/core/code/engine/core/ingestion/cfg/visitors/dart.js +840 -0
  62. package/dist/core/code/engine/core/ingestion/cfg/visitors/go-harvest.js +625 -0
  63. package/dist/core/code/engine/core/ingestion/cfg/visitors/go.js +642 -0
  64. package/dist/core/code/engine/core/ingestion/cfg/visitors/java-harvest.js +517 -0
  65. package/dist/core/code/engine/core/ingestion/cfg/visitors/java.js +816 -0
  66. package/dist/core/code/engine/core/ingestion/cfg/visitors/kotlin-harvest.js +723 -0
  67. package/dist/core/code/engine/core/ingestion/cfg/visitors/kotlin.js +813 -0
  68. package/dist/core/code/engine/core/ingestion/cfg/visitors/php-harvest.js +630 -0
  69. package/dist/core/code/engine/core/ingestion/cfg/visitors/php.js +725 -0
  70. package/dist/core/code/engine/core/ingestion/cfg/visitors/python-harvest.js +776 -0
  71. package/dist/core/code/engine/core/ingestion/cfg/visitors/python.js +562 -0
  72. package/dist/core/code/engine/core/ingestion/cfg/visitors/ruby-harvest.js +591 -0
  73. package/dist/core/code/engine/core/ingestion/cfg/visitors/ruby.js +760 -0
  74. package/dist/core/code/engine/core/ingestion/cfg/visitors/rust-harvest.js +877 -0
  75. package/dist/core/code/engine/core/ingestion/cfg/visitors/rust.js +562 -0
  76. package/dist/core/code/engine/core/ingestion/cfg/visitors/scope-tree-harvest.js +120 -0
  77. package/dist/core/code/engine/core/ingestion/cfg/visitors/swift-harvest.js +683 -0
  78. package/dist/core/code/engine/core/ingestion/cfg/visitors/swift.js +791 -0
  79. package/dist/core/code/engine/core/ingestion/cfg/visitors/typescript-harvest.js +1060 -0
  80. package/dist/core/code/engine/core/ingestion/cfg/visitors/typescript.js +587 -0
  81. package/dist/core/code/engine/core/ingestion/class-extractors/configs/c-cpp.js +77 -0
  82. package/dist/core/code/engine/core/ingestion/class-extractors/configs/csharp.js +24 -0
  83. package/dist/core/code/engine/core/ingestion/class-extractors/configs/dart.js +10 -0
  84. package/dist/core/code/engine/core/ingestion/class-extractors/configs/go.js +28 -0
  85. package/dist/core/code/engine/core/ingestion/class-extractors/configs/jvm.js +67 -0
  86. package/dist/core/code/engine/core/ingestion/class-extractors/configs/php.js +10 -0
  87. package/dist/core/code/engine/core/ingestion/class-extractors/configs/python.js +10 -0
  88. package/dist/core/code/engine/core/ingestion/class-extractors/configs/ruby.js +13 -0
  89. package/dist/core/code/engine/core/ingestion/class-extractors/configs/rust.js +10 -0
  90. package/dist/core/code/engine/core/ingestion/class-extractors/configs/swift.js +21 -0
  91. package/dist/core/code/engine/core/ingestion/class-extractors/configs/typescript-javascript.js +31 -0
  92. package/dist/core/code/engine/core/ingestion/class-extractors/generic.js +144 -0
  93. package/dist/core/code/engine/core/ingestion/class-types.js +2 -0
  94. package/dist/core/code/engine/core/ingestion/cluster-enricher.js +174 -0
  95. package/dist/core/code/engine/core/ingestion/community-processor.js +604 -0
  96. package/dist/core/code/engine/core/ingestion/constants.js +26 -0
  97. package/dist/core/code/engine/core/ingestion/cpp-ue-preprocessor.js +263 -0
  98. package/dist/core/code/engine/core/ingestion/csharp-namespace-gate.js +133 -0
  99. package/dist/core/code/engine/core/ingestion/di-extractors/index.js +38 -0
  100. package/dist/core/code/engine/core/ingestion/di-extractors/spring.js +310 -0
  101. package/dist/core/code/engine/core/ingestion/emit-references.js +244 -0
  102. package/dist/core/code/engine/core/ingestion/entry-point-scoring.js +201 -0
  103. package/dist/core/code/engine/core/ingestion/export-detection.js +244 -0
  104. package/dist/core/code/engine/core/ingestion/field-extractor.js +29 -0
  105. package/dist/core/code/engine/core/ingestion/field-extractors/configs/c-cpp.js +107 -0
  106. package/dist/core/code/engine/core/ingestion/field-extractors/configs/csharp.js +124 -0
  107. package/dist/core/code/engine/core/ingestion/field-extractors/configs/dart.js +99 -0
  108. package/dist/core/code/engine/core/ingestion/field-extractors/configs/go.js +102 -0
  109. package/dist/core/code/engine/core/ingestion/field-extractors/configs/helpers.js +198 -0
  110. package/dist/core/code/engine/core/ingestion/field-extractors/configs/jvm.js +172 -0
  111. package/dist/core/code/engine/core/ingestion/field-extractors/configs/php.js +67 -0
  112. package/dist/core/code/engine/core/ingestion/field-extractors/configs/python.js +94 -0
  113. package/dist/core/code/engine/core/ingestion/field-extractors/configs/ruby.js +79 -0
  114. package/dist/core/code/engine/core/ingestion/field-extractors/configs/rust.js +55 -0
  115. package/dist/core/code/engine/core/ingestion/field-extractors/configs/swift.js +93 -0
  116. package/dist/core/code/engine/core/ingestion/field-extractors/configs/typescript-javascript.js +59 -0
  117. package/dist/core/code/engine/core/ingestion/field-extractors/generic.js +147 -0
  118. package/dist/core/code/engine/core/ingestion/field-extractors/typescript.js +266 -0
  119. package/dist/core/code/engine/core/ingestion/field-types.js +3 -0
  120. package/dist/core/code/engine/core/ingestion/filesystem-walker.js +136 -0
  121. package/dist/core/code/engine/core/ingestion/finalize-orchestrator.js +159 -0
  122. package/dist/core/code/engine/core/ingestion/framework-detection.js +432 -0
  123. package/dist/core/code/engine/core/ingestion/frameworks/spring/analysis-features.js +38 -0
  124. package/dist/core/code/engine/core/ingestion/frameworks/spring/annotation-arguments.js +234 -0
  125. package/dist/core/code/engine/core/ingestion/frameworks/spring/aop-candidates.js +88 -0
  126. package/dist/core/code/engine/core/ingestion/frameworks/spring/aop.js +487 -0
  127. package/dist/core/code/engine/core/ingestion/frameworks/spring/auto-configuration.js +21 -0
  128. package/dist/core/code/engine/core/ingestion/frameworks/spring/bean-candidates.js +189 -0
  129. package/dist/core/code/engine/core/ingestion/frameworks/spring/bean-catalog.js +32 -0
  130. package/dist/core/code/engine/core/ingestion/frameworks/spring/bean-factories.js +73 -0
  131. package/dist/core/code/engine/core/ingestion/frameworks/spring/conditionals.js +323 -0
  132. package/dist/core/code/engine/core/ingestion/frameworks/spring/config-bindings.js +119 -0
  133. package/dist/core/code/engine/core/ingestion/frameworks/spring/di-metadata.js +385 -0
  134. package/dist/core/code/engine/core/ingestion/frameworks/spring/resource-injection.js +96 -0
  135. package/dist/core/code/engine/core/ingestion/import-resolvers/configs/c-cpp.js +17 -0
  136. package/dist/core/code/engine/core/ingestion/import-resolvers/configs/csharp.js +46 -0
  137. package/dist/core/code/engine/core/ingestion/import-resolvers/configs/dart.js +59 -0
  138. package/dist/core/code/engine/core/ingestion/import-resolvers/configs/go.js +30 -0
  139. package/dist/core/code/engine/core/ingestion/import-resolvers/configs/jvm.js +73 -0
  140. package/dist/core/code/engine/core/ingestion/import-resolvers/configs/php.js +19 -0
  141. package/dist/core/code/engine/core/ingestion/import-resolvers/configs/python.js +45 -0
  142. package/dist/core/code/engine/core/ingestion/import-resolvers/configs/ruby.js +20 -0
  143. package/dist/core/code/engine/core/ingestion/import-resolvers/configs/rust.js +58 -0
  144. package/dist/core/code/engine/core/ingestion/import-resolvers/configs/swift.js +94 -0
  145. package/dist/core/code/engine/core/ingestion/import-resolvers/configs/typescript-javascript.js +26 -0
  146. package/dist/core/code/engine/core/ingestion/import-resolvers/csharp.js +128 -0
  147. package/dist/core/code/engine/core/ingestion/import-resolvers/go.js +50 -0
  148. package/dist/core/code/engine/core/ingestion/import-resolvers/jvm.js +112 -0
  149. package/dist/core/code/engine/core/ingestion/import-resolvers/php.js +80 -0
  150. package/dist/core/code/engine/core/ingestion/import-resolvers/python.js +75 -0
  151. package/dist/core/code/engine/core/ingestion/import-resolvers/resolver-factory.js +36 -0
  152. package/dist/core/code/engine/core/ingestion/import-resolvers/ruby.js +20 -0
  153. package/dist/core/code/engine/core/ingestion/import-resolvers/rust.js +79 -0
  154. package/dist/core/code/engine/core/ingestion/import-resolvers/standard.js +180 -0
  155. package/dist/core/code/engine/core/ingestion/import-resolvers/types.js +7 -0
  156. package/dist/core/code/engine/core/ingestion/import-resolvers/utils.js +153 -0
  157. package/dist/core/code/engine/core/ingestion/import-target-adapter.js +99 -0
  158. package/dist/core/code/engine/core/ingestion/language-config.js +391 -0
  159. package/dist/core/code/engine/core/ingestion/language-provider.js +25 -0
  160. package/dist/core/code/engine/core/ingestion/languages/c/arity-metadata.js +98 -0
  161. package/dist/core/code/engine/core/ingestion/languages/c/arity.js +21 -0
  162. package/dist/core/code/engine/core/ingestion/languages/c/capture-side-channel.js +69 -0
  163. package/dist/core/code/engine/core/ingestion/languages/c/captures.js +189 -0
  164. package/dist/core/code/engine/core/ingestion/languages/c/header-scan.js +58 -0
  165. package/dist/core/code/engine/core/ingestion/languages/c/import-decomposer.js +68 -0
  166. package/dist/core/code/engine/core/ingestion/languages/c/import-target.js +103 -0
  167. package/dist/core/code/engine/core/ingestion/languages/c/index.js +33 -0
  168. package/dist/core/code/engine/core/ingestion/languages/c/interpret.js +53 -0
  169. package/dist/core/code/engine/core/ingestion/languages/c/merge-bindings.js +26 -0
  170. package/dist/core/code/engine/core/ingestion/languages/c/query.js +210 -0
  171. package/dist/core/code/engine/core/ingestion/languages/c/scope-resolver.js +112 -0
  172. package/dist/core/code/engine/core/ingestion/languages/c/simple-hooks.js +24 -0
  173. package/dist/core/code/engine/core/ingestion/languages/c/static-linkage.js +109 -0
  174. package/dist/core/code/engine/core/ingestion/languages/c-cpp.js +506 -0
  175. package/dist/core/code/engine/core/ingestion/languages/cpp/adl.js +804 -0
  176. package/dist/core/code/engine/core/ingestion/languages/cpp/arity-metadata.js +258 -0
  177. package/dist/core/code/engine/core/ingestion/languages/cpp/arity.js +37 -0
  178. package/dist/core/code/engine/core/ingestion/languages/cpp/capture-side-channel.js +89 -0
  179. package/dist/core/code/engine/core/ingestion/languages/cpp/captures.js +1975 -0
  180. package/dist/core/code/engine/core/ingestion/languages/cpp/constraint-extractor.js +311 -0
  181. package/dist/core/code/engine/core/ingestion/languages/cpp/constraint-filter.js +210 -0
  182. package/dist/core/code/engine/core/ingestion/languages/cpp/conversion-rank.js +163 -0
  183. package/dist/core/code/engine/core/ingestion/languages/cpp/file-local-linkage.js +327 -0
  184. package/dist/core/code/engine/core/ingestion/languages/cpp/header-scan.js +53 -0
  185. package/dist/core/code/engine/core/ingestion/languages/cpp/import-decomposer.js +134 -0
  186. package/dist/core/code/engine/core/ingestion/languages/cpp/import-target.js +16 -0
  187. package/dist/core/code/engine/core/ingestion/languages/cpp/index.js +33 -0
  188. package/dist/core/code/engine/core/ingestion/languages/cpp/inline-namespaces.js +379 -0
  189. package/dist/core/code/engine/core/ingestion/languages/cpp/interpret.js +239 -0
  190. package/dist/core/code/engine/core/ingestion/languages/cpp/member-lookup.js +470 -0
  191. package/dist/core/code/engine/core/ingestion/languages/cpp/merge-bindings.js +32 -0
  192. package/dist/core/code/engine/core/ingestion/languages/cpp/query.js +763 -0
  193. package/dist/core/code/engine/core/ingestion/languages/cpp/range-bindings.js +230 -0
  194. package/dist/core/code/engine/core/ingestion/languages/cpp/scope-resolver.js +354 -0
  195. package/dist/core/code/engine/core/ingestion/languages/cpp/simple-hooks.js +67 -0
  196. package/dist/core/code/engine/core/ingestion/languages/cpp/two-phase-lookup.js +348 -0
  197. package/dist/core/code/engine/core/ingestion/languages/cpp/type-classifier.js +56 -0
  198. package/dist/core/code/engine/core/ingestion/languages/cpp/user-defined-conversions.js +128 -0
  199. package/dist/core/code/engine/core/ingestion/languages/csharp/accessor-unwrap.js +67 -0
  200. package/dist/core/code/engine/core/ingestion/languages/csharp/arity-metadata.js +49 -0
  201. package/dist/core/code/engine/core/ingestion/languages/csharp/arity.js +40 -0
  202. package/dist/core/code/engine/core/ingestion/languages/csharp/cache-stats.js +32 -0
  203. package/dist/core/code/engine/core/ingestion/languages/csharp/captures.js +557 -0
  204. package/dist/core/code/engine/core/ingestion/languages/csharp/import-decomposer.js +96 -0
  205. package/dist/core/code/engine/core/ingestion/languages/csharp/import-target.js +176 -0
  206. package/dist/core/code/engine/core/ingestion/languages/csharp/index.js +95 -0
  207. package/dist/core/code/engine/core/ingestion/languages/csharp/interpret.js +150 -0
  208. package/dist/core/code/engine/core/ingestion/languages/csharp/merge-bindings.js +58 -0
  209. package/dist/core/code/engine/core/ingestion/languages/csharp/namespace-siblings.js +708 -0
  210. package/dist/core/code/engine/core/ingestion/languages/csharp/qualified-type-names.js +62 -0
  211. package/dist/core/code/engine/core/ingestion/languages/csharp/query.js +578 -0
  212. package/dist/core/code/engine/core/ingestion/languages/csharp/receiver-binding.js +142 -0
  213. package/dist/core/code/engine/core/ingestion/languages/csharp/resolution-config.js +18 -0
  214. package/dist/core/code/engine/core/ingestion/languages/csharp/scope-resolver.js +84 -0
  215. package/dist/core/code/engine/core/ingestion/languages/csharp/simple-hooks.js +81 -0
  216. package/dist/core/code/engine/core/ingestion/languages/csharp.js +204 -0
  217. package/dist/core/code/engine/core/ingestion/languages/dart/arity-metadata.js +38 -0
  218. package/dist/core/code/engine/core/ingestion/languages/dart/arity.js +34 -0
  219. package/dist/core/code/engine/core/ingestion/languages/dart/built-ins.js +37 -0
  220. package/dist/core/code/engine/core/ingestion/languages/dart/cache-stats.js +30 -0
  221. package/dist/core/code/engine/core/ingestion/languages/dart/captures.js +1096 -0
  222. package/dist/core/code/engine/core/ingestion/languages/dart/expand-wildcards.js +34 -0
  223. package/dist/core/code/engine/core/ingestion/languages/dart/extension-type-preprocess.js +33 -0
  224. package/dist/core/code/engine/core/ingestion/languages/dart/import-target.js +68 -0
  225. package/dist/core/code/engine/core/ingestion/languages/dart/index.js +45 -0
  226. package/dist/core/code/engine/core/ingestion/languages/dart/interpret.js +101 -0
  227. package/dist/core/code/engine/core/ingestion/languages/dart/merge-bindings.js +42 -0
  228. package/dist/core/code/engine/core/ingestion/languages/dart/query.js +246 -0
  229. package/dist/core/code/engine/core/ingestion/languages/dart/receiver-binding.js +90 -0
  230. package/dist/core/code/engine/core/ingestion/languages/dart/scope-resolver.js +197 -0
  231. package/dist/core/code/engine/core/ingestion/languages/dart/signature-bindings.js +54 -0
  232. package/dist/core/code/engine/core/ingestion/languages/dart/simple-hooks.js +61 -0
  233. package/dist/core/code/engine/core/ingestion/languages/dart.js +138 -0
  234. package/dist/core/code/engine/core/ingestion/languages/go/arity-metadata.js +71 -0
  235. package/dist/core/code/engine/core/ingestion/languages/go/arity.js +17 -0
  236. package/dist/core/code/engine/core/ingestion/languages/go/cache-stats.js +21 -0
  237. package/dist/core/code/engine/core/ingestion/languages/go/captures.js +492 -0
  238. package/dist/core/code/engine/core/ingestion/languages/go/expand-wildcards.js +97 -0
  239. package/dist/core/code/engine/core/ingestion/languages/go/generic-type-parameters.js +146 -0
  240. package/dist/core/code/engine/core/ingestion/languages/go/import-decomposer.js +47 -0
  241. package/dist/core/code/engine/core/ingestion/languages/go/import-target.js +70 -0
  242. package/dist/core/code/engine/core/ingestion/languages/go/index.js +39 -0
  243. package/dist/core/code/engine/core/ingestion/languages/go/interface-impls.js +955 -0
  244. package/dist/core/code/engine/core/ingestion/languages/go/interpret.js +177 -0
  245. package/dist/core/code/engine/core/ingestion/languages/go/merge-bindings.js +21 -0
  246. package/dist/core/code/engine/core/ingestion/languages/go/method-owners.js +131 -0
  247. package/dist/core/code/engine/core/ingestion/languages/go/namespace-mirror.js +56 -0
  248. package/dist/core/code/engine/core/ingestion/languages/go/package-clause.js +79 -0
  249. package/dist/core/code/engine/core/ingestion/languages/go/package-siblings.js +83 -0
  250. package/dist/core/code/engine/core/ingestion/languages/go/query.js +298 -0
  251. package/dist/core/code/engine/core/ingestion/languages/go/range-binding.js +127 -0
  252. package/dist/core/code/engine/core/ingestion/languages/go/receiver-binding.js +24 -0
  253. package/dist/core/code/engine/core/ingestion/languages/go/scope-resolver.js +75 -0
  254. package/dist/core/code/engine/core/ingestion/languages/go/simple-hooks.js +31 -0
  255. package/dist/core/code/engine/core/ingestion/languages/go/type-binding.js +279 -0
  256. package/dist/core/code/engine/core/ingestion/languages/go.js +160 -0
  257. package/dist/core/code/engine/core/ingestion/languages/index.js +66 -0
  258. package/dist/core/code/engine/core/ingestion/languages/java/analysis-features.js +16 -0
  259. package/dist/core/code/engine/core/ingestion/languages/java/arity-metadata.js +43 -0
  260. package/dist/core/code/engine/core/ingestion/languages/java/arity.js +27 -0
  261. package/dist/core/code/engine/core/ingestion/languages/java/cache-stats.js +32 -0
  262. package/dist/core/code/engine/core/ingestion/languages/java/capture-side-channel.js +123 -0
  263. package/dist/core/code/engine/core/ingestion/languages/java/captures.js +791 -0
  264. package/dist/core/code/engine/core/ingestion/languages/java/import-decomposer.js +88 -0
  265. package/dist/core/code/engine/core/ingestion/languages/java/import-target.js +103 -0
  266. package/dist/core/code/engine/core/ingestion/languages/java/index.js +43 -0
  267. package/dist/core/code/engine/core/ingestion/languages/java/interpret.js +146 -0
  268. package/dist/core/code/engine/core/ingestion/languages/java/merge-bindings.js +43 -0
  269. package/dist/core/code/engine/core/ingestion/languages/java/package-facts.js +16 -0
  270. package/dist/core/code/engine/core/ingestion/languages/java/package-siblings.js +11 -0
  271. package/dist/core/code/engine/core/ingestion/languages/java/query.js +319 -0
  272. package/dist/core/code/engine/core/ingestion/languages/java/receiver-binding.js +98 -0
  273. package/dist/core/code/engine/core/ingestion/languages/java/scope-resolver.js +213 -0
  274. package/dist/core/code/engine/core/ingestion/languages/java/simple-hooks.js +39 -0
  275. package/dist/core/code/engine/core/ingestion/languages/java/spring-aop.js +53 -0
  276. package/dist/core/code/engine/core/ingestion/languages/java/spring-bean-metadata.js +11 -0
  277. package/dist/core/code/engine/core/ingestion/languages/java/spring-conditionals.js +52 -0
  278. package/dist/core/code/engine/core/ingestion/languages/java/spring-config-bindings.js +222 -0
  279. package/dist/core/code/engine/core/ingestion/languages/java/spring-di.js +165 -0
  280. package/dist/core/code/engine/core/ingestion/languages/java.js +192 -0
  281. package/dist/core/code/engine/core/ingestion/languages/javascript/arity.js +15 -0
  282. package/dist/core/code/engine/core/ingestion/languages/javascript/captures.js +1122 -0
  283. package/dist/core/code/engine/core/ingestion/languages/javascript/import-target.js +56 -0
  284. package/dist/core/code/engine/core/ingestion/languages/javascript/index.js +109 -0
  285. package/dist/core/code/engine/core/ingestion/languages/javascript/interpret.js +45 -0
  286. package/dist/core/code/engine/core/ingestion/languages/javascript/merge-bindings.js +21 -0
  287. package/dist/core/code/engine/core/ingestion/languages/javascript/query.js +659 -0
  288. package/dist/core/code/engine/core/ingestion/languages/javascript/scope-resolver.js +78 -0
  289. package/dist/core/code/engine/core/ingestion/languages/javascript/simple-hooks.js +44 -0
  290. package/dist/core/code/engine/core/ingestion/languages/jvm/package-facts.js +46 -0
  291. package/dist/core/code/engine/core/ingestion/languages/jvm/package-siblings.js +200 -0
  292. package/dist/core/code/engine/core/ingestion/languages/kotlin/arity-metadata.js +23 -0
  293. package/dist/core/code/engine/core/ingestion/languages/kotlin/arity.js +18 -0
  294. package/dist/core/code/engine/core/ingestion/languages/kotlin/cache-stats.js +21 -0
  295. package/dist/core/code/engine/core/ingestion/languages/kotlin/capture-side-channel.js +160 -0
  296. package/dist/core/code/engine/core/ingestion/languages/kotlin/captures.js +1262 -0
  297. package/dist/core/code/engine/core/ingestion/languages/kotlin/companion-scopes.js +72 -0
  298. package/dist/core/code/engine/core/ingestion/languages/kotlin/import-decomposer.js +40 -0
  299. package/dist/core/code/engine/core/ingestion/languages/kotlin/import-target.js +135 -0
  300. package/dist/core/code/engine/core/ingestion/languages/kotlin/index.js +26 -0
  301. package/dist/core/code/engine/core/ingestion/languages/kotlin/interpret.js +75 -0
  302. package/dist/core/code/engine/core/ingestion/languages/kotlin/merge-bindings.js +28 -0
  303. package/dist/core/code/engine/core/ingestion/languages/kotlin/owners.js +134 -0
  304. package/dist/core/code/engine/core/ingestion/languages/kotlin/package-facts.js +16 -0
  305. package/dist/core/code/engine/core/ingestion/languages/kotlin/package-siblings.js +11 -0
  306. package/dist/core/code/engine/core/ingestion/languages/kotlin/query.js +243 -0
  307. package/dist/core/code/engine/core/ingestion/languages/kotlin/receiver-binding.js +103 -0
  308. package/dist/core/code/engine/core/ingestion/languages/kotlin/scope-resolver.js +207 -0
  309. package/dist/core/code/engine/core/ingestion/languages/kotlin/simple-hooks.js +42 -0
  310. package/dist/core/code/engine/core/ingestion/languages/kotlin/spring-aop.js +68 -0
  311. package/dist/core/code/engine/core/ingestion/languages/kotlin/spring-bean-metadata.js +11 -0
  312. package/dist/core/code/engine/core/ingestion/languages/kotlin/spring-conditionals.js +53 -0
  313. package/dist/core/code/engine/core/ingestion/languages/kotlin/spring-di.js +304 -0
  314. package/dist/core/code/engine/core/ingestion/languages/kotlin.js +189 -0
  315. package/dist/core/code/engine/core/ingestion/languages/php/arity-metadata.js +66 -0
  316. package/dist/core/code/engine/core/ingestion/languages/php/arity.js +43 -0
  317. package/dist/core/code/engine/core/ingestion/languages/php/cache-stats.js +32 -0
  318. package/dist/core/code/engine/core/ingestion/languages/php/captures.js +1166 -0
  319. package/dist/core/code/engine/core/ingestion/languages/php/import-decomposer.js +238 -0
  320. package/dist/core/code/engine/core/ingestion/languages/php/import-target.js +213 -0
  321. package/dist/core/code/engine/core/ingestion/languages/php/index.js +85 -0
  322. package/dist/core/code/engine/core/ingestion/languages/php/interpret.js +256 -0
  323. package/dist/core/code/engine/core/ingestion/languages/php/merge-bindings.js +50 -0
  324. package/dist/core/code/engine/core/ingestion/languages/php/namespace-siblings.js +353 -0
  325. package/dist/core/code/engine/core/ingestion/languages/php/query.js +391 -0
  326. package/dist/core/code/engine/core/ingestion/languages/php/receiver-binding.js +135 -0
  327. package/dist/core/code/engine/core/ingestion/languages/php/scope-resolver.js +361 -0
  328. package/dist/core/code/engine/core/ingestion/languages/php/simple-hooks.js +116 -0
  329. package/dist/core/code/engine/core/ingestion/languages/php.js +302 -0
  330. package/dist/core/code/engine/core/ingestion/languages/python/arity-metadata.js +49 -0
  331. package/dist/core/code/engine/core/ingestion/languages/python/arity.js +41 -0
  332. package/dist/core/code/engine/core/ingestion/languages/python/cache-stats.js +34 -0
  333. package/dist/core/code/engine/core/ingestion/languages/python/captures.js +299 -0
  334. package/dist/core/code/engine/core/ingestion/languages/python/depends-references.js +68 -0
  335. package/dist/core/code/engine/core/ingestion/languages/python/import-decomposer.js +115 -0
  336. package/dist/core/code/engine/core/ingestion/languages/python/import-target.js +440 -0
  337. package/dist/core/code/engine/core/ingestion/languages/python/index-stats.js +30 -0
  338. package/dist/core/code/engine/core/ingestion/languages/python/index.js +96 -0
  339. package/dist/core/code/engine/core/ingestion/languages/python/interpret.js +430 -0
  340. package/dist/core/code/engine/core/ingestion/languages/python/merge-bindings.js +47 -0
  341. package/dist/core/code/engine/core/ingestion/languages/python/query.js +323 -0
  342. package/dist/core/code/engine/core/ingestion/languages/python/receiver-binding.js +310 -0
  343. package/dist/core/code/engine/core/ingestion/languages/python/scope-resolver.js +80 -0
  344. package/dist/core/code/engine/core/ingestion/languages/python/simple-hooks.js +53 -0
  345. package/dist/core/code/engine/core/ingestion/languages/python.js +140 -0
  346. package/dist/core/code/engine/core/ingestion/languages/ruby/arity.js +41 -0
  347. package/dist/core/code/engine/core/ingestion/languages/ruby/cache-stats.js +21 -0
  348. package/dist/core/code/engine/core/ingestion/languages/ruby/captures.js +864 -0
  349. package/dist/core/code/engine/core/ingestion/languages/ruby/import-target.js +88 -0
  350. package/dist/core/code/engine/core/ingestion/languages/ruby/index.js +29 -0
  351. package/dist/core/code/engine/core/ingestion/languages/ruby/interpret.js +115 -0
  352. package/dist/core/code/engine/core/ingestion/languages/ruby/merge-bindings.js +21 -0
  353. package/dist/core/code/engine/core/ingestion/languages/ruby/query.js +349 -0
  354. package/dist/core/code/engine/core/ingestion/languages/ruby/receiver-binding.js +70 -0
  355. package/dist/core/code/engine/core/ingestion/languages/ruby/scope-resolver.js +263 -0
  356. package/dist/core/code/engine/core/ingestion/languages/ruby/simple-hooks.js +68 -0
  357. package/dist/core/code/engine/core/ingestion/languages/ruby.js +215 -0
  358. package/dist/core/code/engine/core/ingestion/languages/rust/arity.js +16 -0
  359. package/dist/core/code/engine/core/ingestion/languages/rust/cache-stats.js +21 -0
  360. package/dist/core/code/engine/core/ingestion/languages/rust/captures.js +304 -0
  361. package/dist/core/code/engine/core/ingestion/languages/rust/import-decomposer.js +167 -0
  362. package/dist/core/code/engine/core/ingestion/languages/rust/import-target.js +108 -0
  363. package/dist/core/code/engine/core/ingestion/languages/rust/index.js +29 -0
  364. package/dist/core/code/engine/core/ingestion/languages/rust/interpret.js +201 -0
  365. package/dist/core/code/engine/core/ingestion/languages/rust/merge-bindings.js +21 -0
  366. package/dist/core/code/engine/core/ingestion/languages/rust/method-owners.js +76 -0
  367. package/dist/core/code/engine/core/ingestion/languages/rust/module-path.js +222 -0
  368. package/dist/core/code/engine/core/ingestion/languages/rust/qualified-call.js +482 -0
  369. package/dist/core/code/engine/core/ingestion/languages/rust/query.js +280 -0
  370. package/dist/core/code/engine/core/ingestion/languages/rust/range-binding.js +687 -0
  371. package/dist/core/code/engine/core/ingestion/languages/rust/receiver-binding.js +148 -0
  372. package/dist/core/code/engine/core/ingestion/languages/rust/scope-resolver.js +151 -0
  373. package/dist/core/code/engine/core/ingestion/languages/rust/simple-hooks.js +32 -0
  374. package/dist/core/code/engine/core/ingestion/languages/rust.js +183 -0
  375. package/dist/core/code/engine/core/ingestion/languages/swift/arity-metadata.js +44 -0
  376. package/dist/core/code/engine/core/ingestion/languages/swift/arity.js +45 -0
  377. package/dist/core/code/engine/core/ingestion/languages/swift/base-type.js +30 -0
  378. package/dist/core/code/engine/core/ingestion/languages/swift/cache-stats.js +32 -0
  379. package/dist/core/code/engine/core/ingestion/languages/swift/captures.js +594 -0
  380. package/dist/core/code/engine/core/ingestion/languages/swift/conditional-directive-preprocess.js +256 -0
  381. package/dist/core/code/engine/core/ingestion/languages/swift/implicit-imports.js +60 -0
  382. package/dist/core/code/engine/core/ingestion/languages/swift/import-decomposer.js +87 -0
  383. package/dist/core/code/engine/core/ingestion/languages/swift/import-target.js +84 -0
  384. package/dist/core/code/engine/core/ingestion/languages/swift/index.js +56 -0
  385. package/dist/core/code/engine/core/ingestion/languages/swift/interpret.js +93 -0
  386. package/dist/core/code/engine/core/ingestion/languages/swift/merge-bindings.js +51 -0
  387. package/dist/core/code/engine/core/ingestion/languages/swift/query.js +226 -0
  388. package/dist/core/code/engine/core/ingestion/languages/swift/receiver-binding.js +169 -0
  389. package/dist/core/code/engine/core/ingestion/languages/swift/scope-resolver.js +192 -0
  390. package/dist/core/code/engine/core/ingestion/languages/swift/sibling-type-bindings.js +68 -0
  391. package/dist/core/code/engine/core/ingestion/languages/swift/signature-bindings.js +69 -0
  392. package/dist/core/code/engine/core/ingestion/languages/swift/simple-hooks.js +65 -0
  393. package/dist/core/code/engine/core/ingestion/languages/swift/target-grouping.js +97 -0
  394. package/dist/core/code/engine/core/ingestion/languages/swift/target-siblings.js +74 -0
  395. package/dist/core/code/engine/core/ingestion/languages/swift.js +246 -0
  396. package/dist/core/code/engine/core/ingestion/languages/typescript/arity-metadata.js +106 -0
  397. package/dist/core/code/engine/core/ingestion/languages/typescript/arity.js +57 -0
  398. package/dist/core/code/engine/core/ingestion/languages/typescript/array-callback.js +58 -0
  399. package/dist/core/code/engine/core/ingestion/languages/typescript/cache-stats.js +34 -0
  400. package/dist/core/code/engine/core/ingestion/languages/typescript/captures.js +956 -0
  401. package/dist/core/code/engine/core/ingestion/languages/typescript/cjs-export-assignment.js +535 -0
  402. package/dist/core/code/engine/core/ingestion/languages/typescript/cjs-module-exports.js +196 -0
  403. package/dist/core/code/engine/core/ingestion/languages/typescript/import-decomposer.js +374 -0
  404. package/dist/core/code/engine/core/ingestion/languages/typescript/import-target.js +65 -0
  405. package/dist/core/code/engine/core/ingestion/languages/typescript/index.js +108 -0
  406. package/dist/core/code/engine/core/ingestion/languages/typescript/interpret.js +344 -0
  407. package/dist/core/code/engine/core/ingestion/languages/typescript/merge-bindings.js +161 -0
  408. package/dist/core/code/engine/core/ingestion/languages/typescript/nuxt-auto-imports.js +325 -0
  409. package/dist/core/code/engine/core/ingestion/languages/typescript/query.js +1328 -0
  410. package/dist/core/code/engine/core/ingestion/languages/typescript/receiver-binding.js +201 -0
  411. package/dist/core/code/engine/core/ingestion/languages/typescript/scope-resolver.js +293 -0
  412. package/dist/core/code/engine/core/ingestion/languages/typescript/simple-hooks.js +139 -0
  413. package/dist/core/code/engine/core/ingestion/languages/typescript.js +455 -0
  414. package/dist/core/code/engine/core/ingestion/languages/vue/captures.js +70 -0
  415. package/dist/core/code/engine/core/ingestion/languages/vue/import-target.js +61 -0
  416. package/dist/core/code/engine/core/ingestion/languages/vue/index.js +55 -0
  417. package/dist/core/code/engine/core/ingestion/languages/vue/scope-resolver.js +295 -0
  418. package/dist/core/code/engine/core/ingestion/languages/vue.js +96 -0
  419. package/dist/core/code/engine/core/ingestion/local-symbol-pruner.js +68 -0
  420. package/dist/core/code/engine/core/ingestion/method-extractors/configs/c-cpp.js +387 -0
  421. package/dist/core/code/engine/core/ingestion/method-extractors/configs/csharp.js +290 -0
  422. package/dist/core/code/engine/core/ingestion/method-extractors/configs/dart.js +392 -0
  423. package/dist/core/code/engine/core/ingestion/method-extractors/configs/go.js +179 -0
  424. package/dist/core/code/engine/core/ingestion/method-extractors/configs/jvm.js +350 -0
  425. package/dist/core/code/engine/core/ingestion/method-extractors/configs/php.js +306 -0
  426. package/dist/core/code/engine/core/ingestion/method-extractors/configs/python.js +312 -0
  427. package/dist/core/code/engine/core/ingestion/method-extractors/configs/ruby.js +289 -0
  428. package/dist/core/code/engine/core/ingestion/method-extractors/configs/rust.js +198 -0
  429. package/dist/core/code/engine/core/ingestion/method-extractors/configs/swift.js +286 -0
  430. package/dist/core/code/engine/core/ingestion/method-extractors/configs/typescript-javascript.js +341 -0
  431. package/dist/core/code/engine/core/ingestion/method-extractors/generic.js +209 -0
  432. package/dist/core/code/engine/core/ingestion/method-types.js +3 -0
  433. package/dist/core/code/engine/core/ingestion/model/field-registry.js +41 -0
  434. package/dist/core/code/engine/core/ingestion/model/index.js +52 -0
  435. package/dist/core/code/engine/core/ingestion/model/method-registry.js +138 -0
  436. package/dist/core/code/engine/core/ingestion/model/owned-members-lookup.js +46 -0
  437. package/dist/core/code/engine/core/ingestion/model/registration-table.js +234 -0
  438. package/dist/core/code/engine/core/ingestion/model/resolve.js +183 -0
  439. package/dist/core/code/engine/core/ingestion/model/scope-resolution-indexes.js +43 -0
  440. package/dist/core/code/engine/core/ingestion/model/semantic-model.js +179 -0
  441. package/dist/core/code/engine/core/ingestion/model/symbol-table.js +216 -0
  442. package/dist/core/code/engine/core/ingestion/model/type-registry.js +84 -0
  443. package/dist/core/code/engine/core/ingestion/mro-processor.js +709 -0
  444. package/dist/core/code/engine/core/ingestion/parsing-processor.js +312 -0
  445. package/dist/core/code/engine/core/ingestion/pipeline-phases/communities.js +69 -0
  446. package/dist/core/code/engine/core/ingestion/pipeline-phases/cross-file.js +71 -0
  447. package/dist/core/code/engine/core/ingestion/pipeline-phases/di.js +338 -0
  448. package/dist/core/code/engine/core/ingestion/pipeline-phases/http-api-calls.js +312 -0
  449. package/dist/core/code/engine/core/ingestion/pipeline-phases/index.js +54 -0
  450. package/dist/core/code/engine/core/ingestion/pipeline-phases/mro.js +40 -0
  451. package/dist/core/code/engine/core/ingestion/pipeline-phases/orm.js +78 -0
  452. package/dist/core/code/engine/core/ingestion/pipeline-phases/parse-impl.js +1286 -0
  453. package/dist/core/code/engine/core/ingestion/pipeline-phases/parse.js +41 -0
  454. package/dist/core/code/engine/core/ingestion/pipeline-phases/processes.js +193 -0
  455. package/dist/core/code/engine/core/ingestion/pipeline-phases/prune-local-symbols.js +29 -0
  456. package/dist/core/code/engine/core/ingestion/pipeline-phases/registry.js +52 -0
  457. package/dist/core/code/engine/core/ingestion/pipeline-phases/routes.js +409 -0
  458. package/dist/core/code/engine/core/ingestion/pipeline-phases/rpc-edges.js +301 -0
  459. package/dist/core/code/engine/core/ingestion/pipeline-phases/runner.js +207 -0
  460. package/dist/core/code/engine/core/ingestion/pipeline-phases/scan.js +49 -0
  461. package/dist/core/code/engine/core/ingestion/pipeline-phases/spring-aop.js +442 -0
  462. package/dist/core/code/engine/core/ingestion/pipeline-phases/spring-auto-configuration.js +264 -0
  463. package/dist/core/code/engine/core/ingestion/pipeline-phases/spring-config.js +440 -0
  464. package/dist/core/code/engine/core/ingestion/pipeline-phases/structure.js +38 -0
  465. package/dist/core/code/engine/core/ingestion/pipeline-phases/tools.js +89 -0
  466. package/dist/core/code/engine/core/ingestion/pipeline-phases/types.js +40 -0
  467. package/dist/core/code/engine/core/ingestion/pipeline.js +152 -0
  468. package/dist/core/code/engine/core/ingestion/process-processor.js +325 -0
  469. package/dist/core/code/engine/core/ingestion/resolve-references.js +205 -0
  470. package/dist/core/code/engine/core/ingestion/route-extractors/constant-resolver.js +135 -0
  471. package/dist/core/code/engine/core/ingestion/route-extractors/django-root-discovery.js +221 -0
  472. package/dist/core/code/engine/core/ingestion/route-extractors/django.js +428 -0
  473. package/dist/core/code/engine/core/ingestion/route-extractors/expo.js +39 -0
  474. package/dist/core/code/engine/core/ingestion/route-extractors/fastapi-router-bindings.js +264 -0
  475. package/dist/core/code/engine/core/ingestion/route-extractors/laravel.js +501 -0
  476. package/dist/core/code/engine/core/ingestion/route-extractors/middleware.js +175 -0
  477. package/dist/core/code/engine/core/ingestion/route-extractors/nextjs.js +81 -0
  478. package/dist/core/code/engine/core/ingestion/route-extractors/php.js +25 -0
  479. package/dist/core/code/engine/core/ingestion/route-extractors/python-const-resolver.js +307 -0
  480. package/dist/core/code/engine/core/ingestion/route-extractors/response-shapes.js +299 -0
  481. package/dist/core/code/engine/core/ingestion/route-extractors/route-path.js +71 -0
  482. package/dist/core/code/engine/core/ingestion/route-extractors/spring-shared.js +310 -0
  483. package/dist/core/code/engine/core/ingestion/route-extractors/spring.js +441 -0
  484. package/dist/core/code/engine/core/ingestion/scope-extractor-bridge.js +60 -0
  485. package/dist/core/code/engine/core/ingestion/scope-extractor.js +1373 -0
  486. package/dist/core/code/engine/core/ingestion/scope-resolution/contract/scope-resolver.js +282 -0
  487. package/dist/core/code/engine/core/ingestion/scope-resolution/graph-bridge/callee-id-sink.js +72 -0
  488. package/dist/core/code/engine/core/ingestion/scope-resolution/graph-bridge/edges.js +194 -0
  489. package/dist/core/code/engine/core/ingestion/scope-resolution/graph-bridge/ids.js +472 -0
  490. package/dist/core/code/engine/core/ingestion/scope-resolution/graph-bridge/imports-to-edges.js +49 -0
  491. package/dist/core/code/engine/core/ingestion/scope-resolution/graph-bridge/method-dispatch.js +43 -0
  492. package/dist/core/code/engine/core/ingestion/scope-resolution/graph-bridge/node-lookup.js +274 -0
  493. package/dist/core/code/engine/core/ingestion/scope-resolution/graph-bridge/references-to-edges.js +93 -0
  494. package/dist/core/code/engine/core/ingestion/scope-resolution/passes/callable-value-flow.js +1240 -0
  495. package/dist/core/code/engine/core/ingestion/scope-resolution/passes/compound-receiver.js +1174 -0
  496. package/dist/core/code/engine/core/ingestion/scope-resolution/passes/free-call-fallback.js +873 -0
  497. package/dist/core/code/engine/core/ingestion/scope-resolution/passes/imported-return-types.js +226 -0
  498. package/dist/core/code/engine/core/ingestion/scope-resolution/passes/mro.js +107 -0
  499. package/dist/core/code/engine/core/ingestion/scope-resolution/passes/overload-narrowing.js +441 -0
  500. package/dist/core/code/engine/core/ingestion/scope-resolution/passes/property-dispatch.js +122 -0
  501. package/dist/core/code/engine/core/ingestion/scope-resolution/passes/receiver-bound-calls.js +1720 -0
  502. package/dist/core/code/engine/core/ingestion/scope-resolution/pipeline/phase.js +395 -0
  503. package/dist/core/code/engine/core/ingestion/scope-resolution/pipeline/reconcile-ownership.js +208 -0
  504. package/dist/core/code/engine/core/ingestion/scope-resolution/pipeline/registry.js +49 -0
  505. package/dist/core/code/engine/core/ingestion/scope-resolution/pipeline/run.js +632 -0
  506. package/dist/core/code/engine/core/ingestion/scope-resolution/pipeline/validate-bindings-immutability.js +112 -0
  507. package/dist/core/code/engine/core/ingestion/scope-resolution/resolution-outcome.js +41 -0
  508. package/dist/core/code/engine/core/ingestion/scope-resolution/scope/namespace-targets.js +81 -0
  509. package/dist/core/code/engine/core/ingestion/scope-resolution/scope/walkers.js +1835 -0
  510. package/dist/core/code/engine/core/ingestion/scope-resolution/unresolved-receivers.js +242 -0
  511. package/dist/core/code/engine/core/ingestion/scope-resolution/utils/definition-id.js +22 -0
  512. package/dist/core/code/engine/core/ingestion/scope-resolution/workspace-index.js +151 -0
  513. package/dist/core/code/engine/core/ingestion/structure-processor.js +40 -0
  514. package/dist/core/code/engine/core/ingestion/tree-sitter-queries.js +2244 -0
  515. package/dist/core/code/engine/core/ingestion/ts-js-hoc-utils.js +115 -0
  516. package/dist/core/code/engine/core/ingestion/type-env.js +1136 -0
  517. package/dist/core/code/engine/core/ingestion/type-extractors/c-cpp.js +555 -0
  518. package/dist/core/code/engine/core/ingestion/type-extractors/csharp.js +570 -0
  519. package/dist/core/code/engine/core/ingestion/type-extractors/dart.js +372 -0
  520. package/dist/core/code/engine/core/ingestion/type-extractors/go.js +508 -0
  521. package/dist/core/code/engine/core/ingestion/type-extractors/jvm.js +875 -0
  522. package/dist/core/code/engine/core/ingestion/type-extractors/php.js +537 -0
  523. package/dist/core/code/engine/core/ingestion/type-extractors/python.js +477 -0
  524. package/dist/core/code/engine/core/ingestion/type-extractors/ruby.js +380 -0
  525. package/dist/core/code/engine/core/ingestion/type-extractors/rust.js +502 -0
  526. package/dist/core/code/engine/core/ingestion/type-extractors/shared.js +843 -0
  527. package/dist/core/code/engine/core/ingestion/type-extractors/swift.js +490 -0
  528. package/dist/core/code/engine/core/ingestion/type-extractors/types.js +2 -0
  529. package/dist/core/code/engine/core/ingestion/type-extractors/typescript.js +690 -0
  530. package/dist/core/code/engine/core/ingestion/utils/ast-helpers.js +1693 -0
  531. package/dist/core/code/engine/core/ingestion/utils/call-analysis.js +779 -0
  532. package/dist/core/code/engine/core/ingestion/utils/callable-flow-captures.js +932 -0
  533. package/dist/core/code/engine/core/ingestion/utils/callable-labels.js +49 -0
  534. package/dist/core/code/engine/core/ingestion/utils/deferred-resolution-profile.js +151 -0
  535. package/dist/core/code/engine/core/ingestion/utils/effective-ram.js +67 -0
  536. package/dist/core/code/engine/core/ingestion/utils/env.js +60 -0
  537. package/dist/core/code/engine/core/ingestion/utils/event-loop.js +9 -0
  538. package/dist/core/code/engine/core/ingestion/utils/graph-sort.js +103 -0
  539. package/dist/core/code/engine/core/ingestion/utils/heap-probe.js +45 -0
  540. package/dist/core/code/engine/core/ingestion/utils/heritage-marker.js +47 -0
  541. package/dist/core/code/engine/core/ingestion/utils/line-base.js +24 -0
  542. package/dist/core/code/engine/core/ingestion/utils/max-file-size.js +59 -0
  543. package/dist/core/code/engine/core/ingestion/utils/method-props.js +198 -0
  544. package/dist/core/code/engine/core/ingestion/utils/qualified-name.js +73 -0
  545. package/dist/core/code/engine/core/ingestion/utils/receiver-chain-captures.js +60 -0
  546. package/dist/core/code/engine/core/ingestion/utils/receiver-chain-codec.js +188 -0
  547. package/dist/core/code/engine/core/ingestion/utils/scope-tree-walk.js +36 -0
  548. package/dist/core/code/engine/core/ingestion/utils/symbol-labels.js +48 -0
  549. package/dist/core/code/engine/core/ingestion/utils/template-arguments.js +187 -0
  550. package/dist/core/code/engine/core/ingestion/utils/type-parameters.js +209 -0
  551. package/dist/core/code/engine/core/ingestion/utils/verbose.js +6 -0
  552. package/dist/core/code/engine/core/ingestion/variable-extractors/configs/c-cpp.js +133 -0
  553. package/dist/core/code/engine/core/ingestion/variable-extractors/configs/csharp.js +66 -0
  554. package/dist/core/code/engine/core/ingestion/variable-extractors/configs/dart.js +111 -0
  555. package/dist/core/code/engine/core/ingestion/variable-extractors/configs/go.js +153 -0
  556. package/dist/core/code/engine/core/ingestion/variable-extractors/configs/jvm.js +145 -0
  557. package/dist/core/code/engine/core/ingestion/variable-extractors/configs/php.js +61 -0
  558. package/dist/core/code/engine/core/ingestion/variable-extractors/configs/python.js +104 -0
  559. package/dist/core/code/engine/core/ingestion/variable-extractors/configs/ruby.js +55 -0
  560. package/dist/core/code/engine/core/ingestion/variable-extractors/configs/rust.js +79 -0
  561. package/dist/core/code/engine/core/ingestion/variable-extractors/configs/swift.js +91 -0
  562. package/dist/core/code/engine/core/ingestion/variable-extractors/configs/typescript-javascript.js +86 -0
  563. package/dist/core/code/engine/core/ingestion/variable-extractors/generic.js +111 -0
  564. package/dist/core/code/engine/core/ingestion/variable-types.js +3 -0
  565. package/dist/core/code/engine/core/ingestion/vue-sfc-extractor.js +544 -0
  566. package/dist/core/code/engine/core/ingestion/workers/callable-id.js +122 -0
  567. package/dist/core/code/engine/core/ingestion/workers/clone-safety.js +470 -0
  568. package/dist/core/code/engine/core/ingestion/workers/parse-worker.js +2456 -0
  569. package/dist/core/code/engine/core/ingestion/workers/post-result.js +90 -0
  570. package/dist/core/code/engine/core/ingestion/workers/quarantine.js +41 -0
  571. package/dist/core/code/engine/core/ingestion/workers/result-merge.js +59 -0
  572. package/dist/core/code/engine/core/ingestion/workers/worker-pool.js +1725 -0
  573. package/dist/core/code/engine/core/ingestion/workspace-config.js +139 -0
  574. package/dist/core/code/engine/core/lbug/conn-lock.js +72 -0
  575. package/dist/core/code/engine/core/lbug/csv-generator.js +710 -0
  576. package/dist/core/code/engine/core/lbug/cypher-escape.js +24 -0
  577. package/dist/core/code/engine/core/lbug/extension-load-error.js +339 -0
  578. package/dist/core/code/engine/core/lbug/extension-loader.js +261 -0
  579. package/dist/core/code/engine/core/lbug/graph-emit-sink.js +584 -0
  580. package/dist/core/code/engine/core/lbug/lbug-adapter.js +2703 -0
  581. package/dist/core/code/engine/core/lbug/lbug-config.js +1029 -0
  582. package/dist/core/code/engine/core/lbug/native-check.js +435 -0
  583. package/dist/core/code/engine/core/lbug/pool-adapter.js +973 -0
  584. package/dist/core/code/engine/core/lbug/query-params.js +25 -0
  585. package/dist/core/code/engine/core/lbug/query-result-utils.js +31 -0
  586. package/dist/core/code/engine/core/lbug/rel-pair-routing.js +373 -0
  587. package/dist/core/code/engine/core/lbug/schema.js +771 -0
  588. package/dist/core/code/engine/core/lbug/shutdown-helpers.js +40 -0
  589. package/dist/core/code/engine/core/lbug/sidecar-recovery.js +716 -0
  590. package/dist/core/code/engine/core/lbug/stdio-capture.js +49 -0
  591. package/dist/core/code/engine/core/lbug/sync-csv-writer.js +115 -0
  592. package/dist/core/code/engine/core/lbug/wal-checkpoint-driver.js +215 -0
  593. package/dist/core/code/engine/core/lbug/wal-driver-state.js +28 -0
  594. package/dist/core/code/engine/core/logger.js +339 -0
  595. package/dist/core/code/engine/core/platform/capabilities.js +91 -0
  596. package/dist/core/code/engine/core/run-analyze.js +1098 -0
  597. package/dist/core/code/engine/core/tree-sitter/parser-loader.js +281 -0
  598. package/dist/core/code/engine/core/tree-sitter/safe-parse.js +258 -0
  599. package/dist/core/code/engine/core/tree-sitter/vendored-grammars.js +64 -0
  600. package/dist/core/code/engine/lib/utils.js +121 -0
  601. package/dist/core/code/engine/mcp/core/lbug-adapter.js +27 -0
  602. package/dist/core/code/engine/mcp/local/aop-metadata.js +230 -0
  603. package/dist/core/code/engine/mcp/local/bean-metadata.js +49 -0
  604. package/dist/core/code/engine/mcp/local/limits.js +15 -0
  605. package/dist/core/code/engine/mcp/local/line-display.js +6 -0
  606. package/dist/core/code/engine/mcp/local/local-backend.js +4142 -0
  607. package/dist/core/code/engine/storage/branch-index.js +72 -0
  608. package/dist/core/code/engine/storage/file-hash.js +95 -0
  609. package/dist/core/code/engine/storage/fs-atomic.js +34 -0
  610. package/dist/core/code/engine/storage/git.js +555 -0
  611. package/dist/core/code/engine/storage/index-lock.js +664 -0
  612. package/dist/core/code/engine/storage/parse-cache.js +650 -0
  613. package/dist/core/code/engine/storage/parsedfile-store.js +620 -0
  614. package/dist/core/code/engine/storage/repo-manager.js +1061 -0
  615. package/dist/core/code/engine/storage/scope-index-store.js +247 -0
  616. package/dist/core/code/engine/types/pipeline.js +2 -0
  617. package/dist/core/code/scripts/install-duckdb-extension.mjs +125 -0
  618. package/dist/core/code/scripts/resolve-analyze-cmd.cjs +346 -0
  619. package/dist/core/code/shared/graph/types.js +8 -0
  620. package/dist/core/code/shared/index.js +105 -0
  621. package/dist/core/code/shared/integrations/circuit-breaker.js +242 -0
  622. package/dist/core/code/shared/integrations/resilient-fetch.js +224 -0
  623. package/dist/core/code/shared/integrations/retry.js +70 -0
  624. package/dist/core/code/shared/integrations/understand-quickly.js +145 -0
  625. package/dist/core/code/shared/language-detection.js +162 -0
  626. package/dist/core/code/shared/languages.js +27 -0
  627. package/dist/core/code/shared/lbug/schema-constants.js +98 -0
  628. package/dist/core/code/shared/mro-strategy.js +2 -0
  629. package/dist/core/code/shared/pipeline.js +5 -0
  630. package/dist/core/code/shared/scope-resolution/callable-flow-site.js +11 -0
  631. package/dist/core/code/shared/scope-resolution/def-index.js +53 -0
  632. package/dist/core/code/shared/scope-resolution/evidence-weights.js +87 -0
  633. package/dist/core/code/shared/scope-resolution/finalize-algorithm.js +807 -0
  634. package/dist/core/code/shared/scope-resolution/language-classification.js +46 -0
  635. package/dist/core/code/shared/scope-resolution/method-dispatch-index.js +100 -0
  636. package/dist/core/code/shared/scope-resolution/module-scope-index.js +59 -0
  637. package/dist/core/code/shared/scope-resolution/origin-priority.js +23 -0
  638. package/dist/core/code/shared/scope-resolution/parsed-file.js +54 -0
  639. package/dist/core/code/shared/scope-resolution/position-index.js +136 -0
  640. package/dist/core/code/shared/scope-resolution/qualified-name-index.js +77 -0
  641. package/dist/core/code/shared/scope-resolution/reference-site.js +24 -0
  642. package/dist/core/code/shared/scope-resolution/registries/class-registry.js +32 -0
  643. package/dist/core/code/shared/scope-resolution/registries/context.js +52 -0
  644. package/dist/core/code/shared/scope-resolution/registries/evidence.js +152 -0
  645. package/dist/core/code/shared/scope-resolution/registries/field-registry.js +33 -0
  646. package/dist/core/code/shared/scope-resolution/registries/lookup-core.js +392 -0
  647. package/dist/core/code/shared/scope-resolution/registries/lookup-qualified.js +58 -0
  648. package/dist/core/code/shared/scope-resolution/registries/macro-registry.js +34 -0
  649. package/dist/core/code/shared/scope-resolution/registries/method-registry.js +34 -0
  650. package/dist/core/code/shared/scope-resolution/registries/tie-breaks.js +63 -0
  651. package/dist/core/code/shared/scope-resolution/resolve-type-ref.js +128 -0
  652. package/dist/core/code/shared/scope-resolution/scope-id.js +49 -0
  653. package/dist/core/code/shared/scope-resolution/scope-tree.js +225 -0
  654. package/dist/core/code/shared/scope-resolution/symbol-definition.js +12 -0
  655. package/dist/core/code/shared/scope-resolution/types.js +25 -0
  656. package/dist/core/code/shared/test-helpers.js +17 -0
  657. package/dist/core/code/vendor/leiden/index.cjs +355 -0
  658. package/dist/core/code/vendor/leiden/utils.cjs +419 -0
  659. package/dist/core/timeline/cli.d.ts.map +1 -1
  660. package/dist/core/timeline/cli.js +13 -6
  661. package/dist/core/timeline/cli.js.map +1 -1
  662. package/dist/core/timeline/debris.d.ts +20 -0
  663. package/dist/core/timeline/debris.d.ts.map +1 -0
  664. package/dist/core/timeline/debris.js +124 -0
  665. package/dist/core/timeline/debris.js.map +1 -0
  666. package/dist/core/timeline/hook-runner.d.ts.map +1 -1
  667. package/dist/core/timeline/hook-runner.js +3 -1
  668. package/dist/core/timeline/hook-runner.js.map +1 -1
  669. package/dist/core/timeline/hooks.d.ts.map +1 -1
  670. package/dist/core/timeline/hooks.js +13 -5
  671. package/dist/core/timeline/hooks.js.map +1 -1
  672. package/dist/core/timeline/installer.d.ts +2 -0
  673. package/dist/core/timeline/installer.d.ts.map +1 -1
  674. package/dist/core/timeline/installer.js +12 -0
  675. package/dist/core/timeline/installer.js.map +1 -1
  676. package/dist/core/timeline/project-root.d.ts +21 -0
  677. package/dist/core/timeline/project-root.d.ts.map +1 -0
  678. package/dist/core/timeline/project-root.js +83 -0
  679. package/dist/core/timeline/project-root.js.map +1 -0
  680. package/package.json +1 -1
@@ -0,0 +1,1029 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.waitForWindowsHandleRelease = exports.sleep = exports._isTestFixturePathForTest = exports.isOpenRetryExhausted = exports.LBUG_OPEN_RETRY_EXHAUSTED = exports.HANDLE_RELEASE_PROBE_DELAY_MS = exports.HANDLE_RELEASE_PROBE_ATTEMPTS = exports.classifyDeleteAllError = exports.isLbugCheckpointBusyError = exports.isDbBusyError = exports.getOsPageSize = exports._setOsPageSizeForTests = exports.isPageSizeAwareLadybug = exports.isLbugPageSizeFrameError = exports.isLbugCheckpointIoError = exports.WAL_RECOVERY_SUGGESTION = exports.bufferPoolExhaustionRemedy = exports.getEffectiveBufferPoolSize = exports.setBufferPoolSizeHint = exports.estimateBufferPool = exports.granuleRatio = exports.parseWalCheckpointThreshold = exports.LBUG_MAX_DB_SIZE = void 0;
7
+ exports.cleanupNativePathJunctions = cleanupNativePathJunctions;
8
+ exports.toNativeSafePath = toNativeSafePath;
9
+ exports.resolveNativeSafeStorageDir = resolveNativeSafeStorageDir;
10
+ exports.isWalCorruptionError = isWalCorruptionError;
11
+ exports.createLbugDatabase = createLbugDatabase;
12
+ exports.openLbugConnection = openLbugConnection;
13
+ exports.closeLbugConnection = closeLbugConnection;
14
+ const promises_1 = __importDefault(require("fs/promises"));
15
+ const fs_1 = __importDefault(require("fs"));
16
+ const os_1 = __importDefault(require("os"));
17
+ const path_1 = __importDefault(require("path"));
18
+ const crypto_1 = __importDefault(require("crypto"));
19
+ const child_process_1 = require("child_process");
20
+ const worker_threads_1 = require("worker_threads");
21
+ const logger_js_1 = require("../logger.js");
22
+ // ─── Windows non-ASCII path workaround (#1811) ───────────────────────────────
23
+ //
24
+ // KuzuDB's native C++ layer on Windows uses CreateFileA (ANSI), not
25
+ // CreateFileW. Non-ASCII path bytes from Node.js (UTF-8) are
26
+ // misinterpreted via the system's Active Code Page (e.g. GBK), producing
27
+ // a garbled path — "Error 3: The system cannot find the path."
28
+ //
29
+ // Layered workaround:
30
+ // 1. Try 8.3 short-name form (fast, no persistent state)
31
+ // 2. Fall back to an NTFS junction from an ASCII temp path
32
+ // 3. If both fail, log a diagnostic and return the original path
33
+ const NON_ASCII_RE = /[^\x00-\x7F]/;
34
+ const JUNCTION_PREFIX = 'gitnexus-junction-';
35
+ const activeJunctions = new Set();
36
+ let cleanupRegistered = false;
37
+ let orphanScanDone = false;
38
+ function junctionHash(targetDir) {
39
+ return crypto_1.default.createHash('sha256').update(targetDir).digest('hex').slice(0, 16);
40
+ }
41
+ function tryShortPath(p) {
42
+ try {
43
+ // Pass the path via environment variable so the command string is
44
+ // static — avoids CodeQL command-injection taint (the path never
45
+ // appears in the shell command text).
46
+ const result = (0, child_process_1.execFileSync)('cmd.exe', ['/c', 'for %I in ("%CGRAPH_SP%") do @echo %~sI'], {
47
+ encoding: 'utf-8',
48
+ timeout: 5000,
49
+ windowsHide: true,
50
+ stdio: ['pipe', 'pipe', 'pipe'],
51
+ env: { ...process.env, CGRAPH_SP: p },
52
+ });
53
+ const shortPath = result.trim();
54
+ if (shortPath &&
55
+ !NON_ASCII_RE.test(shortPath) &&
56
+ (!shortPath.includes('?') || p.includes('?'))) {
57
+ return shortPath;
58
+ }
59
+ }
60
+ catch {
61
+ // 8.3 unavailable or cmd failed
62
+ }
63
+ return null;
64
+ }
65
+ function tryJunction(targetDir, leaf) {
66
+ const hash = junctionHash(targetDir);
67
+ const junctionLink = path_1.default.join(os_1.default.tmpdir(), `${JUNCTION_PREFIX}${hash}`);
68
+ if (fs_1.default.existsSync(junctionLink)) {
69
+ try {
70
+ const existing = fs_1.default.readlinkSync(junctionLink);
71
+ if (path_1.default.resolve(existing) === path_1.default.resolve(targetDir)) {
72
+ activeJunctions.add(junctionLink);
73
+ return path_1.default.join(junctionLink, leaf);
74
+ }
75
+ fs_1.default.rmSync(junctionLink, { recursive: true, force: true });
76
+ }
77
+ catch {
78
+ // Stale or broken junction — remove and recreate
79
+ try {
80
+ fs_1.default.rmSync(junctionLink, { recursive: true, force: true });
81
+ }
82
+ catch {
83
+ /* best effort */
84
+ }
85
+ }
86
+ }
87
+ try {
88
+ fs_1.default.symlinkSync(targetDir, junctionLink, 'junction');
89
+ activeJunctions.add(junctionLink);
90
+ return path_1.default.join(junctionLink, leaf);
91
+ }
92
+ catch (err) {
93
+ if (err.code === 'EEXIST') {
94
+ try {
95
+ const existing = fs_1.default.readlinkSync(junctionLink);
96
+ if (path_1.default.resolve(existing) === path_1.default.resolve(targetDir)) {
97
+ activeJunctions.add(junctionLink);
98
+ return path_1.default.join(junctionLink, leaf);
99
+ }
100
+ }
101
+ catch {
102
+ /* cannot verify — fall through */
103
+ }
104
+ }
105
+ }
106
+ return null;
107
+ }
108
+ function registerCleanupHandlers() {
109
+ if (cleanupRegistered)
110
+ return;
111
+ cleanupRegistered = true;
112
+ process.on('exit', () => cleanupNativePathJunctions());
113
+ for (const signal of ['SIGTERM', 'SIGINT']) {
114
+ process.on(signal, () => {
115
+ cleanupNativePathJunctions();
116
+ if (process.platform === 'win32') {
117
+ process.exit(signal === 'SIGINT' ? 130 : 143);
118
+ }
119
+ else {
120
+ process.kill(process.pid, signal);
121
+ }
122
+ });
123
+ }
124
+ }
125
+ function scanOrphanedJunctions() {
126
+ if (orphanScanDone)
127
+ return;
128
+ orphanScanDone = true;
129
+ try {
130
+ const tmpdir = os_1.default.tmpdir();
131
+ const entries = fs_1.default.readdirSync(tmpdir);
132
+ for (const entry of entries) {
133
+ if (!entry.startsWith(JUNCTION_PREFIX))
134
+ continue;
135
+ const junctionPath = path_1.default.join(tmpdir, entry);
136
+ try {
137
+ const target = fs_1.default.readlinkSync(junctionPath);
138
+ try {
139
+ fs_1.default.lstatSync(target);
140
+ }
141
+ catch {
142
+ fs_1.default.rmSync(junctionPath, { recursive: true, force: true });
143
+ }
144
+ }
145
+ catch {
146
+ // Not a symlink/junction or unreadable — leave it
147
+ }
148
+ }
149
+ }
150
+ catch {
151
+ // tmpdir unreadable — skip scan
152
+ }
153
+ }
154
+ function cleanupNativePathJunctions() {
155
+ for (const junctionPath of activeJunctions) {
156
+ try {
157
+ fs_1.default.rmSync(junctionPath, { recursive: true, force: true });
158
+ }
159
+ catch {
160
+ // Best effort — EPERM on Windows is common during exit
161
+ }
162
+ }
163
+ activeJunctions.clear();
164
+ }
165
+ function toNativeSafePath(p) {
166
+ if (process.platform !== 'win32')
167
+ return p;
168
+ if (!NON_ASCII_RE.test(p))
169
+ return p;
170
+ if (worker_threads_1.isMainThread) {
171
+ scanOrphanedJunctions();
172
+ registerCleanupHandlers();
173
+ }
174
+ const shortPath = tryShortPath(p);
175
+ if (shortPath)
176
+ return shortPath;
177
+ if (!worker_threads_1.isMainThread) {
178
+ logger_js_1.logger.warn(`GitNexus: non-ASCII path in worker thread — junction fallback skipped. ` +
179
+ `Path: "${p}". 8.3 short names may need to be enabled on this volume.`);
180
+ return p;
181
+ }
182
+ const targetDir = path_1.default.dirname(p);
183
+ const leaf = path_1.default.basename(p);
184
+ if (fs_1.default.existsSync(targetDir)) {
185
+ const junctionResult = tryJunction(targetDir, leaf);
186
+ if (junctionResult)
187
+ return junctionResult;
188
+ }
189
+ logger_js_1.logger.warn(`GitNexus: non-ASCII path "${p}" could not be converted to an ASCII-safe form. ` +
190
+ 'LadybugDB may fail with "Cannot open file." To fix: move the repo to a path ' +
191
+ 'without CJK/Unicode characters, or enable 8.3 short names on this volume ' +
192
+ '(fsutil 8dot3name set 0).');
193
+ return p;
194
+ }
195
+ /**
196
+ * Resolve the on-disk CSV staging dir for `<storagePath>/<subdir>`, applying the
197
+ * same ASCII-safe relocation `toNativeSafePath` enables: on Windows with a
198
+ * non-ASCII storage path, LadybugDB's bulk COPY cannot open files under that
199
+ * path, so the dir is relocated under `os.tmpdir()`. Shared by the structural
200
+ * `csv/` dir and the streaming `pdg-csv/` dir (#2202) so the two can never
201
+ * diverge on platform handling; the `gitnexus-<subdir>-` prefix keeps their tmp
202
+ * locations distinct and recognizable.
203
+ *
204
+ * The relocated dir is created with `fs.mkdtempSync` (a unique, mode-0700,
205
+ * guaranteed-not-pre-existing suffix) rather than a deterministic
206
+ * `gitnexus-<subdir>-<hash>` name. A predictable name in the world-readable OS
207
+ * temp dir is information-disclosure-prone and pre-plantable
208
+ * (CWE-377/378 / CodeQL `js/insecure-temporary-file`); mkdtemp's random suffix
209
+ * is the documented mitigation and is what reaches the streaming sink's
210
+ * `fs.openSync`. The non-Windows / ASCII path stays a pure `path.join` (no dir
211
+ * created) and is byte-identical to before.
212
+ */
213
+ function resolveNativeSafeStorageDir(storagePath, subdir) {
214
+ if (process.platform === 'win32' && NON_ASCII_RE.test(storagePath)) {
215
+ // 8.3-shorten the tmpdir base first (a non-ASCII Windows *profile* path can
216
+ // make os.tmpdir() itself non-ASCII), THEN mkdtemp so the returned path —
217
+ // the one that flows into fs.openSync — is provably mkdtemp-sourced (random,
218
+ // exclusive) and clears the insecure-temp-file dataflow.
219
+ const base = toNativeSafePath(os_1.default.tmpdir());
220
+ return fs_1.default.mkdtempSync(path_1.default.join(base, `gitnexus-${subdir}-`));
221
+ }
222
+ return path_1.default.join(storagePath, subdir);
223
+ }
224
+ /**
225
+ * Shared configuration for `@ladybugdb/core` `Database` construction.
226
+ *
227
+ * Two values changed meaningfully in `@ladybugdb/core` 0.16.0 and need to be
228
+ * pinned explicitly by every caller, otherwise GitNexus regresses:
229
+ *
230
+ * 1. `maxDBSize` defaults to `0`, which the native runtime interprets as
231
+ * "use the platform's full mmap address space" — typically 8 TB on
232
+ * 64-bit Linux. Constrained environments (CI runners, containers, WSL)
233
+ * cannot reserve that much address space and crash with
234
+ * `Buffer manager exception: Mmap for size 8796093022208 failed.`
235
+ * See LadybugDB upstream JSDoc:
236
+ * > "introduced temporarily for now to get around with the default 8TB
237
+ * > mmap address space limit some environment".
238
+ *
239
+ * 2. `enableCompression` flipped its default from `false` (0.15.x) to
240
+ * `true` (0.16.0). Existing call sites that relied on the positional
241
+ * default must now pass `false` explicitly to preserve behaviour.
242
+ *
243
+ * 3. `bufferManagerSize` (not a 0.16.0 change, same pin-explicitly
244
+ * principle): `0` means "native default", and the native default buffer
245
+ * pool is 80% of physical RAM. A long-lived `cgraph mcp` process or a
246
+ * large incremental analyze can balloon to that ceiling and OOM-kill the
247
+ * host session (#2557), so GitNexus pins an explicit bounded pool — see
248
+ * `resolveBufferManagerSize`.
249
+ *
250
+ * Putting these in one shared module guarantees every `new lbug.Database(...)`
251
+ * call site agrees on the same ceilings and behaviour.
252
+ */
253
+ /**
254
+ * Upper bound for any single GitNexus LadybugDB file (graph index, group
255
+ * bridge, install scratch, test fixture). 16 GiB is intentionally generous
256
+ * for real-world code graphs (the GitNexus self-index uses < 50 MiB) while
257
+ * remaining far below any 64-bit OS mmap ceiling.
258
+ *
259
+ * Override with the `CGRAPH_LBUG_MAX_DB_SIZE` environment variable when
260
+ * indexing genuinely huge monorepos. Values are coerced to a positive
261
+ * integer; anything invalid falls back to the default.
262
+ */
263
+ exports.LBUG_MAX_DB_SIZE = (() => {
264
+ const raw = process.env.CGRAPH_LBUG_MAX_DB_SIZE;
265
+ if (raw) {
266
+ const parsed = Number(raw);
267
+ if (Number.isFinite(parsed) && parsed > 0)
268
+ return Math.floor(parsed);
269
+ }
270
+ return 16 * 1024 * 1024 * 1024;
271
+ })();
272
+ const parseWalCheckpointThreshold = (raw) => {
273
+ if (raw === undefined)
274
+ return undefined;
275
+ const normalized = raw.trim();
276
+ if (normalized.length === 0)
277
+ return undefined;
278
+ const parsed = Number(normalized);
279
+ if (!Number.isInteger(parsed) || parsed < -1)
280
+ return undefined;
281
+ return parsed;
282
+ };
283
+ exports.parseWalCheckpointThreshold = parseWalCheckpointThreshold;
284
+ /**
285
+ * Default GitNexus WAL auto-checkpoint threshold in bytes (64 MiB).
286
+ *
287
+ * Larger than Ladybug's stock ~16 MiB to reduce checkpoint rename/remove
288
+ * churn under heavy analyze write load — the original race that motivated
289
+ * issue #1741 triggered at the stock threshold. README examples in
290
+ * `README.md` and `cgraph/README.md` and the recovery hint in
291
+ * `analyze.ts` MUST stay in sync with this value.
292
+ */
293
+ const DEFAULT_WAL_CHECKPOINT_THRESHOLD = 64 * 1024 * 1024;
294
+ const resolveCheckpointThreshold = () => {
295
+ const raw = process.env.CGRAPH_WAL_CHECKPOINT_THRESHOLD;
296
+ if (raw === undefined)
297
+ return DEFAULT_WAL_CHECKPOINT_THRESHOLD;
298
+ const parsed = (0, exports.parseWalCheckpointThreshold)(raw);
299
+ if (parsed !== undefined)
300
+ return parsed;
301
+ // Non-empty but unparseable input: warn the operator and fall back. Mirrors
302
+ // the CLI's `--wal-checkpoint-threshold` validation (which hard-errors)
303
+ // but the env-var path stays soft to preserve "set once in your shell"
304
+ // ergonomics across mixed-version invocations.
305
+ if (raw.trim().length > 0) {
306
+ logger_js_1.logger.warn({ rawValue: raw, fallback: DEFAULT_WAL_CHECKPOINT_THRESHOLD }, `Ignoring invalid CGRAPH_WAL_CHECKPOINT_THRESHOLD=${raw}; expected integer >= -1; falling back to default (${DEFAULT_WAL_CHECKPOINT_THRESHOLD}).`);
307
+ }
308
+ return DEFAULT_WAL_CHECKPOINT_THRESHOLD;
309
+ };
310
+ /**
311
+ * Default ceiling for the LadybugDB buffer pool in bytes (#2557).
312
+ *
313
+ * The pool is a page cache with eviction, so the ceiling trades throughput
314
+ * on very large working sets for a machine that stays alive: 2 GiB is
315
+ * ~40× the GitNexus self-index, while the native 80%-of-RAM default let a
316
+ * `detect_changes` call grow a 105 MiB on-disk index to 19.5 GiB RSS and
317
+ * OOM-kill the reporter's session. The `min` with 80% of `os.totalmem()`
318
+ * keeps sub-2.5-GiB machines at the native-equivalent bound (no regression
319
+ * there); the 64 MiB floor keeps tiny containers above any plausible
320
+ * native minimum pool size.
321
+ */
322
+ const DEFAULT_BUFFER_POOL_CAP = 2 * 1024 * 1024 * 1024;
323
+ const BUFFER_POOL_FLOOR = 64 * 1024 * 1024;
324
+ // COPY-safety floor for the adaptive hint (below). LadybugDB's bulk COPY needs
325
+ // working buffer-pool memory that scales with the repo: a 64 MiB pool fails
326
+ // ("buffer pool is full and no memory could be freed") on any non-trivial repo,
327
+ // and even the ~1800-file GitNexus checkout needs ≥256 MiB. So the adaptive
328
+ // size never drops a repo below this — a distinct, higher floor than
329
+ // BUFFER_POOL_FLOOR, which only guards defaultBufferPoolSize on tiny-RAM
330
+ // machines. It is still clamped up to defaultBufferPoolSize, so a machine whose
331
+ // default is below this floor keeps its default rather than over-committing.
332
+ const ADAPTIVE_POOL_FLOOR = 256 * 1024 * 1024;
333
+ const parseBufferPoolSize = (raw) => {
334
+ if (raw === undefined)
335
+ return undefined;
336
+ const normalized = raw.trim();
337
+ if (normalized.length === 0)
338
+ return undefined;
339
+ const parsed = Number(normalized);
340
+ if (!Number.isFinite(parsed) || parsed < 0)
341
+ return undefined;
342
+ return Math.floor(parsed);
343
+ };
344
+ /**
345
+ * The buffer-manager frame size compiled into every shipped `@ladybugdb/core`
346
+ * binary (`LBUG_PAGE_SIZE_LOG2 = 12` in the engine's CMake) — frames are 4 KiB
347
+ * on every platform, independent of the OS page size.
348
+ */
349
+ const LBUG_ASSUMED_FRAME_SIZE = 4096;
350
+ /**
351
+ * How much the OS page size amplifies buffer-pool consumption (#2631).
352
+ *
353
+ * LadybugDB's VM region charges pool budget per DISCARD GRANULE, not per
354
+ * frame: `discardGranuleSize = max(frameSize, osPageSize)` (vm_region.cpp),
355
+ * `claimFrame` bills the whole granule when its first 4 KiB frame becomes
356
+ * resident, and `releaseFrame` refunds only when the granule's LAST frame
357
+ * leaves. On a 64 KiB-page kernel (aarch64 openEuler — Ascend hosts) that is
358
+ * 16 frames per granule: scattered access is billed up to 16× its real bytes,
359
+ * and whole eviction passes can evict frames yet refund nothing — which is
360
+ * exactly the engine's "buffer pool is full and no memory could be freed"
361
+ * throw. Apple Silicon macOS (16 KiB pages) is the same mechanism at 4×.
362
+ *
363
+ * So the ANALYZE-path pool sizes (the per-element estimate, the COPY-safety
364
+ * floor, and the cap the hint is clamped against) are scaled by this ratio:
365
+ * the budget must cover worst-case granule charging or COPY dies on non-4K
366
+ * hosts with a pool that would be ample on x86. The hintless default
367
+ * (defaultBufferPoolSize — MCP serve, doctor, native-check) is deliberately
368
+ * NOT scaled: the pool is a native eager allocation committed at DB open
369
+ * (measured — see POOL_BYTES_PER_ELEMENT below), so scaling the global
370
+ * default would revert the #2557 OOM cap on every 16 KiB/64 KiB host. If the
371
+ * engine ever charges per-frame (or ships page-size-matched frames), this
372
+ * collapses back to 1 and the scaling disappears.
373
+ *
374
+ * Fail-safe: an undetectable page size (win32 — where the granule mechanism
375
+ * is absent anyway — or a failed `getconf`) means ratio 1, i.e. today's
376
+ * behavior.
377
+ */
378
+ const granuleRatio = (pageSize = (0, exports.getOsPageSize)()) => {
379
+ if (pageSize === undefined || !Number.isFinite(pageSize))
380
+ return 1;
381
+ return Math.max(1, Math.floor(pageSize / LBUG_ASSUMED_FRAME_SIZE));
382
+ };
383
+ exports.granuleRatio = granuleRatio;
384
+ /**
385
+ * Hintless pool default — MCP serve, doctor, native-check, any open without a
386
+ * per-run hint. Deliberately UNSCALED (#2557): the pool is an eager native
387
+ * allocation at DB open, so a page-size-scaled default would hand a
388
+ * long-lived `cgraph mcp` on a 16 KiB/64 KiB host up to 80% of RAM — the
389
+ * exact OOM exposure the 2 GiB cap was added to remove.
390
+ */
391
+ const defaultBufferPoolSize = () => Math.min(DEFAULT_BUFFER_POOL_CAP, Math.max(BUFFER_POOL_FLOOR, Math.floor(os_1.default.totalmem() * 0.8)));
392
+ /**
393
+ * Upper bound for the ANALYZE-path (hinted) pool: the #2557 cap scaled by the
394
+ * granule ratio, still bounded by 80% of RAM. Scaling only this bound — and
395
+ * not defaultBufferPoolSize — is what lets the #2631 fix take effect during
396
+ * the bulk COPY without touching hintless opens: with an unscaled cap the
397
+ * min() below would clamp the scaled COPY floor straight back to 2 GiB.
398
+ */
399
+ const scaledAnalyzePoolCap = (pageSize) => Math.min(DEFAULT_BUFFER_POOL_CAP * (0, exports.granuleRatio)(pageSize), Math.max(BUFFER_POOL_FLOOR, Math.floor(os_1.default.totalmem() * 0.8)));
400
+ /**
401
+ * Clamp an adaptive pool request to [ADAPTIVE_POOL_FLOOR × granuleRatio,
402
+ * scaledAnalyzePoolCap]. The lower bound keeps LadybugDB's COPY viable
403
+ * (scaled because the granule accounting inflates consumption on non-4K
404
+ * hosts, see granuleRatio); the upper bound means the hint can never exceed
405
+ * the page-size-scaled #2557 cap or 80% of RAM — and on a machine whose cap
406
+ * is below the COPY floor, the cap wins, so the pool is never over-committed.
407
+ * On 4 KiB hosts (ratio 1) this is byte-identical to clamping against the
408
+ * hintless default.
409
+ */
410
+ const clampBufferPool = (bytes, pageSize = (0, exports.getOsPageSize)()) => Math.min(scaledAnalyzePoolCap(pageSize), Math.max(ADAPTIVE_POOL_FLOOR * (0, exports.granuleRatio)(pageSize), Math.floor(bytes)));
411
+ /**
412
+ * Buffer-pool bytes to provision per graph element (node + relationship).
413
+ *
414
+ * The fixed 2 GiB default is far larger than most repos' working set, and
415
+ * LadybugDB eagerly commits the pool at DB open — measured: a full
416
+ * `analyze --force` of the GitNexus checkout takes ~51 s with the 2 GiB pool
417
+ * vs ~35 s with the ~414 MiB this factor yields (31% faster; the oversized
418
+ * pool's commit dominates). The pool is a page cache over the on-disk index,
419
+ * which scales with node/edge count, so a per-element budget sizes it to the
420
+ * repo. Kept generous so the whole index stays resident (no COPY thrash) and
421
+ * always clamped to at least ADAPTIVE_POOL_FLOOR; tuned by timing a real
422
+ * large-repo `analyze --force` at this factor vs a forced 2 GiB pool (the pool
423
+ * is a native eager allocation, measured with a real analyze, not a build-free
424
+ * bench — see the emit-path COPY timing note in bench/emit-persistence).
425
+ */
426
+ const POOL_BYTES_PER_ELEMENT = 4 * 1024;
427
+ /**
428
+ * Size the buffer pool to an estimated graph size (node + relationship count),
429
+ * clamped to [ADAPTIVE_POOL_FLOOR, scaledAnalyzePoolCap], with every term
430
+ * scaled by granuleRatio (#2631): on non-4K hosts the engine bills pool
431
+ * budget per OS-page-sized granule, so the same graph consumes up to
432
+ * pageSize/4096 × the budget it needs on x86. On 4 KiB hosts the ratio is 1
433
+ * and this is byte-identical to the pre-#2631 behavior. The estimate is never
434
+ * above the page-size-scaled #2557 cap bounded by 80% of RAM, never below the
435
+ * scaled COPY-safety floor; the hintless default stays unscaled.
436
+ *
437
+ * `pageSize` is a test seam (the pageSizeDoctorLines convention); production
438
+ * callers omit it and get the memoized real OS page size.
439
+ */
440
+ const estimateBufferPool = (graphElementCount, pageSize = (0, exports.getOsPageSize)()) => clampBufferPool(graphElementCount * POOL_BYTES_PER_ELEMENT * (0, exports.granuleRatio)(pageSize), pageSize);
441
+ exports.estimateBufferPool = estimateBufferPool;
442
+ /**
443
+ * Optional per-run buffer-pool size hint (bytes). The analyze orchestrator sets
444
+ * it once the graph size is known (after the pipeline, before the DB open) so
445
+ * the pool is sized to the repo instead of the fixed 2 GiB default, and clears
446
+ * it at run end. Non-analyze opens (MCP serve, `native-check` `:memory:`) never
447
+ * set it and keep the default.
448
+ */
449
+ let bufferPoolSizeHint;
450
+ /** Set (bytes) or clear (`undefined`) the per-run buffer-pool size hint. */
451
+ const setBufferPoolSizeHint = (bytes) => {
452
+ bufferPoolSizeHint = bytes;
453
+ };
454
+ exports.setBufferPoolSizeHint = setBufferPoolSizeHint;
455
+ /**
456
+ * Resolve the `bufferManagerSize` passed to every `new lbug.Database(...)`.
457
+ * `CGRAPH_LBUG_BUFFER_POOL_SIZE` (bytes) overrides everything; `0` is a
458
+ * deliberate escape hatch that restores LadybugDB's native unbounded
459
+ * 80%-of-RAM default. With no env override, a per-run `setBufferPoolSizeHint`
460
+ * (clamped to [floor, default]) sizes the pool to the repo; otherwise the
461
+ * default. Resolved at call time (not module load) so tests can stub the env
462
+ * var, the hint, and `os.totalmem`.
463
+ */
464
+ const resolveBufferManagerSize = () => {
465
+ const raw = process.env.CGRAPH_LBUG_BUFFER_POOL_SIZE;
466
+ if (raw === undefined) {
467
+ return bufferPoolSizeHint !== undefined
468
+ ? clampBufferPool(bufferPoolSizeHint)
469
+ : defaultBufferPoolSize();
470
+ }
471
+ const parsed = parseBufferPoolSize(raw);
472
+ if (parsed !== undefined)
473
+ return parsed;
474
+ // Non-empty but unparseable input: warn the operator and fall back —
475
+ // mirrors the CGRAPH_WAL_CHECKPOINT_THRESHOLD env path above.
476
+ if (raw.trim().length > 0) {
477
+ logger_js_1.logger.warn({ rawValue: raw, fallback: defaultBufferPoolSize() }, `Ignoring invalid CGRAPH_LBUG_BUFFER_POOL_SIZE=${raw}; expected integer >= 0 (bytes; 0 restores the native 80%-of-RAM default); falling back to the platform default pool size.`);
478
+ }
479
+ return defaultBufferPoolSize();
480
+ };
481
+ /**
482
+ * Doctor-facing view of the pool size the next Database open would get
483
+ * (#2631): env override > clamped hint > unscaled hintless default. Read-only;
484
+ * doctor prints it next to the page-size lines so support triage sees the
485
+ * sizing inputs at a glance. `0` is the pass-through sentinel for LadybugDB's
486
+ * native 80%-of-RAM default — callers must label it, not print "0 MiB".
487
+ */
488
+ const getEffectiveBufferPoolSize = () => resolveBufferManagerSize();
489
+ exports.getEffectiveBufferPoolSize = getEffectiveBufferPoolSize;
490
+ /**
491
+ * Matches the engine's buffer-pool exhaustion throw (buffer_manager.cpp:
492
+ * "Unable to allocate memory! The buffer pool is full and no memory could be
493
+ * freed!"). Distinct from isLbugPageSizeFrameError above, which matches the
494
+ * madvise/frame-release failure class.
495
+ */
496
+ const BUFFER_POOL_EXHAUSTION_RE = /buffer pool is full|unable to allocate memory/i;
497
+ const formatMiB = (bytes) => `${Math.round(bytes / (1024 * 1024))} MiB`;
498
+ /**
499
+ * Actionable remedy for a buffer-pool exhaustion error (#2631), or undefined
500
+ * when `message` is not that class. Cause → consequence → remedy, the
501
+ * diagnoseExtensionLoad convention: names the effective pool, the override
502
+ * knob, and — on non-4K hosts — the granule amplification that makes the
503
+ * budget exhaust early (the reporter's Ascend/aarch64 64 KiB kernel billed a
504
+ * pool up to 16× faster than the same analyze on x86).
505
+ */
506
+ const bufferPoolExhaustionRemedy = (message, pageSize = (0, exports.getOsPageSize)()) => {
507
+ if (!BUFFER_POOL_EXHAUSTION_RE.test(message))
508
+ return undefined;
509
+ const ratio = (0, exports.granuleRatio)(pageSize);
510
+ const pool = resolveBufferManagerSize();
511
+ // 0 is the pass-through sentinel (CGRAPH_LBUG_BUFFER_POOL_SIZE=0 →
512
+ // LadybugDB's native 80%-of-RAM default) — "0 MiB" would be nonsense in the
513
+ // very triage text this remedy exists to provide.
514
+ const poolLabel = pool === 0 ? "LadybugDB's native 80%-of-RAM default" : formatMiB(pool);
515
+ const pageNote = ratio > 1
516
+ ? ` This host's ${(pageSize ?? 0) / 1024} KiB OS page size makes the engine bill pool ` +
517
+ `memory in ${(pageSize ?? 0) / 1024} KiB granules — up to ${ratio}× faster budget use ` +
518
+ `than a 4 KiB-page host running the same analyze.`
519
+ : '';
520
+ return (`The LadybugDB buffer pool (${poolLabel}) was exhausted during the bulk COPY.` +
521
+ pageNote +
522
+ ` Set CGRAPH_LBUG_BUFFER_POOL_SIZE=<bytes> to raise it (e.g. ${4 * 1024 * 1024 * 1024}` +
523
+ ` for 4 GiB); 0 restores LadybugDB's native 80%-of-RAM default.`);
524
+ };
525
+ exports.bufferPoolExhaustionRemedy = bufferPoolExhaustionRemedy;
526
+ /** Matches WAL corruption errors from the LadybugDB engine. */
527
+ const WAL_CORRUPTION_RE = /corrupt(ed)?\s+wal|invalid\s+wal\s+record|wal.*corrupt|checksum.*wal/i;
528
+ exports.WAL_RECOVERY_SUGGESTION = 'WAL corruption detected. Run `cgraph analyze --force` to rebuild the index.';
529
+ function isWalCorruptionError(err) {
530
+ if (!err)
531
+ return false;
532
+ const msg = err instanceof Error ? err.message : String(err);
533
+ return WAL_CORRUPTION_RE.test(msg);
534
+ }
535
+ // ─── Ladybug WAL checkpoint IO error matchers ───────────────────────────────
536
+ //
537
+ // Matched against LadybugDB v0.18.0 (see `cgraph/package.json`
538
+ // @ladybugdb/core). Strict regexes encode local_file_system.cpp wording
539
+ // verified at that version. Two-tier strategy: strict matchers first so we
540
+ // only fire on real checkpoint-rotation shapes; a permissive fallback
541
+ // catches future Ladybug message drift so the recovery hint keeps surfacing
542
+ // even if upstream wording changes.
543
+ //
544
+ // From Ladybug native LocalFileSystem exceptions (`local_file_system.cpp`),
545
+ // surfaced in Node as:
546
+ // "Runtime exception: IO exception: Error renaming file ..."
547
+ // "Runtime exception: IO exception: Error removing directory or file ..."
548
+ // We only match checkpoint-rotation shapes:
549
+ // - "<db>.wal -> <db>.wal.checkpoint" rename failures
550
+ // - "<db>.wal.checkpoint" remove failures
551
+ // Example matches:
552
+ // "Runtime exception: IO exception: Error renaming file /x/lbug.wal to /x/lbug.wal.checkpoint. ErrorMessage: Permission denied"
553
+ // "Runtime exception: IO exception: Error removing directory or file /x/lbug.wal.checkpoint. Error Message: Permission denied"
554
+ // Matching is case-insensitive to remain robust across wrappers/platforms.
555
+ const LBUG_CHECKPOINT_RENAME_RE = /^runtime exception: io exception:\s*error renaming file\s+.+?\.wal\s+to\s+.+?\.wal\.checkpoint(?:\.|\s|$)/i;
556
+ const LBUG_CHECKPOINT_REMOVE_RE = /^runtime exception: io exception:\s*error removing directory or file\s+.+?\.wal\.checkpoint(?:\.|\s|$)/i;
557
+ /**
558
+ * Permissive fallback: any IO-exception-shaped message that mentions a
559
+ * `.wal.checkpoint` path. Catches future Ladybug message drift (different
560
+ * verb, additional preamble, locale variation) so the recovery hint keeps
561
+ * surfacing even if the strict regexes go stale.
562
+ */
563
+ const LBUG_CHECKPOINT_PERMISSIVE_RE = /io exception.*\.wal\.checkpoint/i;
564
+ /**
565
+ * True when `err` looks like a Ladybug WAL-checkpoint rotation/remove IO
566
+ * failure. Tries strict matchers first (renames + removes), then falls
567
+ * back to the permissive matcher.
568
+ */
569
+ const isLbugCheckpointIoError = (err) => {
570
+ if (!err)
571
+ return false;
572
+ const msg = err instanceof Error ? err.message : String(err);
573
+ if (LBUG_CHECKPOINT_RENAME_RE.test(msg) || LBUG_CHECKPOINT_REMOVE_RE.test(msg))
574
+ return true;
575
+ return LBUG_CHECKPOINT_PERMISSIVE_RE.test(msg);
576
+ };
577
+ exports.isLbugCheckpointIoError = isLbugCheckpointIoError;
578
+ // ─── Ladybug non-4K page-size frame-release matcher (#1231) ─────────────────
579
+ //
580
+ // LadybugDB <= 0.17.x hardcoded a 4 KiB OS-page assumption in its buffer
581
+ // manager: evicting a frame released physical memory with
582
+ // `madvise(frame, frameSize, MADV_DONTNEED)` on 4 KiB-aligned frame
583
+ // addresses (verified by disassembling `VMRegion::releaseFrame` in
584
+ // @ladybugdb/core-linux-arm64 0.17.1 — `mov w2, #0x4` = MADV_DONTNEED,
585
+ // throw on non-zero return). On kernels with 16 KiB pages (Raspberry Pi 5
586
+ // default 2712 kernel, Asahi Linux) or 64 KiB pages (some enterprise arm64
587
+ // distros), madvise rejects addresses that are not multiples of the real
588
+ // page size with EINVAL, surfacing as:
589
+ // "Buffer manager exception: Releasing physical memory associated with a
590
+ // frame failed with error code -1: Invalid argument."
591
+ // which aborts `cgraph analyze` mid-COPY.
592
+ //
593
+ // @ladybugdb/core 0.18.0 rewrote the release path with runtime OS-page-size
594
+ // detection and discard-granule-aligned madvise (new binary strings:
595
+ // "Failed to detect the operating system page size.", "Unsupported page
596
+ // size combination: frame size {}, discard granule size {}, frame group
597
+ // size {}."), so upgrading is the fix. The residual 0.18.0 guard
598
+ // ("Unsupported page size combination") is matched here too so exotic
599
+ // configurations receive the same actionable guidance instead of a raw
600
+ // native message.
601
+ const LBUG_FRAME_RELEASE_RE = /releasing physical memory associated with a frame failed/i;
602
+ const LBUG_PAGE_COMBO_RE = /unsupported page size combination/i;
603
+ /**
604
+ * True when `err` looks like the LadybugDB buffer manager failing to release
605
+ * frame memory — the failure mode of a 4 KiB page-size assumption on a
606
+ * 16 KiB/64 KiB-page kernel (#1231). Deliberately does NOT match the
607
+ * generic "buffer pool is full" exhaustion error: that one is handled as a
608
+ * SIZING problem — though since #2631 we know page size drives sizing too
609
+ * (the engine bills pool budget per OS-page-sized discard granule, so non-4K
610
+ * hosts exhaust the same budget up to pageSize/4096× earlier; see
611
+ * granuleRatio, which scales the pool accordingly, and
612
+ * bufferPoolExhaustionRemedy, which explains it to the operator).
613
+ */
614
+ const isLbugPageSizeFrameError = (err) => {
615
+ if (!err)
616
+ return false;
617
+ const msg = err instanceof Error ? err.message : String(err);
618
+ return LBUG_FRAME_RELEASE_RE.test(msg) || LBUG_PAGE_COMBO_RE.test(msg);
619
+ };
620
+ exports.isLbugPageSizeFrameError = isLbugPageSizeFrameError;
621
+ /**
622
+ * True when the given `@ladybugdb/core` version contains the runtime
623
+ * OS-page-size detection introduced in 0.18.0 (see the matcher comment
624
+ * above). Unknown/unparseable versions return false so callers err on the
625
+ * side of showing the upgrade hint.
626
+ */
627
+ const isPageSizeAwareLadybug = (version) => {
628
+ if (!version)
629
+ return false;
630
+ const m = /^(\d+)\.(\d+)/.exec(version.trim());
631
+ if (!m)
632
+ return false;
633
+ const major = Number(m[1]);
634
+ const minor = Number(m[2]);
635
+ return major > 0 || minor >= 18;
636
+ };
637
+ exports.isPageSizeAwareLadybug = isPageSizeAwareLadybug;
638
+ // `undefined` = not probed yet; `null` = probed and unavailable. Cached
639
+ // because analyze error paths and doctor may both ask, and getconf forks.
640
+ let cachedOsPageSize;
641
+ /**
642
+ * Test seam (the `_captureLogger` convention): pin the memoized OS page size
643
+ * so sizing tests are host-independent — without this they would silently
644
+ * drift on 16 KiB-page Apple Silicon runners. `number` pins a value, `null`
645
+ * pins "undetectable", `undefined` clears the memo so the next call re-probes.
646
+ */
647
+ const _setOsPageSizeForTests = (pageSize) => {
648
+ cachedOsPageSize = pageSize;
649
+ };
650
+ exports._setOsPageSizeForTests = _setOsPageSizeForTests;
651
+ /**
652
+ * OS memory page size in bytes, or `undefined` when it cannot be determined
653
+ * (Windows, missing getconf, sandboxed exec). Node exposes no page-size API,
654
+ * so this shells out to POSIX `getconf PAGE_SIZE` — same execFileSync shape
655
+ * as the Windows 8.3 short-path probe above, but with a tighter timeout and
656
+ * an explicit killSignal (see the options comment below).
657
+ */
658
+ const getOsPageSize = () => {
659
+ if (cachedOsPageSize !== undefined)
660
+ return cachedOsPageSize ?? undefined;
661
+ if (process.platform === 'win32') {
662
+ // Windows allocation granularity is not what madvise alignment is about;
663
+ // the #1231 failure mode is POSIX-only.
664
+ cachedOsPageSize = null;
665
+ return undefined;
666
+ }
667
+ try {
668
+ // killSignal SIGKILL (first use in this repo): the default SIGTERM is
669
+ // catchable, so a signal-trapping child held the "5s" timeout for 9s in
670
+ // review reproduction — SIGKILL makes the timeout real for everything
671
+ // except a child stuck in uninterruptible I/O (D state). 2000ms, not
672
+ // 5000: doctor runs this probe on its happy path and real getconf
673
+ // answers in ~2ms, but keep margin for loaded Pi-class hardware — a
674
+ // too-tight ceiling would silently drop the very #1231 diagnostics this
675
+ // probe exists to provide (the catch caches the failure). (#2424 review)
676
+ const out = (0, child_process_1.execFileSync)('getconf', ['PAGE_SIZE'], {
677
+ encoding: 'utf-8',
678
+ timeout: 2000,
679
+ killSignal: 'SIGKILL',
680
+ stdio: ['ignore', 'pipe', 'pipe'],
681
+ });
682
+ const parsed = Number(out.trim());
683
+ cachedOsPageSize = Number.isInteger(parsed) && parsed > 0 ? parsed : null;
684
+ }
685
+ catch {
686
+ cachedOsPageSize = null;
687
+ }
688
+ return cachedOsPageSize ?? undefined;
689
+ };
690
+ exports.getOsPageSize = getOsPageSize;
691
+ /**
692
+ * Return true when the error message indicates that a LadybugDB write
693
+ * transaction could not proceed due to lock contention — either a file
694
+ * lock that could not be acquired (either at construction time,
695
+ * `new lbug.Database(...)` raising from `local_file_system.cpp`, or during
696
+ * a query, another writer holds the exclusive lock), or a same-process
697
+ * write transaction rejected because another write transaction is already
698
+ * active on the connection.
699
+ *
700
+ * Lives here (not in `lbug-adapter.ts`) so both the construction-time
701
+ * retry (`openWithLockRetry` in this file) and the query-time retry
702
+ * (`withLbugDb` in `lbug-adapter.ts`) consult the same matcher. Callers
703
+ * import directly from this module — no re-export to keep in sync.
704
+ */
705
+ const isDbBusyError = (err) => {
706
+ const msg = (err instanceof Error ? err.message : String(err)).toLowerCase();
707
+ // `lock` already subsumes `could not set lock`; the broader term is kept
708
+ // because graph-DB transient errors include "deadlock", "lock contention",
709
+ // and the LadybugDB native module's "could not set lock on file" — all of
710
+ // which deserve a retry. LadybugDB also reports same-process writer
711
+ // contention without the words "busy" or "lock".
712
+ //
713
+ // "only one write transaction at a time" was observed against LadybugDB
714
+ // 0.18.0 (see cgraph/package.json @ladybugdb/core).
715
+ //
716
+ // If a non-transient lock-shaped error ever surfaces (e.g., "lock file
717
+ // missing" during recovery), tighten this matcher rather than raising the
718
+ // retry budget.
719
+ return (msg.includes('busy') ||
720
+ msg.includes('lock') ||
721
+ msg.includes('already in use') ||
722
+ msg.includes('only one write transaction at a time'));
723
+ };
724
+ exports.isDbBusyError = isDbBusyError;
725
+ /**
726
+ * True when a WAL-checkpoint IO error ALSO carries a busy/lock signal — the
727
+ * rotation failed because another handle (a `cgraph mcp` server, or this
728
+ * process's own reader) holds the store's WAL open, rather than a permanent
729
+ * disk error. Reuses `isDbBusyError`'s already-tested keyword set instead of a
730
+ * fresh regex, so an unmatched message degrades to "IO error" rather than
731
+ * silently claiming a held-open cause. (#2599)
732
+ */
733
+ const isLbugCheckpointBusyError = (err) => {
734
+ if (!(0, exports.isLbugCheckpointIoError)(err))
735
+ return false;
736
+ // Anchor to real held-open wording rather than isDbBusyError's broad
737
+ // `.includes('lock')`, which matches the DB PATH embedded in the checkpoint
738
+ // error message (e.g. a repo under `blockchain-app`) and would misclassify a
739
+ // pure disk fault as held-open (#2614 LOW).
740
+ const msg = (err instanceof Error ? err.message : String(err)).toLowerCase();
741
+ return (msg.includes('could not set lock') ||
742
+ msg.includes('lock is held') ||
743
+ msg.includes('being used by another process') ||
744
+ msg.includes('is busy'));
745
+ };
746
+ exports.isLbugCheckpointBusyError = isLbugCheckpointBusyError;
747
+ /**
748
+ * Classify an error thrown while clearing all relationships of one type
749
+ * before an incremental re-write (`deleteAllRelationshipsOfType` in
750
+ * `lbug-adapter.ts` — the `deleteAllInjects` / `deleteAllCallSummaries` /
751
+ * `deleteAllInterprocTaintPaths` family).
752
+ *
753
+ * - `'benign-missing-table'`: the CodeRelation table does not exist yet
754
+ * (freshly-initialized DB) — the delete-all is a no-op, stay silent.
755
+ * - `'rethrow'`: ANY other failure (lock, disk, closed connection, native
756
+ * error) leaves stale rows that the subsequent re-extract then DUPLICATES
757
+ * (CodeRelation has no PK), so the caller must abort the writeback
758
+ * (#2084 review P2-5).
759
+ *
760
+ * Pure classification, extracted here (next to the other error matchers) so
761
+ * the load-bearing regex/branch is unit-testable without a native DB —
762
+ * driving a synthetic failure through the real singleton connection would
763
+ * break every later test in the shared integration suite (#2200 review).
764
+ */
765
+ const classifyDeleteAllError = (err) => {
766
+ const msg = err instanceof Error ? err.message : String(err);
767
+ return /no table|not exist|not found|does not exist|Table .* does not exist/i.test(msg)
768
+ ? 'benign-missing-table'
769
+ : 'rethrow';
770
+ };
771
+ exports.classifyDeleteAllError = classifyDeleteAllError;
772
+ function createLbugDatabase(lbugModule, databasePath, options = {}) {
773
+ // .d.ts declares fewer args than the native constructor accepts.
774
+ return new lbugModule.Database(databasePath, resolveBufferManagerSize(), // bufferManagerSize (#2557: default min(2 GiB, 80% RAM); CGRAPH_LBUG_BUFFER_POOL_SIZE overrides; 0 restores the native 80%-of-RAM default)
775
+ false, // enableCompression (pinned for v0.16.0)
776
+ options.readOnly ?? false, exports.LBUG_MAX_DB_SIZE, true, // autoCheckpoint (always on)
777
+ resolveCheckpointThreshold(), // checkpointThreshold (default 64 MiB; override with CGRAPH_WAL_CHECKPOINT_THRESHOLD; -1 keeps Ladybug stock ~16 MiB)
778
+ options.throwOnWalReplayFailure ?? true, true);
779
+ }
780
+ // ─── Lock-busy retry tuning knobs ───────────────────────────────────────────
781
+ //
782
+ // All four GitNexus retry pairs that touch native LadybugDB locks live with
783
+ // a comment cross-reference here so an SRE tuning Windows flakes finds them
784
+ // in one grep:
785
+ //
786
+ // 1. OPEN_LOCK_RETRY_ATTEMPTS / OPEN_LOCK_RETRY_DELAY_MS (this file)
787
+ // → `new lbug.Database()` constructor lock failures
788
+ // 2. HANDLE_RELEASE_PROBE_ATTEMPTS / HANDLE_RELEASE_PROBE_DELAY_MS (this file)
789
+ // → post-close fs.open probe to absorb Windows handle-release lag; also
790
+ // the shared budget for wipeLbugDbFiles' ENOENT-verified removal
791
+ // (lbug-adapter.ts) and the dirty-recovery sidecar park's
792
+ // rename/rm retries (sidecar-recovery.ts) — same lock class
793
+ // 3. DB_LOCK_RETRY_ATTEMPTS / DB_LOCK_RETRY_DELAY_MS (lbug-adapter.ts withLbugDb)
794
+ // → query-time busy/lock retry around already-open connections
795
+ //
796
+ // `new lbug.Database()` calls into the native module which performs an
797
+ // OS-level exclusive lock on `<dbPath>`. On Windows that lock can fail
798
+ // for reasons specific to the OS (Defender briefly opens new files,
799
+ // libuv handle release lags the JS-side close). 5 attempts × 100ms
800
+ // linear back-off (max sleep 100+200+300+400 = 1s, plus 5 ctor RTTs
801
+ // of 10–50ms each = ~1.0–1.2s worst case) clears the typical
802
+ // AV-scanner hold without masking real cross-process conflicts.
803
+ //
804
+ // Source: https://github.com/LadybugDB/ladybug/blob/v0.18.0/src/common/file_system/local_file_system.cpp#L127
805
+ // (v0.18.0 appends " (Error: <code>)" / " (Lock is held by PID X)" on POSIX,
806
+ // but the "Could not set lock on file : " prefix `isDbBusyError` substring-
807
+ // matches on is unchanged.)
808
+ const OPEN_LOCK_RETRY_ATTEMPTS = 5;
809
+ const OPEN_LOCK_RETRY_DELAY_MS = 100;
810
+ // Exported (this shipping review, FIX 1/2): the dirty-recovery sidecar park
811
+ // (sidecar-recovery.ts) and the ENOENT-verified wipe (lbug-adapter.ts
812
+ // wipeLbugDbFiles) retry the SAME Windows handle-release/AV lock class, and
813
+ // their previous private mirror constants were documentation-coupled copies
814
+ // that could drift from this tuning-knob registry silently.
815
+ exports.HANDLE_RELEASE_PROBE_ATTEMPTS = 5;
816
+ exports.HANDLE_RELEASE_PROBE_DELAY_MS = 50;
817
+ const HANDLE_RELEASE_LOCK_CODES = new Set(['EBUSY', 'EPERM', 'EACCES']);
818
+ // Retry-budget registry, part 2 (retry-budget consolidation): the remaining
819
+ // open-time lock retries live next to their call sites but are catalogued here
820
+ // so all lbug retry budgets surface in one grep. They retry the same lock class
821
+ // as 1–3 ("Could not set lock" while a writer rebuilds the index):
822
+ // 4. LOCK_RETRY_ATTEMPTS / LOCK_RETRY_DELAY_MS (pool-adapter.ts)
823
+ // → read pool's read-only open while `cgraph analyze` is writing
824
+ // (3 attempts, linear 2s·n back-off ≈ 6s total)
825
+ // 5. LBUG_OPEN_RETRY_ATTEMPTS / _BASE_MS / _MAX_MS (group/bridge-db.ts)
826
+ // → cross-repo bridge RO open race (10 attempts, linear 100ms·n capped
827
+ // at 500ms ≈ 3.5s total)
828
+ // Kept in-file (not moved here) so explicit `lbug-config` test mocks don't have
829
+ // to enumerate them; change a budget in its call site and update this catalogue.
830
+ /**
831
+ * Test-fixture directory prefixes recognized by `isTestFixturePath`.
832
+ *
833
+ * IMPORTANT: this list must stay in sync with the prefixes passed to
834
+ * `createTempDir` in `cgraph/test/helpers/test-db.ts` and the prefixes
835
+ * used by `withTestLbugDB` (`cgraph/test/helpers/test-indexed-db.ts`).
836
+ * If you add a new test that passes a custom prefix to `createTempDir`,
837
+ * add it here too — otherwise the stale-sidecar sweep silently won't
838
+ * fire for that fixture and CI flakes return.
839
+ *
840
+ * The default `createTempDir('gitnexus-test-')` and the lbug variant
841
+ * `'gitnexus-lbug-'` cover today's call sites.
842
+ */
843
+ const TEST_FIXTURE_PREFIXES = ['gitnexus-lbug-', 'gitnexus-test-'];
844
+ /**
845
+ * Marker symbol attached to lock errors after `openWithLockRetry` exhausts
846
+ * its budget. `withLbugDb`'s outer query-time retry consults this so it
847
+ * does not re-retry a path that just spent up to ~1.5s in the open-time
848
+ * loop — preventing 6s tail latencies (3× outer × 5× inner attempts).
849
+ *
850
+ * The symbol is internal to GitNexus; consumers should treat the underlying
851
+ * error message as the user-visible signal.
852
+ */
853
+ exports.LBUG_OPEN_RETRY_EXHAUSTED = Symbol.for('gitnexus.lbug.openRetryExhausted');
854
+ const isOpenRetryExhausted = (err) => {
855
+ if (err === null || err === undefined || typeof err !== 'object')
856
+ return false;
857
+ return err[exports.LBUG_OPEN_RETRY_EXHAUSTED] === true;
858
+ };
859
+ exports.isOpenRetryExhausted = isOpenRetryExhausted;
860
+ const tagOpenRetryExhausted = (err) => {
861
+ if (err && typeof err === 'object') {
862
+ err[exports.LBUG_OPEN_RETRY_EXHAUSTED] = true;
863
+ }
864
+ return err;
865
+ };
866
+ /**
867
+ * True when `dbPath` resolves to a recognized test fixture under the OS
868
+ * temp directory. Used to gate the stale-sidecar sweep so production
869
+ * paths never have their `.wal` / `.lock` files deleted.
870
+ *
871
+ * Defensive shape:
872
+ * - `path.resolve` normalizes `..` segments before the prefix check, so
873
+ * `<tmp>/gitnexus-lbug-x/../../etc/passwd` is rejected.
874
+ * - The tmpRoot check trims any trailing separator returned by some
875
+ * Windows TMP configurations (`C:\Users\X\Temp\`) so the startsWith
876
+ * comparison stays correct.
877
+ * - Only the IMMEDIATE parent directory is matched against the prefix
878
+ * list. An ancestor walk would let a tmpdir whose own basename starts
879
+ * with `gitnexus-lbug-` accept arbitrary nested paths under it.
880
+ */
881
+ const isTestFixturePath = (dbPath) => {
882
+ const tmpRoot = os_1.default.tmpdir().replace(new RegExp(`${path_1.default.sep === '\\' ? '\\\\' : path_1.default.sep}+$`), '');
883
+ const resolved = path_1.default.resolve(dbPath);
884
+ if (!resolved.startsWith(tmpRoot + path_1.default.sep) && resolved !== tmpRoot)
885
+ return false;
886
+ const parentBase = path_1.default.basename(path_1.default.dirname(resolved));
887
+ return TEST_FIXTURE_PREFIXES.some((p) => parentBase.startsWith(p));
888
+ };
889
+ /** Exported only for direct unit testing — production callers use `openWithLockRetry`. */
890
+ exports._isTestFixturePathForTest = isTestFixturePath;
891
+ // Exported alongside HANDLE_RELEASE_PROBE_* (this shipping review, FIX 1/2)
892
+ // so the consumers of the shared retry budget do not each grow a private copy.
893
+ const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
894
+ exports.sleep = sleep;
895
+ /**
896
+ * Attempt to remove stale `.wal` / `.lock` sidecars that a previous aborted
897
+ * test run may have left behind. Best-effort: ENOENT is normal, anything
898
+ * else is swallowed so the caller's retry can surface the original error.
899
+ */
900
+ const sweepStaleSidecars = async (dbPath) => {
901
+ for (const suffix of ['.wal', '.lock']) {
902
+ try {
903
+ await promises_1.default.unlink(dbPath + suffix);
904
+ }
905
+ catch {
906
+ /* missing sidecar or permission error — let the open retry surface it */
907
+ }
908
+ }
909
+ };
910
+ /**
911
+ * Run `construct` with bounded retries when `new lbug.Database(...)` throws
912
+ * a busy/lock error. The original (loop-captured) error is preferred over
913
+ * any post-sweep error so triage sees the real LadybugDB lock message.
914
+ * On exhaustion the rethrown error is tagged via
915
+ * `LBUG_OPEN_RETRY_EXHAUSTED` so the outer query-time retry in
916
+ * `withLbugDb` skips re-retrying a freshly-exhausted path.
917
+ */
918
+ const openWithLockRetry = async (construct, dbPath) => {
919
+ let originalLockError;
920
+ for (let attempt = 1; attempt <= OPEN_LOCK_RETRY_ATTEMPTS; attempt++) {
921
+ try {
922
+ return construct();
923
+ }
924
+ catch (err) {
925
+ if (!(0, exports.isDbBusyError)(err))
926
+ throw err;
927
+ originalLockError = err;
928
+ if (attempt === OPEN_LOCK_RETRY_ATTEMPTS)
929
+ break;
930
+ await (0, exports.sleep)(OPEN_LOCK_RETRY_DELAY_MS * attempt);
931
+ }
932
+ }
933
+ // Final defense: only for recognized test fixtures, sweep stale sidecars
934
+ // (a prior aborted test run can leave a `.wal` lock that survives the
935
+ // tmp dir cleanup). Production paths never reach this branch — the guard
936
+ // requires the immediate parent dir to match a test prefix AND the
937
+ // resolved path to live under the OS temp directory.
938
+ if (isTestFixturePath(dbPath)) {
939
+ await sweepStaleSidecars(dbPath);
940
+ try {
941
+ return construct();
942
+ }
943
+ catch {
944
+ // Intentionally do NOT overwrite originalLockError. The user-actionable
945
+ // signal is "we exhausted lock retries" — a different error from the
946
+ // post-sweep attempt is less useful than the lock failure that drove
947
+ // the sweep in the first place.
948
+ }
949
+ }
950
+ throw tagOpenRetryExhausted(originalLockError);
951
+ };
952
+ async function openLbugConnection(lbugModule, databasePath, options = {}) {
953
+ const safePath = toNativeSafePath(databasePath);
954
+ let db;
955
+ try {
956
+ db = await openWithLockRetry(() => createLbugDatabase(lbugModule, safePath, options), safePath);
957
+ return { db, conn: new lbugModule.Connection(db) };
958
+ }
959
+ catch (err) {
960
+ if (db)
961
+ await db.close().catch(() => { });
962
+ throw err;
963
+ }
964
+ }
965
+ async function closeLbugConnection(handle) {
966
+ await handle.conn.close().catch(() => { });
967
+ await handle.db.close().catch(() => { });
968
+ }
969
+ /**
970
+ * Probe `dbPath` AND its `.wal` sidecar after `db.close()` so any
971
+ * residual native file handle surfaces as EBUSY/EPERM/EACCES and the
972
+ * bounded retry absorbs the release lag. Windows-only — Linux/macOS do
973
+ * not exhibit this race.
974
+ *
975
+ * Both files matter. Empirically, on rapid open→close→reopen cycles the
976
+ * main `dbPath` handle releases first; the `.wal` handle from the
977
+ * previous Database lingers and the new Database's first write (CREATE
978
+ * NODE TABLE during schema init) fails with "Could not set lock on
979
+ * file". Probing both makes safeClose actually return when the kernel
980
+ * is fully done with the path.
981
+ *
982
+ * Returns `true` when both probes succeeded (or skipped on non-lock
983
+ * errors / missing files). Returns `false` when either probe exhausted
984
+ * its budget with a lock code still in flight.
985
+ *
986
+ * Defensive shape:
987
+ * - Opens read+write (`'r+'`) so the probe actually surfaces exclusive
988
+ * locks held by the previous Database. A read-only probe (`'r'`) is
989
+ * insufficient — Windows will grant read access while the previous
990
+ * handle's exclusive write lock is still in flight, which lets
991
+ * `safeClose` return before the next CREATE NODE TABLE can lock the
992
+ * file.
993
+ * - `try/finally` around `handle.close()` guarantees no fd leak even
994
+ * if close itself throws.
995
+ */
996
+ const waitForWindowsHandleRelease = async (dbPath) => {
997
+ const mainReleased = await probeSinglePath(dbPath);
998
+ const walReleased = await probeSinglePath(dbPath + '.wal');
999
+ return mainReleased && walReleased;
1000
+ };
1001
+ exports.waitForWindowsHandleRelease = waitForWindowsHandleRelease;
1002
+ const probeSinglePath = async (filePath) => {
1003
+ for (let attempt = 1; attempt <= exports.HANDLE_RELEASE_PROBE_ATTEMPTS; attempt++) {
1004
+ let handle;
1005
+ try {
1006
+ handle = await promises_1.default.open(filePath, 'r+');
1007
+ return true;
1008
+ }
1009
+ catch (err) {
1010
+ const code = err?.code;
1011
+ if (!code || !HANDLE_RELEASE_LOCK_CODES.has(code))
1012
+ return true; // ENOENT / unrelated → not our problem
1013
+ if (attempt === exports.HANDLE_RELEASE_PROBE_ATTEMPTS)
1014
+ return false;
1015
+ await (0, exports.sleep)(exports.HANDLE_RELEASE_PROBE_DELAY_MS * attempt);
1016
+ }
1017
+ finally {
1018
+ if (handle) {
1019
+ try {
1020
+ await handle.close();
1021
+ }
1022
+ catch {
1023
+ /* swallow — caller cannot do anything useful with a probe-close failure */
1024
+ }
1025
+ }
1026
+ }
1027
+ }
1028
+ return false;
1029
+ };