@backbencher/brain 0.0.0-stage → 0.1.1

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 (319) hide show
  1. package/CHANGELOG.md +298 -0
  2. package/EMBEDDINGS.md +355 -0
  3. package/LICENSE +21 -0
  4. package/README.md +415 -2
  5. package/bin/bb +13 -0
  6. package/dist/analysis-exclusions-7ZJDXOVZ.js +35 -0
  7. package/dist/brain-index-health-Q5APTJQL.js +17 -0
  8. package/dist/brain-relationship-enrichment-MYR2AM4F.js +558 -0
  9. package/dist/brain.sql-EIM4WS4D.js +29 -0
  10. package/dist/chunk-22V37YTK.js +1758 -0
  11. package/dist/chunk-2BSKD7O3.js +40 -0
  12. package/dist/chunk-2DE27DVC.js +1314 -0
  13. package/dist/chunk-2RRBMNBQ.js +322 -0
  14. package/dist/chunk-2WXYNLBA.js +29 -0
  15. package/dist/chunk-3CTFIJJB.js +17 -0
  16. package/dist/chunk-3ZTOHHSW.js +2104 -0
  17. package/dist/chunk-4H22TLOT.js +543 -0
  18. package/dist/chunk-5BVAH26D.js +340 -0
  19. package/dist/chunk-62DHLYW6.js +3427 -0
  20. package/dist/chunk-7AN7U5IZ.js +371 -0
  21. package/dist/chunk-7DRPNVIN.js +782 -0
  22. package/dist/chunk-7MBYT777.js +174 -0
  23. package/dist/chunk-AHDWGM7Q.js +236 -0
  24. package/dist/chunk-B5GEAAYF.js +818 -0
  25. package/dist/chunk-BEIZZ73B.js +1479 -0
  26. package/dist/chunk-BQ3OVQ3P.js +125 -0
  27. package/dist/chunk-D2Q4Y47A.js +53 -0
  28. package/dist/chunk-DIYAGQJL.js +34 -0
  29. package/dist/chunk-DWKXZ6IF.js +336 -0
  30. package/dist/chunk-DYM4FQEE.js +90 -0
  31. package/dist/chunk-ENW4BTBA.js +930 -0
  32. package/dist/chunk-EWMWK7WN.js +75 -0
  33. package/dist/chunk-EY5ZZUUA.js +626 -0
  34. package/dist/chunk-GBI7V7KY.js +69 -0
  35. package/dist/chunk-GEFFO6O2.js +152 -0
  36. package/dist/chunk-HJEWO5EV.js +247 -0
  37. package/dist/chunk-HQSPJDHI.js +613 -0
  38. package/dist/chunk-KAET47ZL.js +125 -0
  39. package/dist/chunk-KCDECRJY.js +440 -0
  40. package/dist/chunk-L5TDYKYK.js +76 -0
  41. package/dist/chunk-MLKGABMK.js +9 -0
  42. package/dist/chunk-NO3U3FJQ.js +201 -0
  43. package/dist/chunk-OWISBAOF.js +61 -0
  44. package/dist/chunk-QKTRECYS.js +1119 -0
  45. package/dist/chunk-QLK6ED4Q.js +235 -0
  46. package/dist/chunk-R2GW4F6R.js +19 -0
  47. package/dist/chunk-RCMTFSEF.js +87 -0
  48. package/dist/chunk-RM3PY6TG.js +376 -0
  49. package/dist/chunk-ROMM6KMC.js +433 -0
  50. package/dist/chunk-SGGCSHAX.js +12050 -0
  51. package/dist/chunk-SK6YVHFZ.js +211 -0
  52. package/dist/chunk-SM7RFQRO.js +214 -0
  53. package/dist/chunk-UGR4QIGS.js +67 -0
  54. package/dist/chunk-UQNQZXHY.js +711 -0
  55. package/dist/chunk-UUNHHX4M.js +13 -0
  56. package/dist/chunk-VL52PL2T.js +71 -0
  57. package/dist/chunk-WIG36E67.js +196 -0
  58. package/dist/chunk-XHK3WWGB.js +7436 -0
  59. package/dist/chunk-XTQM2IP3.js +2863 -0
  60. package/dist/chunk-ZE2LG76D.js +1296 -0
  61. package/dist/chunk-ZETTGPAW.js +6950 -0
  62. package/dist/cli/index.js +37 -0
  63. package/dist/config-HZAAYDP3.js +10 -0
  64. package/dist/content-search-7XIP555Q.js +593 -0
  65. package/dist/database-76RP44JG.js +9 -0
  66. package/dist/doctor-ANGETYMN.js +395 -0
  67. package/dist/edit-engine-CG72LDZD.js +51 -0
  68. package/dist/engine-BKEOGN7N.js +11 -0
  69. package/dist/engine-VIW6NSKO.js +18 -0
  70. package/dist/fingerprint-OBLIMZLP.js +33 -0
  71. package/dist/framework-intelligence-3LORTPOX.js +860 -0
  72. package/dist/freshness-3K6VU5OT.js +174 -0
  73. package/dist/graph-engine-HBSQNPTB.js +21 -0
  74. package/dist/graph_request-Q6NKB6N2.js +350 -0
  75. package/dist/impact_request-LYP672WE.js +68 -0
  76. package/dist/index-space-IUUN5WYV.js +15 -0
  77. package/dist/index-status-7OVGYSGW.js +34 -0
  78. package/dist/index.js +159 -0
  79. package/dist/instance-FO6QZRLH.js +19 -0
  80. package/dist/language-detection-DFCAU5DZ.js +11 -0
  81. package/dist/lsp/server.js +4301 -0
  82. package/dist/mcp/server.js +132 -0
  83. package/dist/onboard-DIQZV2NW.js +161 -0
  84. package/dist/override-companion-pass-XR7MHTP7.js +117 -0
  85. package/dist/parallel-indexer-FK2XKZXY.js +88 -0
  86. package/dist/pool-worker.js +1153 -0
  87. package/dist/project-health-6XPENVAA.js +94 -0
  88. package/dist/project-index-5SDPHITE.js +57 -0
  89. package/dist/project-registry-ZJ3DVUGO.js +355 -0
  90. package/dist/real-bash-analyzer-EJAU5LW5.js +2201 -0
  91. package/dist/real-c-analyzer-HBD3FNNH.js +5942 -0
  92. package/dist/real-clean-analyzer-4EEZLPV5.js +3470 -0
  93. package/dist/real-clojure-analyzer-Q55EBOO2.js +2818 -0
  94. package/dist/real-cpp-analyzer-IVVOD25R.js +4101 -0
  95. package/dist/real-csharp-analyzer-ZBNLNJZJ.js +3298 -0
  96. package/dist/real-css-analyzer-6XRQLUN7.js +15 -0
  97. package/dist/real-dart-analyzer-OLR72EFW.js +3944 -0
  98. package/dist/real-elixir-analyzer-MQWGAH2I.js +2192 -0
  99. package/dist/real-erlang-analyzer-7BVPQEHO.js +1731 -0
  100. package/dist/real-fsharp-analyzer-C2UPFNOA.js +2390 -0
  101. package/dist/real-go-analyzer-UKGI43YS.js +4126 -0
  102. package/dist/real-graphql-analyzer-VE2EEFII.js +1442 -0
  103. package/dist/real-groovy-analyzer-W26VACFW.js +2285 -0
  104. package/dist/real-haskell-analyzer-5CVVAJRX.js +2533 -0
  105. package/dist/real-hcl-analyzer-5ZT4U43N.js +725 -0
  106. package/dist/real-html-analyzer-JWNX3C6I.js +1759 -0
  107. package/dist/real-java-analyzer-GU42VBGQ.js +4677 -0
  108. package/dist/real-javascript-analyzer-QA4QOJ6W.js +14 -0
  109. package/dist/real-json-analyzer-MPA6PRXL.js +1640 -0
  110. package/dist/real-julia-analyzer-22CWYQMN.js +2085 -0
  111. package/dist/real-kotlin-analyzer-QDZJLXXU.js +3956 -0
  112. package/dist/real-lua-analyzer-G7NHLYKS.js +1957 -0
  113. package/dist/real-makefile-analyzer-OCY3GT5N.js +920 -0
  114. package/dist/real-markdown-analyzer-TEJK2JXJ.js +1215 -0
  115. package/dist/real-matlab-analyzer-Q5SWLN7Z.js +480 -0
  116. package/dist/real-nim-analyzer-YLXSK563.js +3603 -0
  117. package/dist/real-objective-c-analyzer-D23ACC2R.js +1518 -0
  118. package/dist/real-perl-analyzer-WWTRHYDT.js +1865 -0
  119. package/dist/real-php-analyzer-JNKJHTCL.js +9368 -0
  120. package/dist/real-powershell-analyzer-XRSNQERV.js +2915 -0
  121. package/dist/real-protobuf-analyzer-3OKUCZ7T.js +867 -0
  122. package/dist/real-python-analyzer-VXAFWI72.js +4880 -0
  123. package/dist/real-r-analyzer-ZGAIDVI4.js +2596 -0
  124. package/dist/real-ruby-analyzer-X2KTLVBH.js +2429 -0
  125. package/dist/real-rust-analyzer-OFFHPL2A.js +3359 -0
  126. package/dist/real-scala-analyzer-TSTW27J6.js +3293 -0
  127. package/dist/real-scss-analyzer-AVWYPSOQ.js +1515 -0
  128. package/dist/real-solidity-analyzer-UCI2KWUB.js +2608 -0
  129. package/dist/real-sql-analyzer-F77ZMQXR.js +3840 -0
  130. package/dist/real-svelte-analyzer-SF7NRUO5.js +2532 -0
  131. package/dist/real-swift-analyzer-MN5QT3QN.js +2311 -0
  132. package/dist/real-toml-analyzer-66L7BDCQ.js +929 -0
  133. package/dist/real-typescript-analyzer-6KEMVDWQ.js +14 -0
  134. package/dist/real-vb-analyzer-VICVPOP7.js +3145 -0
  135. package/dist/real-vba-analyzer-HXLTTHKM.js +466 -0
  136. package/dist/real-vue-analyzer-QXR56CFV.js +2680 -0
  137. package/dist/real-xml-analyzer-YL465ZJW.js +2405 -0
  138. package/dist/real-yaml-analyzer-SUBCBNSI.js +3528 -0
  139. package/dist/real-zig-analyzer-HIQLZMGY.js +2430 -0
  140. package/dist/regex-search-NJKHMZNO.js +239 -0
  141. package/dist/rules-ACHPB7QU.js +152 -0
  142. package/dist/scoped-path-MJYWJZQX.js +11 -0
  143. package/dist/setup-show-NT5ZHYNE.js +15 -0
  144. package/dist/setup-wizard-G5YYR5T6.js +24 -0
  145. package/dist/symbol-search-GZJIM2J2.js +16 -0
  146. package/dist/taint-KXUHHPIE.js +202 -0
  147. package/dist/taint-analyzer-N7YLZU3N.js +163 -0
  148. package/dist/tool-handlers-OJDC35DI.js +72 -0
  149. package/dist/tool-registry-BPEJNSZG.js +17 -0
  150. package/dist/tool-validation-Q57YMMBX.js +32 -0
  151. package/dist/type-inference-QMT2RMLV.js +13 -0
  152. package/dist/vector-binary-LMY4QGAN.js +19 -0
  153. package/dist/version-ABP2TUL2.js +9 -0
  154. package/dist/wasm-NMWO3WXY.js +16 -0
  155. package/docs/EMBEDDINGS.md +132 -0
  156. package/docs/README.md +178 -0
  157. package/docs/data/m10-baseline.json +602 -0
  158. package/docs/data/m10-benchmark-baseline.json +57 -0
  159. package/docs/data/m10-benchmark-last-run.json +127 -0
  160. package/docs/data/m10-final-audit.json +215 -0
  161. package/docs/data/m12-final-audit.json +138 -0
  162. package/docs/data/m12-surface-matrix.json +50 -0
  163. package/docs/data/public-tools.json +1902 -0
  164. package/docs/indexing/DEAD-ASSETS.md +88 -0
  165. package/docs/indexing/INDEXER-REVIEW.md +634 -0
  166. package/docs/indexing/PERFORMANCE-FINDINGS.md +106 -0
  167. package/docs/indexing/README.md +427 -0
  168. package/docs/indexing/discovery-matrix.md +41 -0
  169. package/docs/indexing/embeddings.md +325 -0
  170. package/docs/indexing/environment-variables.md +77 -0
  171. package/docs/indexing/performance.md +323 -0
  172. package/docs/indexing/resume.md +345 -0
  173. package/docs/indexing/troubleshooting.md +391 -0
  174. package/docs/man/bb.1 +190 -0
  175. package/docs/tools/bb_analyze.md +147 -0
  176. package/docs/tools/bb_annotate.md +110 -0
  177. package/docs/tools/bb_annotations.md +106 -0
  178. package/docs/tools/bb_ask.md +101 -0
  179. package/docs/tools/bb_cross_language.md +103 -0
  180. package/docs/tools/bb_doc.md +169 -0
  181. package/docs/tools/bb_edit.md +185 -0
  182. package/docs/tools/bb_graph.md +169 -0
  183. package/docs/tools/bb_health.md +156 -0
  184. package/docs/tools/bb_impact.md +117 -0
  185. package/docs/tools/bb_index.md +108 -0
  186. package/docs/tools/bb_migrate.md +135 -0
  187. package/docs/tools/bb_patterns.md +140 -0
  188. package/docs/tools/bb_search.md +150 -0
  189. package/docs/tools/bb_security.md +100 -0
  190. package/docs/tools/bb_visualize.md +184 -0
  191. package/grammars/README.md +57 -0
  192. package/grammars/THIRD-PARTY-NOTICES.md +50 -0
  193. package/grammars/tree-sitter-c/LICENSE +21 -0
  194. package/grammars/tree-sitter-clojure/LICENSE.md +21 -0
  195. package/grammars/tree-sitter-cpp/LICENSE +21 -0
  196. package/grammars/tree-sitter-csharp/LICENSE +21 -0
  197. package/grammars/tree-sitter-css/LICENSE +21 -0
  198. package/grammars/tree-sitter-css/README.md +21 -0
  199. package/grammars/tree-sitter-dart/LICENSE +20 -0
  200. package/grammars/tree-sitter-dart-upstream/LICENSE +20 -0
  201. package/grammars/tree-sitter-dart-upstream/README.md +18 -0
  202. package/grammars/tree-sitter-elixir/LICENSE +176 -0
  203. package/grammars/tree-sitter-elixir/README.md +11 -0
  204. package/grammars/tree-sitter-fsharp/LICENSE +21 -0
  205. package/grammars/tree-sitter-fsharp/README.md +45 -0
  206. package/grammars/tree-sitter-graphql/LICENSE +21 -0
  207. package/grammars/tree-sitter-graphql/README.md +106 -0
  208. package/grammars/tree-sitter-groovy/LICENSE +21 -0
  209. package/grammars/tree-sitter-groovy/README.md +4 -0
  210. package/grammars/tree-sitter-haskell/LICENSE +21 -0
  211. package/grammars/tree-sitter-haskell/README.md +394 -0
  212. package/grammars/tree-sitter-hcl/CHANGELOG.md +102 -0
  213. package/grammars/tree-sitter-hcl/LICENSE +201 -0
  214. package/grammars/tree-sitter-hcl/README.md +39 -0
  215. package/grammars/tree-sitter-html/LICENSE +21 -0
  216. package/grammars/tree-sitter-html/README.md +21 -0
  217. package/grammars/tree-sitter-julia/LICENSE +21 -0
  218. package/grammars/tree-sitter-julia/README.md +24 -0
  219. package/grammars/tree-sitter-kotlin/LICENSE +9 -0
  220. package/grammars/tree-sitter-lua/LICENSE.md +21 -0
  221. package/grammars/tree-sitter-lua/README.md +29 -0
  222. package/grammars/tree-sitter-make/LICENSE +21 -0
  223. package/grammars/tree-sitter-matlab/LICENSE +19 -0
  224. package/grammars/tree-sitter-matlab/README.md +99 -0
  225. package/grammars/tree-sitter-nim/LICENSE +373 -0
  226. package/grammars/tree-sitter-nim/README.md +46 -0
  227. package/grammars/tree-sitter-objc/LICENSE +21 -0
  228. package/grammars/tree-sitter-objc/README.md +20 -0
  229. package/grammars/tree-sitter-perl/LICENSE +7 -0
  230. package/grammars/tree-sitter-perl/README.md +100 -0
  231. package/grammars/tree-sitter-powershell/LICENSE +21 -0
  232. package/grammars/tree-sitter-powershell/README.md +7 -0
  233. package/grammars/tree-sitter-proto/LICENSE +21 -0
  234. package/grammars/tree-sitter-proto/README.md +105 -0
  235. package/grammars/tree-sitter-r/LICENSE +9 -0
  236. package/grammars/tree-sitter-r/README.md +66 -0
  237. package/grammars/tree-sitter-ruby/LICENSE +22 -0
  238. package/grammars/tree-sitter-scss/LICENSE +21 -0
  239. package/grammars/tree-sitter-scss/README.md +17 -0
  240. package/grammars/tree-sitter-solidity/LICENSE +7 -0
  241. package/grammars/tree-sitter-sql/LICENSE +21 -0
  242. package/grammars/tree-sitter-typescript/LICENSE +21 -0
  243. package/grammars/tree-sitter-vba/LICENSE +21 -0
  244. package/grammars/tree-sitter-vba/README.md +738 -0
  245. package/grammars/tree-sitter-vbnet/LICENSE +21 -0
  246. package/grammars/tree-sitter-vbnet/README.md +322 -0
  247. package/grammars/tree-sitter-xml/LICENSE +19 -0
  248. package/grammars/tree-sitter-yaml/LICENSE +20 -0
  249. package/grammars/tree-sitter-yaml/README.md +21 -0
  250. package/package.json +184 -4
  251. package/wasm/dart.wasm +0 -0
  252. package/wasm/tree-sitter-bash.wasm +0 -0
  253. package/wasm/tree-sitter-c.wasm +0 -0
  254. package/wasm/tree-sitter-c_sharp.wasm +0 -0
  255. package/wasm/tree-sitter-clean.wasm +0 -0
  256. package/wasm/tree-sitter-clojure.wasm +0 -0
  257. package/wasm/tree-sitter-core_schema.wasm +0 -0
  258. package/wasm/tree-sitter-cpp.wasm +0 -0
  259. package/wasm/tree-sitter-css.wasm +0 -0
  260. package/wasm/tree-sitter-dart.wasm +0 -0
  261. package/wasm/tree-sitter-elisp.wasm +0 -0
  262. package/wasm/tree-sitter-elixir.wasm +0 -0
  263. package/wasm/tree-sitter-elm.wasm +0 -0
  264. package/wasm/tree-sitter-embedded_template.wasm +0 -0
  265. package/wasm/tree-sitter-erlang.wasm +0 -0
  266. package/wasm/tree-sitter-fsharp.wasm +0 -0
  267. package/wasm/tree-sitter-fsharp_signature.wasm +0 -0
  268. package/wasm/tree-sitter-go.wasm +0 -0
  269. package/wasm/tree-sitter-graphql.wasm +0 -0
  270. package/wasm/tree-sitter-groovy.wasm +0 -0
  271. package/wasm/tree-sitter-haskell.wasm +0 -0
  272. package/wasm/tree-sitter-hcl.wasm +0 -0
  273. package/wasm/tree-sitter-html.wasm +0 -0
  274. package/wasm/tree-sitter-java.wasm +0 -0
  275. package/wasm/tree-sitter-javascript.wasm +0 -0
  276. package/wasm/tree-sitter-json.wasm +0 -0
  277. package/wasm/tree-sitter-json_schema.wasm +0 -0
  278. package/wasm/tree-sitter-julia.wasm +0 -0
  279. package/wasm/tree-sitter-kotlin.wasm +0 -0
  280. package/wasm/tree-sitter-lua.wasm +0 -0
  281. package/wasm/tree-sitter-make.wasm +0 -0
  282. package/wasm/tree-sitter-markdown.wasm +0 -0
  283. package/wasm/tree-sitter-markdown_inline.wasm +0 -0
  284. package/wasm/tree-sitter-matlab.wasm +0 -0
  285. package/wasm/tree-sitter-nim.wasm +0 -0
  286. package/wasm/tree-sitter-objc.wasm +0 -0
  287. package/wasm/tree-sitter-ocaml.wasm +0 -0
  288. package/wasm/tree-sitter-perl.wasm +0 -0
  289. package/wasm/tree-sitter-php.wasm +0 -0
  290. package/wasm/tree-sitter-php_only.wasm +0 -0
  291. package/wasm/tree-sitter-powershell.wasm +0 -0
  292. package/wasm/tree-sitter-protobuf.wasm +0 -0
  293. package/wasm/tree-sitter-python.wasm +0 -0
  294. package/wasm/tree-sitter-ql.wasm +0 -0
  295. package/wasm/tree-sitter-r.wasm +0 -0
  296. package/wasm/tree-sitter-rescript.wasm +0 -0
  297. package/wasm/tree-sitter-ruby.wasm +0 -0
  298. package/wasm/tree-sitter-rust.wasm +0 -0
  299. package/wasm/tree-sitter-scala.wasm +0 -0
  300. package/wasm/tree-sitter-scss.wasm +0 -0
  301. package/wasm/tree-sitter-solidity.wasm +0 -0
  302. package/wasm/tree-sitter-sql.wasm +0 -0
  303. package/wasm/tree-sitter-svelte.wasm +0 -0
  304. package/wasm/tree-sitter-swift.wasm +0 -0
  305. package/wasm/tree-sitter-systemrdl.wasm +0 -0
  306. package/wasm/tree-sitter-terraform.wasm +0 -0
  307. package/wasm/tree-sitter-tlaplus.wasm +0 -0
  308. package/wasm/tree-sitter-toml.wasm +0 -0
  309. package/wasm/tree-sitter-tsx.wasm +0 -0
  310. package/wasm/tree-sitter-typescript.wasm +0 -0
  311. package/wasm/tree-sitter-vba.wasm +0 -0
  312. package/wasm/tree-sitter-vbnet.wasm +0 -0
  313. package/wasm/tree-sitter-vue.wasm +0 -0
  314. package/wasm/tree-sitter-xml.wasm +0 -0
  315. package/wasm/tree-sitter-yaml.wasm +0 -0
  316. package/wasm/tree-sitter-zig.wasm +0 -0
  317. package/wasm/tree-sitter.wasm +0 -0
  318. package/wasm/tsx.wasm +0 -0
  319. package/wasm/typescript.wasm +0 -0
