@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,860 @@
1
+ import {
2
+ ASTEngine
3
+ } from "./chunk-3ZTOHHSW.js";
4
+ import "./chunk-BQ3OVQ3P.js";
5
+ import "./chunk-SK6YVHFZ.js";
6
+ import "./chunk-2BSKD7O3.js";
7
+ import "./chunk-KAET47ZL.js";
8
+ import "./chunk-KCDECRJY.js";
9
+ import "./chunk-MLKGABMK.js";
10
+
11
+ // src/ast/framework-intelligence.ts
12
+ var FrameworkIntelligence;
13
+ ((FrameworkIntelligence2) => {
14
+ FrameworkIntelligence2.PURE_LANGUAGE_PRIMARIES = /* @__PURE__ */ new Set([
15
+ "JavaScript",
16
+ "TypeScript",
17
+ "Python",
18
+ "Ruby",
19
+ "Java",
20
+ "C#",
21
+ "C++",
22
+ "C",
23
+ "Go",
24
+ "Rust",
25
+ "SQL",
26
+ "Dart",
27
+ "Objective-C",
28
+ "YAML",
29
+ "JSON",
30
+ "Lua",
31
+ "R",
32
+ "Haskell",
33
+ "Scala",
34
+ "Clojure",
35
+ "Groovy",
36
+ "Elixir",
37
+ "PHP",
38
+ "Swift",
39
+ "Kotlin",
40
+ "Erlang",
41
+ "Bash",
42
+ "unknown"
43
+ ]);
44
+ FrameworkIntelligence2.TOOLING_DEFAULTS = /* @__PURE__ */ new Set([
45
+ "stl",
46
+ "win32",
47
+ "POSIX",
48
+ "Standard Library",
49
+ "Standard C Library",
50
+ "test-framework",
51
+ "cmake"
52
+ ]);
53
+ class FrameworkDetector {
54
+ patterns = /* @__PURE__ */ new Map();
55
+ insights = [];
56
+ constructor() {
57
+ this.initializePatterns();
58
+ }
59
+ analyzeFrameworkUsage(symbols, relationships, imports, content, language) {
60
+ const detectedFrameworks = this.detectFrameworks(imports, content, language);
61
+ const patterns = [];
62
+ this.insights = [];
63
+ for (const framework of detectedFrameworks) {
64
+ const frameworkPatterns = this.analyzeFrameworkPatterns(
65
+ framework,
66
+ symbols,
67
+ relationships,
68
+ content,
69
+ language
70
+ );
71
+ patterns.push(...frameworkPatterns);
72
+ }
73
+ this.generateArchitecturalInsights(symbols, relationships, patterns, content);
74
+ const architecturalScore = this.calculateArchitecturalScore(patterns, this.insights);
75
+ return {
76
+ detectedFrameworks,
77
+ patterns,
78
+ insights: this.insights,
79
+ architecturalScore
80
+ };
81
+ }
82
+ detectFrameworks(imports, content, language) {
83
+ const frameworks = /* @__PURE__ */ new Set();
84
+ switch (language) {
85
+ case "typescript":
86
+ case "javascript":
87
+ this.detectJavaScriptFrameworks(imports, content, frameworks);
88
+ break;
89
+ case "python":
90
+ this.detectPythonFrameworks(imports, content, frameworks);
91
+ break;
92
+ case "java":
93
+ this.detectJavaFrameworks(imports, content, frameworks);
94
+ break;
95
+ case "csharp":
96
+ case "fsharp":
97
+ this.detectDotNetFrameworks(imports, content, frameworks);
98
+ break;
99
+ case "ruby":
100
+ this.detectRubyFrameworks(imports, content, frameworks);
101
+ break;
102
+ case "swift":
103
+ this.detectSwiftFrameworks(imports, content, frameworks);
104
+ break;
105
+ case "kotlin":
106
+ this.detectKotlinFrameworks(imports, content, frameworks);
107
+ break;
108
+ case "go":
109
+ this.detectGoFrameworks(imports, content, frameworks);
110
+ break;
111
+ case "rust":
112
+ this.detectRustFrameworks(imports, content, frameworks);
113
+ break;
114
+ case "lua":
115
+ this.detectLuaFrameworks(imports, content, frameworks);
116
+ break;
117
+ case "dart":
118
+ this.detectDartFrameworks(imports, content, frameworks);
119
+ break;
120
+ case "elixir":
121
+ this.detectElixirFrameworks(imports, content, frameworks);
122
+ break;
123
+ case "sql":
124
+ this.detectSqlFrameworks(imports, content, frameworks);
125
+ break;
126
+ case "scala":
127
+ this.detectScalaFrameworks(imports, content, frameworks);
128
+ break;
129
+ case "haskell":
130
+ this.detectHaskellFrameworks(imports, content, frameworks);
131
+ break;
132
+ case "erlang":
133
+ this.detectErlangFrameworks(imports, content, frameworks);
134
+ break;
135
+ case "c":
136
+ case "cpp":
137
+ this.detectCCppFrameworks(imports, content, frameworks);
138
+ break;
139
+ case "groovy":
140
+ this.detectGroovyFrameworks(imports, content, frameworks);
141
+ break;
142
+ default:
143
+ break;
144
+ }
145
+ return Array.from(frameworks);
146
+ }
147
+ detectSqlFrameworks(imports, content, frameworks) {
148
+ if (content.includes("{{ config(") || content.includes("{{ ref(") || content.includes("{{ source(") || content.includes("{% ") || content.includes("materialized=") || content.includes("{{ dbt_")) {
149
+ frameworks.add("dbt");
150
+ }
151
+ if (/--\s*(postgres|postgresql)/i.test(content) || /postgresql/i.test(content.slice(0, 500))) frameworks.add("postgresql");
152
+ if (/--\s*mysql/i.test(content) || /\bmysql\b/i.test(content.slice(0, 500))) frameworks.add("mysql");
153
+ }
154
+ detectDartFrameworks(imports, content, frameworks) {
155
+ if (this.hasImport(imports, "package:flutter") || content.includes("Flutter") || content.includes("Widget build") || content.includes("StatelessWidget") || content.includes("StatefulWidget") || content.includes("MaterialApp")) {
156
+ frameworks.add("flutter");
157
+ if (this.hasImport(imports, "package:flutter_bloc") || content.includes("BlocProvider") || content.includes("BlocBuilder")) frameworks.add("flutter-bloc");
158
+ if (this.hasImport(imports, "package:riverpod") || content.includes("riverpod")) frameworks.add("riverpod");
159
+ if (this.hasImport(imports, "package:provider") || content.includes("ChangeNotifierProvider")) frameworks.add("provider");
160
+ if (this.hasImport(imports, "package:dio") || content.includes("Dio()")) frameworks.add("dio");
161
+ if (content.includes("Get.put") || this.hasImport(imports, "package:get")) frameworks.add("getx");
162
+ }
163
+ if (this.hasImport(imports, "package:angular") || content.includes("@Component")) frameworks.add("angular-dart");
164
+ if (this.hasImport(imports, "package:test") || content.includes("test(") || content.includes("expect(")) frameworks.add("dart-test");
165
+ }
166
+ detectElixirFrameworks(imports, content, frameworks) {
167
+ if (content.includes("use Phoenix") || content.includes("Phoenix.") || this.hasImport(imports, "phoenix")) {
168
+ frameworks.add("phoenix");
169
+ if (content.includes("Ecto.") || this.hasImport(imports, "ecto")) frameworks.add("ecto");
170
+ }
171
+ if (content.includes("Plug.") || this.hasImport(imports, "plug")) frameworks.add("plug");
172
+ if (content.includes("defmodule") && content.includes("use ExUnit")) frameworks.add("exunit");
173
+ if (content.includes("Broadway") || this.hasImport(imports, "broadway")) frameworks.add("broadway");
174
+ }
175
+ detectScalaFrameworks(imports, content, frameworks) {
176
+ if (this.hasImport(imports, "play.api") || content.includes("extends Controller")) frameworks.add("play");
177
+ if (this.hasImport(imports, "akka") || content.includes("ActorSystem") || content.includes("ActorRef")) {
178
+ frameworks.add("akka");
179
+ if (content.includes("akka.http") || content.includes("Http()")) frameworks.add("akka-http");
180
+ }
181
+ if (this.hasImport(imports, "org.apache.spark") || content.includes("SparkSession")) frameworks.add("spark");
182
+ if (content.includes("scalatest") || this.hasImport(imports, "org.scalatest")) frameworks.add("scalatest");
183
+ if (this.hasImport(imports, "slick") || content.includes("TableQuery")) frameworks.add("slick");
184
+ }
185
+ detectHaskellFrameworks(imports, content, frameworks) {
186
+ if (this.hasImport(imports, "Yesod") || content.includes("mkYesod")) frameworks.add("yesod");
187
+ if (this.hasImport(imports, "Servant") || content.includes(":>")) frameworks.add("servant");
188
+ if (this.hasImport(imports, "Lens") || content.includes("makeLenses")) frameworks.add("lens");
189
+ if (content.includes("import Test.") || content.includes("QuickCheck")) frameworks.add("hspec-quickcheck");
190
+ }
191
+ detectErlangFrameworks(imports, content, frameworks) {
192
+ if (content.includes("-behaviour(gen_server)") || content.includes("gen_server:") || content.includes("-behaviour(supervisor)")) frameworks.add("otp");
193
+ if (content.includes("cowboy") || content.includes("cowboy_router")) frameworks.add("cowboy");
194
+ if (content.includes("rebar3") || content.includes("rebar.config")) frameworks.add("rebar3");
195
+ if (content.includes("meck:") || content.includes("eunit:") || content.includes("?assert")) frameworks.add("eunit");
196
+ }
197
+ detectCCppFrameworks(imports, content, frameworks) {
198
+ if (content.includes("#include <Q") || content.includes("QApplication") || content.includes("QWidget")) frameworks.add("qt");
199
+ if (content.includes("#include <boost/") || content.includes("boost::")) frameworks.add("boost");
200
+ if (content.includes("glfw") || content.includes("glut") || content.includes("GL/gl") || content.includes("#include <GL/")) frameworks.add("opengl");
201
+ if (content.includes("unittest") || content.includes("gtest") || content.includes("catch2") || content.includes("doctest")) frameworks.add("test-framework");
202
+ if (content.includes("cmake_minimum_required") || content.includes("project(")) frameworks.add("cmake");
203
+ }
204
+ detectGroovyFrameworks(imports, content, frameworks) {
205
+ if (content.includes("@Grab") || content.includes("grails") || content.includes("GrailsApp")) frameworks.add("grails");
206
+ if (content.includes("gradle") || content.includes("buildscript")) frameworks.add("gradle");
207
+ if (content.includes("spock.lang") || content.includes("expect:")) frameworks.add("spock");
208
+ }
209
+ detectJavaScriptFrameworks(imports, content, frameworks) {
210
+ if (this.hasImport(imports, "react") || content.includes("React.")) {
211
+ frameworks.add("react");
212
+ if (this.hasImport(imports, "next") || content.includes("getServerSideProps")) {
213
+ frameworks.add("nextjs");
214
+ }
215
+ if (this.hasImport(imports, "gatsby")) {
216
+ frameworks.add("gatsby");
217
+ }
218
+ }
219
+ if (this.hasImport(imports, "vue") || content.includes("createApp")) {
220
+ frameworks.add("vue");
221
+ if (this.hasImport(imports, "nuxt")) {
222
+ frameworks.add("nuxtjs");
223
+ }
224
+ }
225
+ if (this.hasImport(imports, "@angular/core") || content.includes("@Component")) {
226
+ frameworks.add("angular");
227
+ }
228
+ if (this.hasImport(imports, "express")) {
229
+ frameworks.add("express");
230
+ }
231
+ if (this.hasImport(imports, "fastify")) {
232
+ frameworks.add("fastify");
233
+ }
234
+ if (this.hasImport(imports, "koa")) {
235
+ frameworks.add("koa");
236
+ }
237
+ if (this.hasImport(imports, "jest") || content.includes("describe(")) {
238
+ frameworks.add("jest");
239
+ }
240
+ if (this.hasImport(imports, "mocha")) {
241
+ frameworks.add("mocha");
242
+ }
243
+ if (this.hasImport(imports, "redux") || this.hasImport(imports, "@reduxjs/toolkit")) {
244
+ frameworks.add("redux");
245
+ }
246
+ if (this.hasImport(imports, "zustand")) {
247
+ frameworks.add("zustand");
248
+ }
249
+ }
250
+ detectPythonFrameworks(imports, content, frameworks) {
251
+ if (this.hasModule(imports, "django") || content.includes("from django")) {
252
+ frameworks.add("django");
253
+ }
254
+ if (this.hasModule(imports, "flask") || content.includes("from flask")) {
255
+ frameworks.add("flask");
256
+ }
257
+ if (this.hasModule(imports, "fastapi")) {
258
+ frameworks.add("fastapi");
259
+ }
260
+ if (this.hasModule(imports, "tornado")) {
261
+ frameworks.add("tornado");
262
+ }
263
+ if (this.hasModule(imports, "pandas")) {
264
+ frameworks.add("pandas");
265
+ }
266
+ if (this.hasModule(imports, "numpy")) {
267
+ frameworks.add("numpy");
268
+ }
269
+ if (this.hasModule(imports, "tensorflow") || this.hasModule(imports, "tf")) {
270
+ frameworks.add("tensorflow");
271
+ }
272
+ if (this.hasModule(imports, "torch") || this.hasModule(imports, "pytorch")) {
273
+ frameworks.add("pytorch");
274
+ }
275
+ if (this.hasModule(imports, "pytest") || content.includes("def test_")) {
276
+ frameworks.add("pytest");
277
+ }
278
+ }
279
+ detectJavaFrameworks(imports, content, frameworks) {
280
+ if (this.hasImport(imports, "org.springframework")) {
281
+ frameworks.add("spring");
282
+ if (content.includes("@SpringBootApplication")) {
283
+ frameworks.add("spring-boot");
284
+ }
285
+ if (content.includes("@RestController")) {
286
+ frameworks.add("spring-mvc");
287
+ }
288
+ }
289
+ if (this.hasImport(imports, "org.junit")) {
290
+ frameworks.add("junit");
291
+ }
292
+ if (this.hasImport(imports, "org.mockito")) {
293
+ frameworks.add("mockito");
294
+ }
295
+ if (this.hasImport(imports, "javax.persistence") || this.hasImport(imports, "jakarta.persistence")) {
296
+ frameworks.add("jpa");
297
+ }
298
+ if (this.hasImport(imports, "org.hibernate")) {
299
+ frameworks.add("hibernate");
300
+ }
301
+ }
302
+ detectDotNetFrameworks(imports, content, frameworks) {
303
+ if (this.hasImport(imports, "Microsoft.AspNetCore") || content.includes("using Microsoft.AspNetCore")) {
304
+ frameworks.add("aspnet-core");
305
+ }
306
+ if (this.hasImport(imports, "Microsoft.EntityFrameworkCore")) {
307
+ frameworks.add("entity-framework");
308
+ }
309
+ if (this.hasImport(imports, "Xunit") || content.includes("[Fact]")) {
310
+ frameworks.add("xunit");
311
+ }
312
+ if (this.hasImport(imports, "NUnit")) {
313
+ frameworks.add("nunit");
314
+ }
315
+ if (content.includes("using System.Linq") || content.includes(".Where(") || content.includes(".Select(")) {
316
+ frameworks.add("linq");
317
+ }
318
+ }
319
+ detectRubyFrameworks(imports, content, frameworks) {
320
+ if (content.includes("require 'rails'") || content.includes("class ApplicationController")) {
321
+ frameworks.add("rails");
322
+ }
323
+ if (content.includes("require 'sinatra'")) {
324
+ frameworks.add("sinatra");
325
+ }
326
+ if (content.includes("require 'hanami'")) {
327
+ frameworks.add("hanami");
328
+ }
329
+ if (content.includes("require 'rspec'")) {
330
+ frameworks.add("rspec");
331
+ }
332
+ }
333
+ detectPHPFrameworks(imports, content, frameworks) {
334
+ if (content.includes("use Illuminate\\") || content.includes("Artisan::")) {
335
+ frameworks.add("laravel");
336
+ }
337
+ if (content.includes("use Symfony\\")) {
338
+ frameworks.add("symfony");
339
+ }
340
+ if (content.includes("class CI_Controller") || content.includes("$this->load->")) {
341
+ frameworks.add("codeigniter");
342
+ }
343
+ }
344
+ detectSwiftFrameworks(imports, content, frameworks) {
345
+ if (this.hasImport(imports, "UIKit")) {
346
+ frameworks.add("uikit");
347
+ }
348
+ if (this.hasImport(imports, "SwiftUI")) {
349
+ frameworks.add("swiftui");
350
+ }
351
+ if (this.hasImport(imports, "Combine")) {
352
+ frameworks.add("combine");
353
+ }
354
+ if (this.hasImport(imports, "NIO") || this.hasImport(imports, "NIOCore") || this.hasImport(imports, "NIOHTTP1") || content.includes("import NIO")) {
355
+ frameworks.add("swift-nio");
356
+ }
357
+ if (this.hasImport(imports, "Vapor") || content.includes("Vapor")) {
358
+ frameworks.add("vapor");
359
+ }
360
+ if (this.hasImport(imports, "XCTest") || content.includes("XCTest")) {
361
+ frameworks.add("xctest");
362
+ }
363
+ }
364
+ detectKotlinFrameworks(imports, content, frameworks) {
365
+ if (this.hasImport(imports, "android") || this.hasImport(imports, "androidx")) {
366
+ frameworks.add("android");
367
+ }
368
+ if (this.hasImport(imports, "kotlinx.coroutines")) {
369
+ frameworks.add("kotlin-coroutines");
370
+ }
371
+ if (this.hasImport(imports, "org.springframework")) {
372
+ frameworks.add("spring-kotlin");
373
+ }
374
+ }
375
+ detectGoFrameworks(imports, content, frameworks) {
376
+ if (this.hasImport(imports, "gin-gonic/gin")) {
377
+ frameworks.add("gin");
378
+ }
379
+ if (this.hasImport(imports, "gorilla/mux")) {
380
+ frameworks.add("gorilla");
381
+ }
382
+ if (this.hasImport(imports, "echo")) {
383
+ frameworks.add("echo");
384
+ }
385
+ }
386
+ detectRustFrameworks(imports, content, frameworks) {
387
+ if (this.hasImport(imports, "actix_web") || this.hasImport(imports, "actix-web") || content.includes("#[actix_web::main]")) {
388
+ frameworks.add("actix-web");
389
+ }
390
+ if (this.hasImport(imports, "axum") || content.includes("axum::")) {
391
+ frameworks.add("axum");
392
+ }
393
+ if (this.hasImport(imports, "warp")) {
394
+ frameworks.add("warp");
395
+ }
396
+ if (this.hasImport(imports, "rocket") || content.includes("#[rocket::")) {
397
+ frameworks.add("rocket");
398
+ }
399
+ if (this.hasImport(imports, "poem")) {
400
+ frameworks.add("poem");
401
+ }
402
+ if (this.hasImport(imports, "tokio") || content.includes("#[tokio::main]")) {
403
+ frameworks.add("tokio");
404
+ }
405
+ if (this.hasImport(imports, "async_std")) {
406
+ frameworks.add("async-std");
407
+ }
408
+ if (this.hasImport(imports, "rayon") || content.includes("rayon::")) {
409
+ frameworks.add("rayon");
410
+ }
411
+ if (this.hasImport(imports, "serde") || content.includes("#[derive(Serialize")) {
412
+ frameworks.add("serde");
413
+ }
414
+ if (this.hasImport(imports, "clap")) {
415
+ frameworks.add("clap");
416
+ }
417
+ if (this.hasImport(imports, "diesel")) {
418
+ frameworks.add("diesel");
419
+ }
420
+ if (this.hasImport(imports, "sqlx")) {
421
+ frameworks.add("sqlx");
422
+ }
423
+ }
424
+ detectLuaFrameworks(imports, content, frameworks) {
425
+ const mods = imports.map((i) => i.module).filter((m) => typeof m === "string");
426
+ const has = (name) => mods.some((m) => m === name || m.startsWith(`${name}.`) || m.includes(`.${name}.`));
427
+ if (content.includes("love.") || content.includes("love.load")) frameworks.add("Love2D");
428
+ if (content.includes("ngx.") || content.includes("resty.") || has("resty")) frameworks.add("OpenResty");
429
+ if (content.includes("game:GetService") || content.includes("Instance.new")) frameworks.add("Roblox");
430
+ if (content.includes("lapis.Application") || has("lapis") || /require\s*\(?\s*["']lapis(?:[./][^"']*)?["']/.test(content)) {
431
+ frameworks.add("Lapis");
432
+ }
433
+ }
434
+ analyzeFrameworkPatterns(framework, symbols, relationships, content, language) {
435
+ const patterns = [];
436
+ const frameworkPatterns = this.patterns.get(framework) || [];
437
+ for (const pattern of frameworkPatterns) {
438
+ if (this.detectPattern(pattern, symbols, relationships, content)) {
439
+ patterns.push(pattern);
440
+ }
441
+ }
442
+ return patterns;
443
+ }
444
+ detectPattern(pattern, symbols, relationships, content) {
445
+ switch (pattern.name) {
446
+ case "react-hooks-usage":
447
+ return this.detectReactHooks(symbols, content);
448
+ case "redux-store-structure":
449
+ return this.detectReduxStore(symbols, relationships);
450
+ case "django-model-relations":
451
+ return this.detectDjangoModels(symbols, content);
452
+ case "spring-dependency-injection":
453
+ return this.detectSpringDI(symbols, content);
454
+ case "rails-active-record":
455
+ return this.detectRailsActiveRecord(symbols, content);
456
+ case "swiftui-declarative":
457
+ return this.detectSwiftUIPatterns(symbols, content);
458
+ default:
459
+ return false;
460
+ }
461
+ }
462
+ detectReactHooks(symbols, content) {
463
+ const hookPatterns = ["useState", "useEffect", "useContext", "useReducer", "useMemo", "useCallback"];
464
+ return hookPatterns.some((hook) => content.includes(hook));
465
+ }
466
+ detectReduxStore(symbols, relationships) {
467
+ const hasStore = symbols.some((s) => s.name.includes("store") || s.name.includes("reducer"));
468
+ const hasActions = symbols.some((s) => s.name.includes("action") || s.name.includes("dispatch"));
469
+ return hasStore && hasActions;
470
+ }
471
+ detectDjangoModels(symbols, content) {
472
+ return symbols.some(
473
+ (s) => s.kind === ASTEngine.SymbolKind.Class && (content.includes("models.Model") || content.includes("class Meta:"))
474
+ );
475
+ }
476
+ detectSpringDI(symbols, content) {
477
+ const diAnnotations = ["@Autowired", "@Component", "@Service", "@Repository", "@Controller"];
478
+ return diAnnotations.some((annotation) => content.includes(annotation));
479
+ }
480
+ detectRailsActiveRecord(symbols, content) {
481
+ return symbols.some(
482
+ (s) => s.kind === ASTEngine.SymbolKind.Class && content.includes("< ApplicationRecord")
483
+ );
484
+ }
485
+ detectSwiftUIPatterns(symbols, content) {
486
+ const swiftuiPatterns = ["@State", "@Binding", "@ObservedObject", "@StateObject", "View"];
487
+ return swiftuiPatterns.some((pattern) => content.includes(pattern));
488
+ }
489
+ generateArchitecturalInsights(symbols, relationships, patterns, content) {
490
+ this.analyzeComplexity(symbols);
491
+ this.detectAntiPatterns(symbols, relationships, content);
492
+ this.analyzeFrameworkUsageQuality(patterns, symbols);
493
+ this.analyzeSecurityPatterns(symbols, content);
494
+ }
495
+ analyzeComplexity(symbols) {
496
+ const functions = symbols.filter((s) => s.kind === ASTEngine.SymbolKind.Function);
497
+ for (const func of functions) {
498
+ const complexity = func.metadata?.cyclomaticComplexity || 0;
499
+ if (complexity > 10) {
500
+ this.insights.push({
501
+ pattern: "high-complexity-function",
502
+ category: "performance",
503
+ impact: complexity > 20 ? "critical" : "high",
504
+ description: `Function ${func.name} has high cyclomatic complexity (${complexity})`,
505
+ location: func.range,
506
+ suggestions: [
507
+ "Break down into smaller functions",
508
+ "Extract common logic into helper methods",
509
+ "Consider using strategy pattern for complex conditionals"
510
+ ]
511
+ });
512
+ }
513
+ }
514
+ }
515
+ detectAntiPatterns(symbols, relationships, content) {
516
+ const classes = symbols.filter((s) => s.kind === ASTEngine.SymbolKind.Class);
517
+ const methodsByOwner = /* @__PURE__ */ new Map();
518
+ for (const s of symbols) {
519
+ if (s.kind === ASTEngine.SymbolKind.Method && s.ownerName) {
520
+ let list = methodsByOwner.get(s.ownerName);
521
+ if (!list) {
522
+ list = [];
523
+ methodsByOwner.set(s.ownerName, list);
524
+ }
525
+ list.push(s);
526
+ }
527
+ }
528
+ for (const cls of classes) {
529
+ const classMethods = methodsByOwner.get(cls.name) || [];
530
+ if (classMethods.length > 20) {
531
+ this.insights.push({
532
+ pattern: "god-class",
533
+ category: "anti_pattern",
534
+ impact: "high",
535
+ description: `Class ${cls.name} has too many methods (${classMethods.length})`,
536
+ location: cls.range,
537
+ suggestions: [
538
+ "Split class into smaller, focused classes",
539
+ "Apply Single Responsibility Principle",
540
+ "Extract related methods into separate classes"
541
+ ]
542
+ });
543
+ }
544
+ }
545
+ const functions = symbols.filter((s) => s.kind === ASTEngine.SymbolKind.Function);
546
+ for (const func of functions) {
547
+ const paramCount = func.parameters?.length || 0;
548
+ if (paramCount > 5) {
549
+ this.insights.push({
550
+ pattern: "long-parameter-list",
551
+ category: "anti_pattern",
552
+ impact: "medium",
553
+ description: `Function ${func.name} has too many parameters (${paramCount})`,
554
+ location: func.range,
555
+ suggestions: [
556
+ "Group related parameters into objects",
557
+ "Use builder pattern for complex constructors",
558
+ "Consider parameter objects or configuration objects"
559
+ ]
560
+ });
561
+ }
562
+ }
563
+ }
564
+ analyzeFrameworkUsageQuality(patterns, symbols) {
565
+ const antiPatterns = patterns.filter((p) => p.antiPattern);
566
+ for (const antiPattern of antiPatterns) {
567
+ this.insights.push({
568
+ pattern: antiPattern.name,
569
+ category: "framework_usage",
570
+ impact: antiPattern.severity === `warning` ? "high" : "medium",
571
+ description: antiPattern.description,
572
+ location: { startLine: 1, startColumn: 1, endLine: 1, endColumn: 1 },
573
+ // TODO: Get actual location
574
+ suggestions: antiPattern.suggestion ? [antiPattern.suggestion] : []
575
+ });
576
+ }
577
+ }
578
+ analyzeSecurityPatterns(symbols, content) {
579
+ if (content.includes("eval(") || content.includes("Function(")) {
580
+ this.insights.push({
581
+ pattern: "dangerous-eval-usage",
582
+ category: "security",
583
+ impact: "critical",
584
+ description: "Use of eval() or Function() constructor detected",
585
+ location: { startLine: 1, startColumn: 1, endLine: 1, endColumn: 1 },
586
+ suggestions: [
587
+ "Avoid using eval() - use JSON.parse() for data parsing",
588
+ "Use safer alternatives like computed properties",
589
+ "Validate and sanitize all inputs"
590
+ ]
591
+ });
592
+ }
593
+ if (content.includes("innerHTML") && !content.includes("DOMPurify")) {
594
+ this.insights.push({
595
+ pattern: "xss-vulnerability",
596
+ category: "security",
597
+ impact: "high",
598
+ description: "Potential XSS vulnerability through innerHTML usage",
599
+ location: { startLine: 1, startColumn: 1, endLine: 1, endColumn: 1 },
600
+ suggestions: [
601
+ "Use textContent instead of innerHTML when possible",
602
+ "Sanitize HTML content with libraries like DOMPurify",
603
+ "Use template engines with automatic escaping"
604
+ ]
605
+ });
606
+ }
607
+ }
608
+ calculateArchitecturalScore(patterns, insights) {
609
+ let score = 100;
610
+ for (const insight of insights) {
611
+ switch (insight.impact) {
612
+ case "critical":
613
+ score -= 20;
614
+ break;
615
+ case "high":
616
+ score -= 10;
617
+ break;
618
+ case "medium":
619
+ score -= 5;
620
+ break;
621
+ case "low":
622
+ score -= 2;
623
+ break;
624
+ }
625
+ }
626
+ const goodPatterns = patterns.filter((p) => !p.antiPattern);
627
+ score += goodPatterns.length * 2;
628
+ return Math.max(0, Math.min(100, score));
629
+ }
630
+ hasImport(imports, module) {
631
+ return imports.some((imp) => (imp.module || "").includes(module));
632
+ }
633
+ /**
634
+ * Does any import name this MODULE — matched by its root segment or in full, NOT by
635
+ * substring?
636
+ *
637
+ * `hasImport` above is a substring test, and it is the right test for a prefix-shaped
638
+ * needle like `org.springframework`. It is catastrophically wrong for a SHORT one. The
639
+ * concrete damage, measured over the python corpus (PY-17):
640
+ *
641
+ * · `"platform".includes("tf")` is **true**, so the TensorFlow alias `tf` fired on every
642
+ * file that imports `platform`. 34 corpus files reported `tensorflow` on the strength
643
+ * of a stdlib import — including `requests/src/requests/help.py` and
644
+ * `ansible/lib/ansible/modules/cron.py`, neither of which has anything to do with it.
645
+ * · `"numpydoc".includes("numpy")` is **true**, so `import numpydoc` reported numpy.
646
+ *
647
+ * A two-character needle matched against a whole dotted module path matches almost
648
+ * anything. The fix is not to shorten the table but to match what "imports this framework"
649
+ * actually means: the import names the framework, optionally with a submodule —
650
+ * `django.db`, `starlette.applications` — so the root segment must EQUAL the framework,
651
+ * and a longer module that merely CONTAINS it is a different library.
652
+ *
653
+ * ADDITIVE, deliberately: `hasImport` is left exactly as it was, because it is correct for
654
+ * every other caller in this file and 20-odd other lanes read it. Changing a shared
655
+ * predicate's semantics to fix one lane's table is the move this repo's own comments keep
656
+ * warning against; adding the precise one and using it where precision is required is not.
657
+ */
658
+ hasModule(imports, module) {
659
+ const want = module.toLowerCase();
660
+ return imports.some((imp) => {
661
+ const m = (imp.module || "").toLowerCase();
662
+ if (m === want) return true;
663
+ const dot = m.indexOf(".");
664
+ return dot > 0 && m.slice(0, dot) === want;
665
+ });
666
+ }
667
+ initializePatterns() {
668
+ this.patterns.set("react", [
669
+ {
670
+ name: "react-hooks-usage",
671
+ framework: "react",
672
+ language: "javascript",
673
+ confidence: 0.9,
674
+ description: "Proper React Hooks usage for state management",
675
+ examples: ["useState", "useEffect", "useContext"]
676
+ },
677
+ {
678
+ name: "react-class-components",
679
+ framework: "react",
680
+ language: "javascript",
681
+ confidence: 0.8,
682
+ description: "Legacy class components detected",
683
+ antiPattern: true,
684
+ severity: "warning",
685
+ suggestion: "Consider migrating to functional components with hooks",
686
+ examples: ["class Component extends React.Component"]
687
+ }
688
+ ]);
689
+ this.patterns.set("redux", [
690
+ {
691
+ name: "redux-store-structure",
692
+ framework: "redux",
693
+ language: "javascript",
694
+ confidence: 0.9,
695
+ description: "Well-structured Redux store with actions and reducers",
696
+ examples: ["createStore", "combineReducers", "dispatch"]
697
+ }
698
+ ]);
699
+ this.patterns.set("django", [
700
+ {
701
+ name: "django-model-relations",
702
+ framework: "django",
703
+ language: "python",
704
+ confidence: 0.9,
705
+ description: "Django model relationships and field definitions",
706
+ examples: ["models.Model", "ForeignKey", "ManyToManyField"]
707
+ }
708
+ ]);
709
+ this.patterns.set("spring", [
710
+ {
711
+ name: "spring-dependency-injection",
712
+ framework: "spring",
713
+ language: "java",
714
+ confidence: 0.9,
715
+ description: "Proper Spring dependency injection usage",
716
+ examples: ["@Autowired", "@Component", "@Service"]
717
+ }
718
+ ]);
719
+ this.patterns.set("rails", [
720
+ {
721
+ name: "rails-active-record",
722
+ framework: "rails",
723
+ language: "ruby",
724
+ confidence: 0.9,
725
+ description: "Rails Active Record model definitions",
726
+ examples: ["< ApplicationRecord", "has_many", "belongs_to"]
727
+ }
728
+ ]);
729
+ this.patterns.set("swiftui", [
730
+ {
731
+ name: "swiftui-declarative",
732
+ framework: "swiftui",
733
+ language: "swift",
734
+ confidence: 0.9,
735
+ description: "Declarative SwiftUI view definitions",
736
+ examples: ["@State", "@Binding", "View"]
737
+ }
738
+ ]);
739
+ }
740
+ }
741
+ FrameworkIntelligence2.FrameworkDetector = FrameworkDetector;
742
+ const FRAMEWORK_ALIASES = {
743
+ spring_mvc: "spring-mvc",
744
+ spring_data: "spring-data",
745
+ spring_core: "spring-core",
746
+ aspnet: "aspnet-core",
747
+ entityframework: "entity-framework",
748
+ aspnet_core: "aspnet-core",
749
+ entity_framework: "entity-framework",
750
+ expressjs: "express",
751
+ fastifyjs: "fastify",
752
+ reactjs: "react",
753
+ vuejs: "vue",
754
+ next_js: "nextjs",
755
+ nextjs: "nextjs",
756
+ "flutter-bloc": "flutter-bloc",
757
+ kotlin_coroutines: "kotlin-coroutines",
758
+ spring_kotlin: "spring-kotlin",
759
+ actix_web: "actix-web",
760
+ async_std: "async-std",
761
+ "Play Framework": "play",
762
+ "play framework": "play",
763
+ gorilla_mux: "gorilla",
764
+ gorillamux: "gorilla",
765
+ // #932 — ONE framework, ONE name. The ruby lane publishes `"Ruby on Rails"`
766
+ // (`RAILS_FRAMEWORK`, whose own header records that the two-spelling defect was
767
+ // fixed on the patterns surface) while `detectRubyFrameworks` below adds the slug
768
+ // `"rails"`, and `canonicalizeDetections` dedupes by ALIASED lowercase — `"rails"`
769
+ // and `"ruby on rails"` are different keys, so both survived into one payload and a
770
+ // consumer keying on the framework string saw two frameworks. MEASURED through
771
+ // `ASTEngine.parseFile` on `require 'rails'` + an ActiveRecord subclass: the
772
+ // published list read `["Ruby on Rails","rails"]`. The alias map is where this
773
+ // repository already puts exactly this policy (swift's `swiftui` slug, the
774
+ // `aspnet`/`entityframework` pairs), so the slug is canonicalised HERE rather than
775
+ // in the detector: the detector's vocabulary may stay a slug table ("rspec",
776
+ // "nunit", "linq" all live there), but the PUBLISHED list answers to one name.
777
+ rails: "Ruby on Rails",
778
+ "ruby on rails": "Ruby on Rails"
779
+ };
780
+ function canonicalizeDetections(detections) {
781
+ const seen = /* @__PURE__ */ new Map();
782
+ for (const raw of detections) {
783
+ const name = (raw || "").trim();
784
+ if (!name) continue;
785
+ const aliased = FRAMEWORK_ALIASES[name.toLowerCase()] ?? name;
786
+ const lower = aliased.toLowerCase();
787
+ if (!seen.has(lower)) seen.set(lower, aliased);
788
+ }
789
+ return Array.from(seen.values());
790
+ }
791
+ function alignFrameworkPatterns(patterns, detections) {
792
+ const displayOf = /* @__PURE__ */ new Map();
793
+ for (const d of detections) {
794
+ const n = String(d || "").trim();
795
+ if (n && !displayOf.has(n.toLowerCase())) displayOf.set(n.toLowerCase(), n);
796
+ }
797
+ const out = [];
798
+ for (const p of patterns) {
799
+ const raw = typeof p?.framework === "string" ? p.framework : "";
800
+ if (!raw) continue;
801
+ const canonical = FRAMEWORK_ALIASES[raw.toLowerCase()] ?? raw;
802
+ const display = displayOf.get(canonical.toLowerCase()) ?? displayOf.get(raw.toLowerCase());
803
+ if (!display) continue;
804
+ out.push(display === raw ? p : { ...p, framework: display });
805
+ }
806
+ return out;
807
+ }
808
+ FrameworkIntelligence2.alignFrameworkPatterns = alignFrameworkPatterns;
809
+ function enhanceWithFrameworkIntelligence(result, content, language) {
810
+ const detector = new FrameworkDetector();
811
+ const analysis = detector.analyzeFrameworkUsage(
812
+ result.symbols,
813
+ result.relationships,
814
+ result.imports,
815
+ content,
816
+ language
817
+ );
818
+ const prev = result.metadata || {};
819
+ const found = /* @__PURE__ */ new Set([...prev.detectedFrameworks || [], ...analysis.detectedFrameworks]);
820
+ const pats = [...prev.frameworkPatterns || [], ...analysis.patterns];
821
+ const allDetections = canonicalizeDetections(Array.from(found));
822
+ const mergedDetections = allDetections.filter(
823
+ (f) => !FrameworkIntelligence2.PURE_LANGUAGE_PRIMARIES.has(f) && !FrameworkIntelligence2.TOOLING_DEFAULTS.has(f)
824
+ );
825
+ let primaryFramework = prev.framework;
826
+ const isReal = (f) => !FrameworkIntelligence2.PURE_LANGUAGE_PRIMARIES.has(f) && !FrameworkIntelligence2.TOOLING_DEFAULTS.has(f);
827
+ if (!primaryFramework || primaryFramework === "unknown") {
828
+ primaryFramework = allDetections.find(isReal) ?? allDetections.find((f) => !FrameworkIntelligence2.TOOLING_DEFAULTS.has(f)) ?? allDetections[0] ?? "unknown";
829
+ } else if (FrameworkIntelligence2.PURE_LANGUAGE_PRIMARIES.has(primaryFramework)) {
830
+ const real = allDetections.find(isReal);
831
+ if (real) primaryFramework = real;
832
+ }
833
+ if (primaryFramework) {
834
+ primaryFramework = FRAMEWORK_ALIASES[primaryFramework.toLowerCase()] ?? primaryFramework;
835
+ }
836
+ const analyzerInsights = prev.architecturalInsights;
837
+ const analyzerScore = prev.architecturalScore;
838
+ const fiFoundNothing = analysis.insights.length === 0 && (pats?.length ?? 0) === 0;
839
+ const keepAnalyzerInsights = fiFoundNothing && Array.isArray(analyzerInsights) && analyzerInsights.length > 0;
840
+ const keepAnalyzerScore = fiFoundNothing && typeof analyzerScore === "number" && analysis.architecturalScore >= 100;
841
+ result.metadata = {
842
+ ...prev,
843
+ framework: primaryFramework,
844
+ detectedFrameworks: mergedDetections,
845
+ // Aligned with the list this same object publishes, so the three keys are one claim.
846
+ frameworkPatterns: alignFrameworkPatterns(pats, mergedDetections),
847
+ architecturalInsights: keepAnalyzerInsights ? analyzerInsights : analysis.insights,
848
+ architecturalScore: keepAnalyzerScore ? analyzerScore : analysis.architecturalScore,
849
+ // The case follows the score that was actually kept, so the two can never
850
+ // disagree (`"Excellent"` from the analyzer against `"excellent"` from here
851
+ // was the pre-fix state for html).
852
+ codeQuality: (keepAnalyzerScore ? analyzerScore : analysis.architecturalScore) >= 80 ? "excellent" : (keepAnalyzerScore ? analyzerScore : analysis.architecturalScore) >= 60 ? "good" : (keepAnalyzerScore ? analyzerScore : analysis.architecturalScore) >= 40 ? "fair" : "poor"
853
+ };
854
+ return result;
855
+ }
856
+ FrameworkIntelligence2.enhanceWithFrameworkIntelligence = enhanceWithFrameworkIntelligence;
857
+ })(FrameworkIntelligence || (FrameworkIntelligence = {}));
858
+ export {
859
+ FrameworkIntelligence
860
+ };