@@ -0,0 +1,37 @@
1
+ import {
2
+ runCli
3
+ } from "../chunk-ZE2LG76D.js";
4
+ import "../chunk-22V37YTK.js";
5
+ import "../chunk-DWKXZ6IF.js";
6
+ import "../chunk-2RRBMNBQ.js";
7
+ import "../chunk-UQNQZXHY.js";
8
+ import "../chunk-ZETTGPAW.js";
9
+ import "../chunk-4H22TLOT.js";
10
+ import "../chunk-B5GEAAYF.js";
11
+ import "../chunk-7AN7U5IZ.js";
12
+ import "../chunk-UGR4QIGS.js";
13
+ import "../chunk-GEFFO6O2.js";
14
+ import "../chunk-NO3U3FJQ.js";
15
+ import "../chunk-DYM4FQEE.js";
16
+ import {
17
+ getProjectId
18
+ } from "../chunk-DIYAGQJL.js";
19
+ import "../chunk-UUNHHX4M.js";
20
+ import "../chunk-WIG36E67.js";
21
+ import "../chunk-QLK6ED4Q.js";
22
+ import "../chunk-QKTRECYS.js";
23
+ import "../chunk-3ZTOHHSW.js";
24
+ import "../chunk-BQ3OVQ3P.js";
25
+ import "../chunk-SK6YVHFZ.js";
26
+ import "../chunk-2BSKD7O3.js";
27
+ import "../chunk-KAET47ZL.js";
28
+ import "../chunk-KCDECRJY.js";
29
+ import "../chunk-D2Q4Y47A.js";
30
+ import "../chunk-SM7RFQRO.js";
31
+ import "../chunk-L5TDYKYK.js";
32
+ import "../chunk-ROMM6KMC.js";
33
+ import "../chunk-MLKGABMK.js";
34
+ export {
35
+ getProjectId,
36
+ runCli
37
+ };
@@ -0,0 +1,10 @@
1
+ import {
2
+ Config,
3
+ resolveEmbeddingConfig
4
+ } from "./chunk-UGR4QIGS.js";
5
+ import "./chunk-2BSKD7O3.js";
6
+ import "./chunk-MLKGABMK.js";
7
+ export {
8
+ Config,
9
+ resolveEmbeddingConfig
10
+ };
@@ -0,0 +1,593 @@
1
+ import {
2
+ tokenizeForEmbedding
3
+ } from "./chunk-7AN7U5IZ.js";
4
+ import {
5
+ checkResultsFreshness
6
+ } from "./chunk-QLK6ED4Q.js";
7
+ import {
8
+ BrainDatabase
9
+ } from "./chunk-QKTRECYS.js";
10
+ import "./chunk-BQ3OVQ3P.js";
11
+ import "./chunk-2BSKD7O3.js";
12
+ import {
13
+ analysis_exclusions_exports
14
+ } from "./chunk-SM7RFQRO.js";
15
+ import "./chunk-L5TDYKYK.js";
16
+ import "./chunk-ROMM6KMC.js";
17
+ import "./chunk-MLKGABMK.js";
18
+
19
+ // src/intelligence/search/content-search.ts
20
+ var fts5Available = null;
21
+ var contentFtsBuilds = /* @__PURE__ */ new Map();
22
+ var CONTENT_FTS_TABLE = "brain_symbol_content_fts";
23
+ var CONTENT_FTS_META = "brain_symbol_content_fts_meta";
24
+ function detectFts5(raw) {
25
+ if (fts5Available !== null) return fts5Available;
26
+ try {
27
+ raw.exec("CREATE VIRTUAL TABLE IF NOT EXISTS temp.__bb_fts_probe USING fts5(x)");
28
+ raw.exec("DROP TABLE IF EXISTS temp.__bb_fts_probe");
29
+ fts5Available = true;
30
+ } catch {
31
+ fts5Available = false;
32
+ }
33
+ return fts5Available;
34
+ }
35
+ function tableExists(raw, name) {
36
+ try {
37
+ return raw.prepare("SELECT 1 AS present FROM sqlite_master WHERE type = 'table' AND name = ?").get(name) != null;
38
+ } catch {
39
+ return false;
40
+ }
41
+ }
42
+ function contentFtsSchema(raw) {
43
+ raw.exec(
44
+ `CREATE VIRTUAL TABLE IF NOT EXISTS ${CONTENT_FTS_TABLE} USING fts5(
45
+ symbol_id UNINDEXED, project_id UNINDEXED, name, qualified_name, docstring,
46
+ tokenize='trigram'
47
+ );
48
+ CREATE TABLE IF NOT EXISTS ${CONTENT_FTS_META} (
49
+ project_id TEXT PRIMARY KEY NOT NULL,
50
+ symbol_count INTEGER NOT NULL,
51
+ max_updated INTEGER NOT NULL
52
+ );
53
+ CREATE TRIGGER IF NOT EXISTS bb_content_fts_symbol_insert
54
+ AFTER INSERT ON brain_symbol
55
+ BEGIN DELETE FROM ${CONTENT_FTS_META} WHERE project_id = NEW.project_id; END;
56
+ CREATE TRIGGER IF NOT EXISTS bb_content_fts_symbol_update
57
+ AFTER UPDATE ON brain_symbol
58
+ BEGIN
59
+ DELETE FROM ${CONTENT_FTS_META} WHERE project_id = OLD.project_id;
60
+ DELETE FROM ${CONTENT_FTS_META} WHERE project_id = NEW.project_id;
61
+ END;
62
+ CREATE TRIGGER IF NOT EXISTS bb_content_fts_symbol_delete
63
+ AFTER DELETE ON brain_symbol
64
+ BEGIN DELETE FROM ${CONTENT_FTS_META} WHERE project_id = OLD.project_id; END;`
65
+ );
66
+ }
67
+ async function ensureContentFts(raw, projectId) {
68
+ if (!detectFts5(raw)) return false;
69
+ try {
70
+ if (!tableExists(raw, CONTENT_FTS_META) || !tableExists(raw, CONTENT_FTS_TABLE)) return false;
71
+ const marker = raw.prepare(
72
+ `SELECT symbol_count AS symbolCount, max_updated AS maxUpdated FROM ${CONTENT_FTS_META} WHERE project_id = ?`
73
+ ).get(projectId);
74
+ return marker != null;
75
+ } catch {
76
+ return false;
77
+ }
78
+ }
79
+ async function rebuildContentSearchIndex(projectId) {
80
+ const key = String(projectId);
81
+ const active = contentFtsBuilds.get(key);
82
+ if (active) {
83
+ await active;
84
+ const raw = await BrainDatabase.getRawInstance(projectId);
85
+ const row = raw.prepare(`SELECT symbol_count AS symbolCount, max_updated AS maxUpdated FROM ${CONTENT_FTS_META} WHERE project_id=?`).get(projectId);
86
+ return { indexed: Number(row?.symbolCount || 0), symbolCount: Number(row?.symbolCount || 0), maxUpdated: Number(row?.maxUpdated || 0) };
87
+ }
88
+ const build = Promise.resolve().then(async () => {
89
+ const raw = await BrainDatabase.getRawInstance(projectId);
90
+ if (!detectFts5(raw)) throw new Error("SQLite FTS5 is unavailable");
91
+ contentFtsSchema(raw);
92
+ const snapshot = raw.prepare(
93
+ "SELECT COUNT(*) AS symbolCount, COALESCE(MAX(time_updated), 0) AS maxUpdated FROM brain_symbol WHERE project_id = ? AND COALESCE(line_start, 0) > 0 AND name NOT LIKE '/%/%'"
94
+ ).get(projectId);
95
+ const rebuild = raw.transaction(() => {
96
+ raw.prepare(`DELETE FROM ${CONTENT_FTS_TABLE} WHERE project_id = ?`).run(projectId);
97
+ const insert = raw.prepare(`INSERT INTO ${CONTENT_FTS_TABLE} (symbol_id, project_id, name, qualified_name, docstring) VALUES (?, ?, ?, ?, ?)`);
98
+ const rows = raw.prepare("SELECT id, name, qualified_name AS qualifiedName, docstring FROM brain_symbol WHERE project_id = ? AND COALESCE(line_start, 0) > 0 AND name NOT LIKE '/%/%'").all(projectId);
99
+ for (const row of rows) insert.run(row.id, projectId, row.name, row.qualifiedName ?? "", row.docstring ?? "");
100
+ raw.prepare(`INSERT INTO ${CONTENT_FTS_META} (project_id, symbol_count, max_updated) VALUES (?, ?, ?) ON CONFLICT(project_id) DO UPDATE SET symbol_count=excluded.symbol_count, max_updated=excluded.max_updated`).run(projectId, snapshot.symbolCount, snapshot.maxUpdated);
101
+ return rows.length;
102
+ });
103
+ const indexed = rebuild();
104
+ return { indexed, symbolCount: snapshot.symbolCount, maxUpdated: snapshot.maxUpdated };
105
+ });
106
+ contentFtsBuilds.set(key, build.then(() => true));
107
+ try {
108
+ return await build;
109
+ } finally {
110
+ contentFtsBuilds.delete(key);
111
+ }
112
+ }
113
+ function ftsQuote(term) {
114
+ return '"' + term.split('"').join('""') + '"';
115
+ }
116
+ var LIKE_ESCAPE_CHAR = "\\";
117
+ function escapeLike(fragment) {
118
+ return fragment.split(LIKE_ESCAPE_CHAR).join(LIKE_ESCAPE_CHAR + LIKE_ESCAPE_CHAR).split("%").join(LIKE_ESCAPE_CHAR + "%").split("_").join(LIKE_ESCAPE_CHAR + "_");
119
+ }
120
+ var LIKE_ESCAPE_CLAUSE = ` ESCAPE '${LIKE_ESCAPE_CHAR}'`;
121
+ function firstLine(text) {
122
+ const line = text.split("\n").find((candidate) => candidate.trim().length > 0) ?? "";
123
+ return line.trim().slice(0, 100);
124
+ }
125
+ var GIANT_CORPUS_OFFSET = 25e3;
126
+ var PHASE_CAP_MIN = 2e4;
127
+ var PHASE_CAP_MAX = 2e5;
128
+ var ID_JOIN_CHUNK = 500;
129
+ function phaseCap(budget) {
130
+ return Math.min(PHASE_CAP_MAX, Math.max(PHASE_CAP_MIN, budget * 4));
131
+ }
132
+ function normalizePageSize(value) {
133
+ if (value === void 0 || value === null) return 100;
134
+ const n = Math.trunc(Number(value));
135
+ if (!Number.isFinite(n) || n < 0) return 100;
136
+ return n;
137
+ }
138
+ function normalizeOffset(value) {
139
+ if (value === void 0 || value === null) return 0;
140
+ const n = Math.trunc(Number(value));
141
+ if (!Number.isFinite(n) || n < 0) return 0;
142
+ return n;
143
+ }
144
+ async function searchContent(projectId, query, options = {}) {
145
+ const raw = await BrainDatabase.getRawInstance(projectId, { readonly: true });
146
+ const maxResults = normalizePageSize(options.maxResults);
147
+ const offset = normalizeOffset(options.offset);
148
+ const trimmed = String(query ?? "").trim();
149
+ if (!trimmed) return withMeta([], "content");
150
+ if (isGiantCorpus(raw, projectId)) {
151
+ return searchContentBounded(raw, projectId, trimmed, options, maxResults, offset);
152
+ }
153
+ return searchContentClassic(raw, projectId, trimmed, options, maxResults, offset, detectFts5(raw));
154
+ }
155
+ function isGiantCorpus(raw, projectId) {
156
+ const probe = raw.prepare(
157
+ "SELECT id FROM brain_symbol WHERE project_id = ? AND COALESCE(line_start, 0) > 0 AND name NOT LIKE ? LIMIT 1 OFFSET ?"
158
+ ).get(projectId, "/%/%", GIANT_CORPUS_OFFSET);
159
+ return probe != null;
160
+ }
161
+ async function searchContentClassic(raw, projectId, trimmed, options, maxResults, offset, fts5) {
162
+ const params = [projectId];
163
+ let filters = "";
164
+ if (options.languages?.length) {
165
+ filters += " AND f.language COLLATE NOCASE IN (" + options.languages.map(() => "?").join(",") + ")";
166
+ params.push(...options.languages);
167
+ }
168
+ if (options.symbolKind) {
169
+ filters += " AND s.symbol_type COLLATE NOCASE = ?";
170
+ params.push(options.symbolKind);
171
+ }
172
+ const corpus = raw.prepare(
173
+ "SELECT s.id, s.file_id AS fileId, s.name, s.qualified_name AS qualifiedName, s.docstring, s.source_text AS sourceText, s.symbol_type AS symbolType, COALESCE(s.line_start, 0) AS line, COALESCE(s.line_end, 0) AS lineEnd, COALESCE(s.complexity, 0) AS complexity, f.relative_path AS relativePath, f.path AS filePath, COALESCE(f.language, 'unknown') AS language FROM brain_symbol s JOIN brain_file f ON f.id = s.file_id WHERE s.project_id = ? AND COALESCE(s.line_start, 0) > 0 AND s.name NOT LIKE '/%/%'" + filters
174
+ ).all(...params);
175
+ const usable = corpus.filter(
176
+ (row) => !analysis_exclusions_exports.isHardNoisePath(row.relativePath) && !analysis_exclusions_exports.isNoiseSymbolName(row.name)
177
+ );
178
+ const matched = matchContentRows(trimmed, usable);
179
+ const ranked = fts5 ? rankWithFts5(raw, trimmed, matched.rows) : sortByFieldWeight(trimmed, matched.rows);
180
+ const page = ranked.slice(offset, offset + maxResults);
181
+ const withBody = usable.filter((r) => !!r.sourceText).length;
182
+ return buildResults(raw, page, "content", maxResults, {
183
+ totalMatches: matched.rows.length,
184
+ // Only the terms route can exceed the cap, so this is the one place a
185
+ // content search truncates — and it reports it rather than looking complete.
186
+ truncated: matched.truncated,
187
+ matchMode: matched.mode,
188
+ ...matched.termMatch ? { termMatch: matched.termMatch } : {},
189
+ // Declared in the contract since the body column landed but never actually
190
+ // populated: a project indexed before it has no searchable body at all, so
191
+ // "nothing matched" there means something different from "nothing could
192
+ // match", and a caller cannot tell those apart without this.
193
+ bodyCoverage: { withBody, symbols: usable.length, ratio: usable.length ? withBody / usable.length : 1 }
194
+ });
195
+ }
196
+ var GIANT_TERM_BUDGET = 2;
197
+ async function searchContentBounded(raw, projectId, trimmed, options, maxResults, offset) {
198
+ const byId = /* @__PURE__ */ new Map();
199
+ const bump = (rows, score) => {
200
+ for (const row of rows) {
201
+ if (analysis_exclusions_exports.isHardNoisePath(row.relativePath) || analysis_exclusions_exports.isNoiseSymbolName(row.name)) continue;
202
+ const existing = byId.get(row.id);
203
+ if (existing) existing.score += score;
204
+ else byId.set(row.id, { row, score });
205
+ }
206
+ };
207
+ const { sql: idFilterSql, params: idFilterParams } = languageClause(options);
208
+ const contentFtsReady = await ensureContentFts(raw, projectId);
209
+ const pageBudget = offset + maxResults;
210
+ const cap = phaseCap(pageBudget);
211
+ let truncated = false;
212
+ const sqlNeedleIds = (needleText) => {
213
+ const needle = "%" + escapeLike(needleText) + "%";
214
+ const ids = raw.prepare(
215
+ `SELECT id FROM brain_symbol WHERE project_id = ? AND COALESCE(line_start, 0) > 0 AND name NOT LIKE '/%/%' AND (name LIKE ? COLLATE NOCASE${LIKE_ESCAPE_CLAUSE} OR qualified_name LIKE ? COLLATE NOCASE${LIKE_ESCAPE_CLAUSE} OR docstring LIKE ? COLLATE NOCASE${LIKE_ESCAPE_CLAUSE} OR source_text LIKE ? COLLATE NOCASE${LIKE_ESCAPE_CLAUSE}) LIMIT ?`
216
+ ).all(projectId, needle, needle, needle, needle, cap);
217
+ if (ids.length >= cap) truncated = true;
218
+ return ids;
219
+ };
220
+ const deferPhrase = contentQueryTerms(trimmed).length > 0;
221
+ bump(selectJoined(raw, projectId, "s.name = ? COLLATE NOCASE" + idFilterSql, [trimmed, ...idFilterParams]), 3);
222
+ {
223
+ const rows = selectJoined(
224
+ raw,
225
+ projectId,
226
+ `s.name LIKE ? COLLATE NOCASE${LIKE_ESCAPE_CLAUSE}${idFilterSql} LIMIT ?`,
227
+ [escapeLike(trimmed) + "%", ...idFilterParams, cap]
228
+ );
229
+ if (rows.length >= cap) truncated = true;
230
+ bump(rows, 3);
231
+ }
232
+ {
233
+ const lowerNeedle = trimmed.toLowerCase();
234
+ const push = (rows) => {
235
+ for (const row of rows) {
236
+ const score = contentScore(row, lowerNeedle);
237
+ if (score > 0) bump([row], score);
238
+ }
239
+ };
240
+ let broadIds = [];
241
+ if (contentFtsReady && trimmed.length >= 3) {
242
+ const ftsQuery = ftsQuote(trimmed);
243
+ broadIds = raw.prepare(`SELECT symbol_id AS id FROM ${CONTENT_FTS_TABLE} WHERE ${CONTENT_FTS_TABLE} MATCH ? AND project_id = ? LIMIT ?`).all(ftsQuery, projectId, cap);
244
+ if (broadIds.length >= cap) truncated = true;
245
+ }
246
+ if (broadIds.length) push(fetchByIds(raw, projectId, broadIds, idFilterSql, idFilterParams));
247
+ const ftsCameBackEmpty = contentFtsReady && trimmed.length >= 3 && broadIds.length === 0 && byId.size === 0;
248
+ if (!deferPhrase && (!contentFtsReady || trimmed.length < 3 || ftsCameBackEmpty)) {
249
+ push(fetchByIds(raw, projectId, sqlNeedleIds(trimmed), idFilterSql, idFilterParams));
250
+ }
251
+ }
252
+ let matchMode = "phrase";
253
+ let termMatch;
254
+ if (byId.size === 0) {
255
+ const terms = contentQueryTerms(trimmed);
256
+ if (terms.length > 0 && hasWhitespace(trimmed)) {
257
+ matchMode = "terms";
258
+ const probedTerms = terms.slice(0, GIANT_TERM_BUDGET);
259
+ if (probedTerms.length < terms.length) truncated = true;
260
+ const scored = /* @__PURE__ */ new Map();
261
+ for (const term of probedTerms) {
262
+ for (const row of fetchByIds(raw, projectId, sqlNeedleIds(term), idFilterSql, idFilterParams)) {
263
+ const weight = bestFieldTermScore(row, term);
264
+ if (weight === 0) continue;
265
+ const existing = scored.get(row.id);
266
+ if (existing) {
267
+ existing.score += weight;
268
+ existing.hits.push(term);
269
+ } else {
270
+ scored.set(row.id, { row, score: weight, hits: [term] });
271
+ }
272
+ }
273
+ }
274
+ const ordered = [...scored.values()].sort(
275
+ (a, b) => b.score - a.score || b.hits.length - a.hits.length || b.row.complexity - a.row.complexity || compareCodeUnits(a.row.relativePath, b.row.relativePath)
276
+ );
277
+ for (const entry of ordered) byId.set(entry.row.id, { row: entry.row, score: entry.score });
278
+ if (ordered.length > 0) termMatch = { queryTerms: probedTerms, topMatched: ordered[0].hits };
279
+ }
280
+ }
281
+ if (deferPhrase && byId.size === 0) {
282
+ for (const row of fetchByIds(raw, projectId, sqlNeedleIds(trimmed), idFilterSql, idFilterParams)) {
283
+ const score = contentScore(row, trimmed.toLowerCase());
284
+ if (score > 0) byId.set(row.id, { row, score });
285
+ }
286
+ }
287
+ const coverage = raw.prepare(
288
+ "SELECT COUNT(*) AS symbols, SUM(CASE WHEN source_text IS NOT NULL THEN 1 ELSE 0 END) AS withBody FROM brain_symbol s JOIN brain_file f ON f.id = s.file_id WHERE s.project_id = ? AND COALESCE(s.line_start, 0) > 0 AND s.name NOT LIKE '/%/%'" + idFilterSql
289
+ ).get(projectId, ...idFilterParams);
290
+ const coverageSymbols = Number(coverage?.symbols ?? 0);
291
+ const withBody = Number(coverage?.withBody ?? 0);
292
+ const bodyCoverage = { withBody, symbols: coverageSymbols, ratio: coverageSymbols ? withBody / coverageSymbols : 1 };
293
+ const ranked = [...byId.values()].sort((a, b) => b.score - a.score || b.row.complexity - a.row.complexity || compareCodeUnits(a.row.relativePath, b.row.relativePath)).map((entry) => entry.row);
294
+ const page = ranked.slice(offset, offset + maxResults);
295
+ return buildResults(raw, page, "content", maxResults, {
296
+ totalMatches: ranked.length,
297
+ truncated,
298
+ matchMode,
299
+ ...termMatch ? { termMatch } : {},
300
+ bodyCoverage
301
+ });
302
+ }
303
+ function contentScore(row, lowerNeedle) {
304
+ let score = 0;
305
+ const lowerName = row.name.toLowerCase();
306
+ if (lowerName === lowerNeedle) score += 3;
307
+ else if (lowerName.startsWith(lowerNeedle)) score += 3;
308
+ else if (lowerName.includes(lowerNeedle)) score += 1;
309
+ if ((row.qualifiedName ?? "").toLowerCase().includes(lowerNeedle)) score += 2;
310
+ if ((row.docstring ?? "").toLowerCase().includes(lowerNeedle)) score += 1;
311
+ if (row.sourceText && row.sourceText.toLowerCase().includes(lowerNeedle)) score += 1;
312
+ return score;
313
+ }
314
+ function selectJoined(raw, projectId, predicate, params) {
315
+ return raw.prepare(
316
+ "SELECT s.id, s.file_id AS fileId, s.name, s.qualified_name AS qualifiedName, s.docstring, s.source_text AS sourceText, s.symbol_type AS symbolType, COALESCE(s.line_start, 0) AS line, COALESCE(s.line_end, 0) AS lineEnd, COALESCE(s.complexity, 0) AS complexity, f.relative_path AS relativePath, f.path AS filePath, COALESCE(f.language, 'unknown') AS language FROM brain_symbol s JOIN brain_file f ON f.id = s.file_id WHERE s.project_id = ? AND COALESCE(s.line_start, 0) > 0 AND s.name NOT LIKE '/%/%' AND " + predicate
317
+ ).all(projectId, ...params);
318
+ }
319
+ function languageClause(options) {
320
+ let sql = "";
321
+ const params = [];
322
+ if (options.languages?.length) {
323
+ sql += " AND f.language COLLATE NOCASE IN (" + options.languages.map(() => "?").join(",") + ")";
324
+ params.push(...options.languages);
325
+ }
326
+ if (options.symbolKind) {
327
+ sql += " AND s.symbol_type COLLATE NOCASE = ?";
328
+ params.push(options.symbolKind);
329
+ }
330
+ return { sql, params };
331
+ }
332
+ function fetchByIds(raw, projectId, idRows, filterSql, filterParams) {
333
+ const distinct = [...new Set(idRows.map((r) => r.id))];
334
+ if (distinct.length === 0) return [];
335
+ const out = [];
336
+ for (let start = 0; start < distinct.length; start += ID_JOIN_CHUNK) {
337
+ const chunk = distinct.slice(start, start + ID_JOIN_CHUNK);
338
+ const placeholders = chunk.map(() => "?").join(",");
339
+ out.push(
340
+ ...raw.prepare(
341
+ "SELECT s.id, s.file_id AS fileId, s.name, s.qualified_name AS qualifiedName, s.docstring, s.source_text AS sourceText, s.symbol_type AS symbolType, COALESCE(s.line_start, 0) AS line, COALESCE(s.line_end, 0) AS lineEnd, COALESCE(s.complexity, 0) AS complexity, f.relative_path AS relativePath, f.path AS filePath, COALESCE(f.language, 'unknown') AS language FROM brain_symbol s JOIN brain_file f ON f.id = s.file_id WHERE s.id IN (" + placeholders + ")" + filterSql
342
+ ).all(...chunk, ...filterParams)
343
+ );
344
+ }
345
+ return out;
346
+ }
347
+ function buildResults(raw, page, mode, _maxResults, meta = { totalMatches: page.length }) {
348
+ const results = withMeta([], mode);
349
+ results.totalMatches = meta.totalMatches;
350
+ if (meta.truncated) results.truncated = true;
351
+ if (meta.matchMode) results.matchMode = meta.matchMode;
352
+ if (meta.termMatch) results.termMatch = meta.termMatch;
353
+ if (meta.bodyCoverage) results.bodyCoverage = meta.bodyCoverage;
354
+ for (const row of page) {
355
+ results.push({
356
+ file: row.relativePath,
357
+ fileId: row.fileId,
358
+ line: row.line,
359
+ column: 0,
360
+ context: row.docstring ? row.symbolType + ": " + row.name + " \u2014 " + firstLine(row.docstring) : row.symbolType + ": " + row.name,
361
+ symbolName: row.name,
362
+ symbolType: row.symbolType,
363
+ language: row.language,
364
+ matchType: "content",
365
+ // When the match came from the BODY and there is no docstring, the first
366
+ // body line is the honest snippet: it shows why this symbol matched rather
367
+ // than repeating its name.
368
+ snippet: row.docstring ? firstLine(row.docstring) : row.sourceText ? firstLine(row.sourceText) : row.qualifiedName || row.name,
369
+ complexity: row.complexity,
370
+ _relevance: 1
371
+ });
372
+ }
373
+ try {
374
+ const freshness = checkResultsFreshness(raw, results.map((result) => ({ fileId: result.fileId })));
375
+ let staleCount = 0;
376
+ for (const result of results) {
377
+ if (["stale", "missing"].includes(freshness.get(result.fileId) ?? "")) {
378
+ result.stale = true;
379
+ staleCount++;
380
+ }
381
+ }
382
+ results.staleCount = staleCount;
383
+ results.freshCount = results.length - staleCount;
384
+ } catch {
385
+ results.freshnessError = true;
386
+ }
387
+ return results;
388
+ }
389
+ function rankWithFts5(raw, query, candidates) {
390
+ if (candidates.length < 2) return candidates;
391
+ const tableName = "__bb_content_fts_" + Math.random().toString(36).slice(2, 10);
392
+ const table = "temp." + tableName;
393
+ try {
394
+ raw.exec("CREATE VIRTUAL TABLE " + table + " USING fts5(id UNINDEXED, name, qualified_name, docstring, source_text)");
395
+ const insert = raw.prepare("INSERT INTO " + table + " (id, name, qualified_name, docstring, source_text) VALUES (?, ?, ?, ?, ?)");
396
+ for (const row of candidates) {
397
+ insert.run(row.id, row.name, row.qualifiedName ?? "", row.docstring ?? "", row.sourceText ?? "");
398
+ }
399
+ const terms = splitOnWhitespace(query).filter(Boolean).map(ftsQuote).join(" OR ");
400
+ if (!terms) return candidates;
401
+ const ranked = raw.prepare(
402
+ "SELECT id, bm25(" + tableName + ") AS score FROM " + table + " WHERE " + tableName + " MATCH ?"
403
+ ).all(terms);
404
+ if (ranked.length === 0) return candidates;
405
+ const byId = new Map(candidates.map((row) => [row.id, row]));
406
+ const lowerNeedle = query.toLowerCase();
407
+ const bm25Position = /* @__PURE__ */ new Map();
408
+ ranked.forEach((match, index) => bm25Position.set(match.id, index));
409
+ const ordered = ranked.map((match) => byId.get(match.id)).filter((row) => !!row).sort(
410
+ (a, b) => (
411
+ // The documented weights beat the ranker: a name hit outranks a
412
+ // docstring hit outranks a body hit. bm25 orders within a class.
413
+ phraseFieldWeight(b, lowerNeedle) - phraseFieldWeight(a, lowerNeedle) || (bm25Position.get(a.id) ?? 0) - (bm25Position.get(b.id) ?? 0) || b.complexity - a.complexity || compareCodeUnits(a.relativePath, b.relativePath)
414
+ )
415
+ );
416
+ if (ordered.length < candidates.length) {
417
+ const placed = new Set(ordered.map((row) => row.id));
418
+ for (const row of sortByFieldWeight(query, candidates)) {
419
+ if (!placed.has(row.id)) {
420
+ ordered.push(row);
421
+ placed.add(row.id);
422
+ }
423
+ }
424
+ }
425
+ return ordered;
426
+ } catch {
427
+ return sortByFieldWeight(query, candidates);
428
+ } finally {
429
+ try {
430
+ raw.exec("DROP TABLE IF EXISTS " + table);
431
+ } catch {
432
+ }
433
+ }
434
+ }
435
+ var BODY_MATCH_WEIGHT = 1;
436
+ var QUESTION_FRAME_WORDS = /* @__PURE__ */ new Set([
437
+ "how",
438
+ "where",
439
+ "what",
440
+ "which",
441
+ "who",
442
+ "when",
443
+ "why",
444
+ "does",
445
+ "do",
446
+ "did",
447
+ "is",
448
+ "are",
449
+ "was",
450
+ "were",
451
+ "the",
452
+ "a",
453
+ "an",
454
+ "of",
455
+ "to",
456
+ "in",
457
+ "on",
458
+ "at",
459
+ "for",
460
+ "with",
461
+ "and",
462
+ "or",
463
+ "it",
464
+ "its",
465
+ "this",
466
+ "that",
467
+ "from",
468
+ "by",
469
+ "be",
470
+ "been",
471
+ "can",
472
+ "could",
473
+ "should",
474
+ "would",
475
+ "there",
476
+ "their"
477
+ ]);
478
+ var TERMS_FALLBACK_CAP = 2e3;
479
+ function hasWhitespace(text) {
480
+ for (let i = 0; i < text.length; i++) {
481
+ const code = text.charCodeAt(i);
482
+ if (code === 32 || code >= 9 && code <= 13 || code === 133 || code === 160 || code === 5760 || code >= 8192 && code <= 8202 || code === 8232 || code === 8233 || code === 8239 || code === 8287 || code === 12288) return true;
483
+ }
484
+ return false;
485
+ }
486
+ function splitOnWhitespace(text) {
487
+ const parts = [];
488
+ let start = -1;
489
+ for (let i = 0; i < text.length; i++) {
490
+ const code = text.charCodeAt(i);
491
+ const space = code === 32 || code >= 9 && code <= 13 || code === 133 || code === 160 || code === 5760 || code >= 8192 && code <= 8202 || code === 8232 || code === 8233 || code === 8239 || code === 8287 || code === 12288;
492
+ if (space) {
493
+ if (start !== -1) {
494
+ parts.push(text.slice(start, i));
495
+ start = -1;
496
+ }
497
+ } else if (start === -1) start = i;
498
+ }
499
+ if (start !== -1) parts.push(text.slice(start));
500
+ return parts;
501
+ }
502
+ function phraseFieldWeight(row, lowerNeedle) {
503
+ if (row.name.toLowerCase().includes(lowerNeedle)) return 3;
504
+ if ((row.qualifiedName ?? "").toLowerCase().includes(lowerNeedle)) return 2;
505
+ if ((row.docstring ?? "").toLowerCase().includes(lowerNeedle)) return 1;
506
+ if (row.sourceText && row.sourceText.toLowerCase().includes(lowerNeedle)) return 1;
507
+ return 0;
508
+ }
509
+ function bestFieldTermScore(row, lowerTerm) {
510
+ if (row.name.toLowerCase().includes(lowerTerm)) return 3;
511
+ if ((row.qualifiedName ?? "").toLowerCase().includes(lowerTerm)) return 2;
512
+ if ((row.docstring ?? "").toLowerCase().includes(lowerTerm)) return 1;
513
+ if (row.sourceText && row.sourceText.toLowerCase().includes(lowerTerm)) return 1;
514
+ return 0;
515
+ }
516
+ function contentQueryTerms(query) {
517
+ const terms = /* @__PURE__ */ new Set();
518
+ for (const t of tokenizeForEmbedding(query)) {
519
+ if (t.length < 2) continue;
520
+ if (QUESTION_FRAME_WORDS.has(t)) continue;
521
+ terms.add(t);
522
+ }
523
+ return [...terms];
524
+ }
525
+ function matchContentRows(query, corpus) {
526
+ let termMatch;
527
+ const needle = query.toLowerCase();
528
+ const matched = [];
529
+ for (const row of corpus) {
530
+ if (row.name.toLowerCase().includes(needle)) matched.push(row);
531
+ else if ((row.qualifiedName ?? "").toLowerCase().includes(needle)) matched.push(row);
532
+ else if ((row.docstring ?? "").toLowerCase().includes(needle)) matched.push(row);
533
+ else if (row.sourceText && row.sourceText.toLowerCase().includes(needle)) matched.push(row);
534
+ }
535
+ if (matched.length > 0) return { rows: matched, mode: "phrase", truncated: false };
536
+ const terms = contentQueryTerms(query);
537
+ const isSingleToken = !hasWhitespace(query.trim());
538
+ if (terms.length === 0 || isSingleToken) return { rows: [], mode: "phrase", truncated: false };
539
+ const scored = [];
540
+ for (const row of corpus) {
541
+ let score = 0;
542
+ const hitTerms = [];
543
+ for (const t of terms) {
544
+ const best = bestFieldTermScore(row, t);
545
+ if (best > 0) {
546
+ score += best;
547
+ hitTerms.push(t);
548
+ }
549
+ }
550
+ if (hitTerms.length > 0) scored.push({ row, score, all: hitTerms.length === terms.length ? 1 : 0, hitTerms });
551
+ }
552
+ if (scored.length === 0) return { rows: [], mode: "terms", truncated: false };
553
+ scored.sort(
554
+ (a, b) => b.score - a.score || b.all - a.all || b.row.complexity - a.row.complexity || compareCodeUnits(a.row.relativePath, b.row.relativePath)
555
+ );
556
+ const truncated = scored.length > TERMS_FALLBACK_CAP;
557
+ termMatch = {
558
+ queryTerms: terms,
559
+ topMatched: scored[0].hitTerms
560
+ };
561
+ return { rows: scored.slice(0, TERMS_FALLBACK_CAP).map((e) => e.row), mode: "terms", truncated, termMatch };
562
+ }
563
+ function sortByFieldWeight(query, corpus) {
564
+ const needle = query.toLowerCase();
565
+ const scored = [];
566
+ for (const row of corpus) {
567
+ let score = 0;
568
+ if (row.name.toLowerCase().includes(needle)) score += 3;
569
+ if ((row.qualifiedName ?? "").toLowerCase().includes(needle)) score += 2;
570
+ if ((row.docstring ?? "").toLowerCase().includes(needle)) score += 1;
571
+ if (row.sourceText && row.sourceText.toLowerCase().includes(needle)) score += BODY_MATCH_WEIGHT;
572
+ if (score > 0) scored.push({ row, score });
573
+ }
574
+ scored.sort((a, b) => b.score - a.score || b.row.complexity - a.row.complexity || compareCodeUnits(a.row.relativePath, b.row.relativePath));
575
+ return scored.map((entry) => entry.row);
576
+ }
577
+ function compareCodeUnits(a, b) {
578
+ return a < b ? -1 : a > b ? 1 : 0;
579
+ }
580
+ function withMeta(results, mode) {
581
+ results.searchMode = mode;
582
+ if (results.staleCount === void 0) results.staleCount = 0;
583
+ if (results.freshCount === void 0) results.freshCount = 0;
584
+ if (results.totalMatches === void 0) results.totalMatches = results.length;
585
+ return results;
586
+ }
587
+ export {
588
+ contentQueryTerms,
589
+ hasWhitespace,
590
+ rebuildContentSearchIndex,
591
+ searchContent,
592
+ splitOnWhitespace
593
+ };
@@ -0,0 +1,9 @@
1
+ import {
2
+ BrainDatabase
3
+ } from "./chunk-QKTRECYS.js";
4
+ import "./chunk-2BSKD7O3.js";
5
+ import "./chunk-ROMM6KMC.js";
6
+ import "./chunk-MLKGABMK.js";
7
+ export {
8
+ BrainDatabase
9
+ };