bluera-knowledge 0.9.21

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 (652) hide show
  1. package/.claude/commands/commit.md +37 -0
  2. package/.claude/hooks/post-edit-check.sh +41 -0
  3. package/.claude/settings.local.json.example +40 -0
  4. package/.claude/skills/atomic-commits/SKILL.md +53 -0
  5. package/.claude-plugin/plugin.json +13 -0
  6. package/.editorconfig +15 -0
  7. package/.github/workflows/auto-release.yml +59 -0
  8. package/.github/workflows/ci.yml +142 -0
  9. package/.github/workflows/release.yml +66 -0
  10. package/.github/workflows/update-marketplace.yml +96 -0
  11. package/.husky/pre-commit +47 -0
  12. package/.husky/pre-push +29 -0
  13. package/.versionrc.json +28 -0
  14. package/CHANGELOG.md +410 -0
  15. package/CLAUDE.md +109 -0
  16. package/LICENSE +21 -0
  17. package/NOTICE +47 -0
  18. package/README.md +1546 -0
  19. package/SECURITY.md +65 -0
  20. package/bun.lock +1758 -0
  21. package/commands/add-folder.md +48 -0
  22. package/commands/add-repo.md +50 -0
  23. package/commands/cancel.md +63 -0
  24. package/commands/check-status.md +78 -0
  25. package/commands/crawl.md +51 -0
  26. package/commands/index.md +48 -0
  27. package/commands/remove-store.md +52 -0
  28. package/commands/search.md +79 -0
  29. package/commands/search.sh +63 -0
  30. package/commands/stores.md +54 -0
  31. package/commands/suggest.md +82 -0
  32. package/dist/chunk-5QMHZUC4.js +3617 -0
  33. package/dist/chunk-5QMHZUC4.js.map +1 -0
  34. package/dist/chunk-BICFAWMN.js +656 -0
  35. package/dist/chunk-BICFAWMN.js.map +1 -0
  36. package/dist/chunk-J7J6LXOJ.js +958 -0
  37. package/dist/chunk-J7J6LXOJ.js.map +1 -0
  38. package/dist/chunk-L2YVNC63.js +59 -0
  39. package/dist/chunk-L2YVNC63.js.map +1 -0
  40. package/dist/index.d.ts +1 -0
  41. package/dist/index.js +1429 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/mcp/server.d.ts +15 -0
  44. package/dist/mcp/server.js +11 -0
  45. package/dist/mcp/server.js.map +1 -0
  46. package/dist/watch.service-YAIKKDCF.js +7 -0
  47. package/dist/watch.service-YAIKKDCF.js.map +1 -0
  48. package/dist/workers/background-worker-cli.d.ts +1 -0
  49. package/dist/workers/background-worker-cli.js +310 -0
  50. package/dist/workers/background-worker-cli.js.map +1 -0
  51. package/docs/plans/2024-12-17-ai-search-quality-implementation.md +752 -0
  52. package/docs/plans/2024-12-17-ai-search-quality-testing-design.md +201 -0
  53. package/docs/plans/2025-12-16-bluera-knowledge-cli.md +2951 -0
  54. package/docs/plans/2025-12-16-phase2-features.md +1518 -0
  55. package/docs/plans/2025-12-17-hil-implementation.md +926 -0
  56. package/docs/plans/2025-12-17-hil-quality-testing.md +224 -0
  57. package/docs/plans/2025-12-17-search-quality-phase1-implementation.md +1416 -0
  58. package/docs/plans/2025-12-17-search-quality-testing-v2-design.md +212 -0
  59. package/docs/plans/2025-12-28-ai-agent-optimization.md +1630 -0
  60. package/eslint-rules/require-skip-comment.js +81 -0
  61. package/eslint.config.js +61 -0
  62. package/hooks/check-dependencies.sh +110 -0
  63. package/hooks/format-search-results.py +132 -0
  64. package/hooks/hooks.json +27 -0
  65. package/hooks/job-status-hook.sh +51 -0
  66. package/knip.json +43 -0
  67. package/mcp.plugin.json +12 -0
  68. package/package.json +103 -0
  69. package/python/crawl_worker.py +275 -0
  70. package/python/requirements.txt +2 -0
  71. package/scripts/readme-version-updater.cjs +18 -0
  72. package/skills/advanced-workflows/SKILL.md +273 -0
  73. package/skills/atomic-commits/SKILL.md +77 -0
  74. package/skills/knowledge-search/SKILL.md +54 -0
  75. package/skills/search-optimization/SKILL.md +396 -0
  76. package/skills/store-lifecycle/SKILL.md +470 -0
  77. package/skills/when-to-query/SKILL.md +66 -0
  78. package/src/analysis/ast-parser.test.ts +423 -0
  79. package/src/analysis/ast-parser.ts +192 -0
  80. package/src/analysis/code-graph.test.ts +698 -0
  81. package/src/analysis/code-graph.ts +245 -0
  82. package/src/analysis/dependency-usage-analyzer.test.ts +799 -0
  83. package/src/analysis/dependency-usage-analyzer.ts +405 -0
  84. package/src/analysis/go-ast-parser.test.ts +531 -0
  85. package/src/analysis/go-ast-parser.ts +478 -0
  86. package/src/analysis/parser-factory.test.ts +132 -0
  87. package/src/analysis/parser-factory.ts +44 -0
  88. package/src/analysis/python-ast-parser.test.ts +210 -0
  89. package/src/analysis/python-ast-parser.ts +34 -0
  90. package/src/analysis/repo-url-resolver.test.ts +533 -0
  91. package/src/analysis/repo-url-resolver.ts +233 -0
  92. package/src/analysis/rust-ast-parser.test.ts +568 -0
  93. package/src/analysis/rust-ast-parser.ts +477 -0
  94. package/src/analysis/tree-sitter-parser.test.ts +297 -0
  95. package/src/analysis/tree-sitter-parser.ts +223 -0
  96. package/src/cli/commands/crawl.test.ts +942 -0
  97. package/src/cli/commands/crawl.ts +141 -0
  98. package/src/cli/commands/index-cmd.test.ts +722 -0
  99. package/src/cli/commands/index-cmd.ts +105 -0
  100. package/src/cli/commands/mcp.test.ts +218 -0
  101. package/src/cli/commands/mcp.ts +18 -0
  102. package/src/cli/commands/plugin-api.test.ts +313 -0
  103. package/src/cli/commands/plugin-api.ts +45 -0
  104. package/src/cli/commands/search.test.ts +911 -0
  105. package/src/cli/commands/search.ts +113 -0
  106. package/src/cli/commands/serve.test.ts +329 -0
  107. package/src/cli/commands/serve.ts +28 -0
  108. package/src/cli/commands/setup.test.ts +820 -0
  109. package/src/cli/commands/setup.ts +153 -0
  110. package/src/cli/commands/store.test.ts +1003 -0
  111. package/src/cli/commands/store.ts +167 -0
  112. package/src/cli/index.ts +7 -0
  113. package/src/cli/program.ts +59 -0
  114. package/src/crawl/article-converter.test.ts +604 -0
  115. package/src/crawl/article-converter.ts +98 -0
  116. package/src/crawl/bridge.test.ts +674 -0
  117. package/src/crawl/bridge.ts +236 -0
  118. package/src/crawl/claude-client.test.ts +663 -0
  119. package/src/crawl/claude-client.ts +234 -0
  120. package/src/crawl/intelligent-crawler.test.ts +931 -0
  121. package/src/crawl/intelligent-crawler.ts +428 -0
  122. package/src/crawl/markdown-utils.test.ts +703 -0
  123. package/src/crawl/markdown-utils.ts +228 -0
  124. package/src/crawl/schemas.ts +114 -0
  125. package/src/db/embeddings.test.ts +63 -0
  126. package/src/db/embeddings.ts +69 -0
  127. package/src/db/index.ts +2 -0
  128. package/src/db/lance.test.ts +390 -0
  129. package/src/db/lance.ts +164 -0
  130. package/src/defaults/repos.ts +67 -0
  131. package/src/index.ts +107 -0
  132. package/src/mcp/cache.test.ts +202 -0
  133. package/src/mcp/cache.ts +103 -0
  134. package/src/mcp/commands/index.ts +20 -0
  135. package/src/mcp/commands/job.commands.ts +54 -0
  136. package/src/mcp/commands/meta.commands.ts +54 -0
  137. package/src/mcp/commands/registry.ts +183 -0
  138. package/src/mcp/commands/store.commands.ts +75 -0
  139. package/src/mcp/handlers/execute.handler.test.ts +179 -0
  140. package/src/mcp/handlers/execute.handler.ts +24 -0
  141. package/src/mcp/handlers/index.ts +43 -0
  142. package/src/mcp/handlers/job.handler.test.ts +189 -0
  143. package/src/mcp/handlers/job.handler.ts +116 -0
  144. package/src/mcp/handlers/search.handler.test.ts +334 -0
  145. package/src/mcp/handlers/search.handler.ts +209 -0
  146. package/src/mcp/handlers/store.handler.test.ts +415 -0
  147. package/src/mcp/handlers/store.handler.ts +295 -0
  148. package/src/mcp/schemas/index.test.ts +315 -0
  149. package/src/mcp/schemas/index.ts +138 -0
  150. package/src/mcp/server.test.ts +36 -0
  151. package/src/mcp/server.ts +162 -0
  152. package/src/mcp/types.ts +41 -0
  153. package/src/plugin/commands.test.ts +789 -0
  154. package/src/plugin/commands.ts +257 -0
  155. package/src/plugin/dependency-analyzer.test.ts +380 -0
  156. package/src/plugin/dependency-analyzer.ts +147 -0
  157. package/src/plugin/git-clone.test.ts +332 -0
  158. package/src/plugin/git-clone.ts +57 -0
  159. package/src/server/app.test.ts +752 -0
  160. package/src/server/app.ts +119 -0
  161. package/src/server/index.test.ts +477 -0
  162. package/src/server/index.ts +1 -0
  163. package/src/services/chunking.service.test.ts +363 -0
  164. package/src/services/chunking.service.ts +350 -0
  165. package/src/services/code-graph.service.test.ts +304 -0
  166. package/src/services/code-graph.service.ts +302 -0
  167. package/src/services/code-unit.service.test.ts +596 -0
  168. package/src/services/code-unit.service.ts +115 -0
  169. package/src/services/config.service.test.ts +127 -0
  170. package/src/services/config.service.ts +69 -0
  171. package/src/services/index.service.test.ts +1002 -0
  172. package/src/services/index.service.ts +266 -0
  173. package/src/services/index.ts +75 -0
  174. package/src/services/job.service.test.ts +418 -0
  175. package/src/services/job.service.ts +246 -0
  176. package/src/services/project-root.service.test.ts +506 -0
  177. package/src/services/project-root.service.ts +112 -0
  178. package/src/services/search.service.test.ts +1105 -0
  179. package/src/services/search.service.ts +892 -0
  180. package/src/services/services.test.ts +38 -0
  181. package/src/services/snippet.service.test.ts +205 -0
  182. package/src/services/snippet.service.ts +166 -0
  183. package/src/services/store.service.test.ts +474 -0
  184. package/src/services/store.service.ts +225 -0
  185. package/src/services/watch.service.test.ts +553 -0
  186. package/src/services/watch.service.ts +71 -0
  187. package/src/types/brands.test.ts +45 -0
  188. package/src/types/brands.ts +32 -0
  189. package/src/types/config.ts +79 -0
  190. package/src/types/document.ts +30 -0
  191. package/src/types/index.ts +66 -0
  192. package/src/types/job.ts +46 -0
  193. package/src/types/progress.ts +9 -0
  194. package/src/types/result.test.ts +44 -0
  195. package/src/types/result.ts +41 -0
  196. package/src/types/search.ts +95 -0
  197. package/src/types/store.test.ts +69 -0
  198. package/src/types/store.ts +47 -0
  199. package/src/utils/type-guards.test.ts +346 -0
  200. package/src/utils/type-guards.ts +61 -0
  201. package/src/workers/background-worker-cli.ts +105 -0
  202. package/src/workers/background-worker.test.ts +178 -0
  203. package/src/workers/background-worker.ts +294 -0
  204. package/src/workers/spawn-worker.test.ts +128 -0
  205. package/src/workers/spawn-worker.ts +49 -0
  206. package/tests/analysis/ast-parser.test.ts +98 -0
  207. package/tests/analysis/code-graph.test.ts +60 -0
  208. package/tests/fixtures/README.md +114 -0
  209. package/tests/fixtures/code-snippets/api/error-handling.ts +267 -0
  210. package/tests/fixtures/code-snippets/api/rest-controller.ts +303 -0
  211. package/tests/fixtures/code-snippets/auth/jwt-auth.ts +213 -0
  212. package/tests/fixtures/code-snippets/auth/oauth-flow.ts +245 -0
  213. package/tests/fixtures/code-snippets/database/repository-pattern.ts +272 -0
  214. package/tests/fixtures/corpus/VERSION.md +25 -0
  215. package/tests/fixtures/corpus/articles/jwt-authentication.md +97 -0
  216. package/tests/fixtures/corpus/articles/react-hooks-patterns.md +127 -0
  217. package/tests/fixtures/corpus/articles/typescript-generics.md +111 -0
  218. package/tests/fixtures/corpus/documentation/express-middleware.md +71 -0
  219. package/tests/fixtures/corpus/documentation/express-routing.md +83 -0
  220. package/tests/fixtures/corpus/documentation/node-streams.md +78 -0
  221. package/tests/fixtures/corpus/oss-repos/express/History.md +3871 -0
  222. package/tests/fixtures/corpus/oss-repos/express/LICENSE +24 -0
  223. package/tests/fixtures/corpus/oss-repos/express/Readme.md +276 -0
  224. package/tests/fixtures/corpus/oss-repos/express/SECURITY.md +56 -0
  225. package/tests/fixtures/corpus/oss-repos/express/benchmarks/Makefile +17 -0
  226. package/tests/fixtures/corpus/oss-repos/express/benchmarks/README.md +34 -0
  227. package/tests/fixtures/corpus/oss-repos/express/benchmarks/middleware.js +20 -0
  228. package/tests/fixtures/corpus/oss-repos/express/benchmarks/run +18 -0
  229. package/tests/fixtures/corpus/oss-repos/express/examples/README.md +29 -0
  230. package/tests/fixtures/corpus/oss-repos/express/examples/auth/index.js +134 -0
  231. package/tests/fixtures/corpus/oss-repos/express/examples/auth/views/foot.ejs +2 -0
  232. package/tests/fixtures/corpus/oss-repos/express/examples/auth/views/head.ejs +20 -0
  233. package/tests/fixtures/corpus/oss-repos/express/examples/auth/views/login.ejs +21 -0
  234. package/tests/fixtures/corpus/oss-repos/express/examples/content-negotiation/db.js +9 -0
  235. package/tests/fixtures/corpus/oss-repos/express/examples/content-negotiation/index.js +46 -0
  236. package/tests/fixtures/corpus/oss-repos/express/examples/content-negotiation/users.js +19 -0
  237. package/tests/fixtures/corpus/oss-repos/express/examples/cookie-sessions/index.js +25 -0
  238. package/tests/fixtures/corpus/oss-repos/express/examples/cookies/index.js +53 -0
  239. package/tests/fixtures/corpus/oss-repos/express/examples/downloads/files/CCTV/345/244/247/350/265/233/344/270/212/346/265/267/345/210/206/350/265/233/345/214/272.txt +2 -0
  240. package/tests/fixtures/corpus/oss-repos/express/examples/downloads/files/amazing.txt +1 -0
  241. package/tests/fixtures/corpus/oss-repos/express/examples/downloads/files/notes/groceries.txt +3 -0
  242. package/tests/fixtures/corpus/oss-repos/express/examples/downloads/index.js +40 -0
  243. package/tests/fixtures/corpus/oss-repos/express/examples/ejs/index.js +57 -0
  244. package/tests/fixtures/corpus/oss-repos/express/examples/ejs/public/stylesheets/style.css +4 -0
  245. package/tests/fixtures/corpus/oss-repos/express/examples/ejs/views/footer.html +2 -0
  246. package/tests/fixtures/corpus/oss-repos/express/examples/ejs/views/header.html +9 -0
  247. package/tests/fixtures/corpus/oss-repos/express/examples/ejs/views/users.html +10 -0
  248. package/tests/fixtures/corpus/oss-repos/express/examples/error/index.js +53 -0
  249. package/tests/fixtures/corpus/oss-repos/express/examples/error-pages/index.js +103 -0
  250. package/tests/fixtures/corpus/oss-repos/express/examples/error-pages/views/404.ejs +3 -0
  251. package/tests/fixtures/corpus/oss-repos/express/examples/error-pages/views/500.ejs +8 -0
  252. package/tests/fixtures/corpus/oss-repos/express/examples/error-pages/views/error_header.ejs +10 -0
  253. package/tests/fixtures/corpus/oss-repos/express/examples/error-pages/views/footer.ejs +2 -0
  254. package/tests/fixtures/corpus/oss-repos/express/examples/error-pages/views/index.ejs +20 -0
  255. package/tests/fixtures/corpus/oss-repos/express/examples/hello-world/index.js +15 -0
  256. package/tests/fixtures/corpus/oss-repos/express/examples/markdown/index.js +44 -0
  257. package/tests/fixtures/corpus/oss-repos/express/examples/markdown/views/index.md +4 -0
  258. package/tests/fixtures/corpus/oss-repos/express/examples/multi-router/controllers/api_v1.js +15 -0
  259. package/tests/fixtures/corpus/oss-repos/express/examples/multi-router/controllers/api_v2.js +15 -0
  260. package/tests/fixtures/corpus/oss-repos/express/examples/multi-router/index.js +18 -0
  261. package/tests/fixtures/corpus/oss-repos/express/examples/mvc/controllers/main/index.js +5 -0
  262. package/tests/fixtures/corpus/oss-repos/express/examples/mvc/controllers/pet/index.js +31 -0
  263. package/tests/fixtures/corpus/oss-repos/express/examples/mvc/controllers/pet/views/edit.ejs +17 -0
  264. package/tests/fixtures/corpus/oss-repos/express/examples/mvc/controllers/pet/views/show.ejs +15 -0
  265. package/tests/fixtures/corpus/oss-repos/express/examples/mvc/controllers/user/index.js +41 -0
  266. package/tests/fixtures/corpus/oss-repos/express/examples/mvc/controllers/user/views/edit.hbs +27 -0
  267. package/tests/fixtures/corpus/oss-repos/express/examples/mvc/controllers/user/views/list.hbs +18 -0
  268. package/tests/fixtures/corpus/oss-repos/express/examples/mvc/controllers/user/views/show.hbs +31 -0
  269. package/tests/fixtures/corpus/oss-repos/express/examples/mvc/controllers/user-pet/index.js +22 -0
  270. package/tests/fixtures/corpus/oss-repos/express/examples/mvc/db.js +16 -0
  271. package/tests/fixtures/corpus/oss-repos/express/examples/mvc/index.js +95 -0
  272. package/tests/fixtures/corpus/oss-repos/express/examples/mvc/lib/boot.js +83 -0
  273. package/tests/fixtures/corpus/oss-repos/express/examples/mvc/public/style.css +14 -0
  274. package/tests/fixtures/corpus/oss-repos/express/examples/mvc/views/404.ejs +13 -0
  275. package/tests/fixtures/corpus/oss-repos/express/examples/mvc/views/5xx.ejs +13 -0
  276. package/tests/fixtures/corpus/oss-repos/express/examples/online/index.js +61 -0
  277. package/tests/fixtures/corpus/oss-repos/express/examples/params/index.js +74 -0
  278. package/tests/fixtures/corpus/oss-repos/express/examples/resource/index.js +95 -0
  279. package/tests/fixtures/corpus/oss-repos/express/examples/route-map/index.js +75 -0
  280. package/tests/fixtures/corpus/oss-repos/express/examples/route-middleware/index.js +90 -0
  281. package/tests/fixtures/corpus/oss-repos/express/examples/route-separation/index.js +55 -0
  282. package/tests/fixtures/corpus/oss-repos/express/examples/route-separation/post.js +13 -0
  283. package/tests/fixtures/corpus/oss-repos/express/examples/route-separation/public/style.css +24 -0
  284. package/tests/fixtures/corpus/oss-repos/express/examples/route-separation/site.js +5 -0
  285. package/tests/fixtures/corpus/oss-repos/express/examples/route-separation/user.js +47 -0
  286. package/tests/fixtures/corpus/oss-repos/express/examples/route-separation/views/footer.ejs +2 -0
  287. package/tests/fixtures/corpus/oss-repos/express/examples/route-separation/views/header.ejs +9 -0
  288. package/tests/fixtures/corpus/oss-repos/express/examples/route-separation/views/index.ejs +10 -0
  289. package/tests/fixtures/corpus/oss-repos/express/examples/route-separation/views/posts/index.ejs +12 -0
  290. package/tests/fixtures/corpus/oss-repos/express/examples/route-separation/views/users/edit.ejs +23 -0
  291. package/tests/fixtures/corpus/oss-repos/express/examples/route-separation/views/users/index.ejs +14 -0
  292. package/tests/fixtures/corpus/oss-repos/express/examples/route-separation/views/users/view.ejs +9 -0
  293. package/tests/fixtures/corpus/oss-repos/express/examples/search/index.js +61 -0
  294. package/tests/fixtures/corpus/oss-repos/express/examples/search/public/client.js +15 -0
  295. package/tests/fixtures/corpus/oss-repos/express/examples/search/public/index.html +21 -0
  296. package/tests/fixtures/corpus/oss-repos/express/examples/session/index.js +37 -0
  297. package/tests/fixtures/corpus/oss-repos/express/examples/session/redis.js +39 -0
  298. package/tests/fixtures/corpus/oss-repos/express/examples/static-files/index.js +43 -0
  299. package/tests/fixtures/corpus/oss-repos/express/examples/static-files/public/css/style.css +3 -0
  300. package/tests/fixtures/corpus/oss-repos/express/examples/static-files/public/hello.txt +1 -0
  301. package/tests/fixtures/corpus/oss-repos/express/examples/static-files/public/js/app.js +1 -0
  302. package/tests/fixtures/corpus/oss-repos/express/examples/vhost/index.js +53 -0
  303. package/tests/fixtures/corpus/oss-repos/express/examples/view-constructor/github-view.js +53 -0
  304. package/tests/fixtures/corpus/oss-repos/express/examples/view-constructor/index.js +48 -0
  305. package/tests/fixtures/corpus/oss-repos/express/examples/view-locals/index.js +155 -0
  306. package/tests/fixtures/corpus/oss-repos/express/examples/view-locals/user.js +36 -0
  307. package/tests/fixtures/corpus/oss-repos/express/examples/view-locals/views/index.ejs +20 -0
  308. package/tests/fixtures/corpus/oss-repos/express/examples/web-service/index.js +117 -0
  309. package/tests/fixtures/corpus/oss-repos/express/index.js +11 -0
  310. package/tests/fixtures/corpus/oss-repos/express/lib/application.js +631 -0
  311. package/tests/fixtures/corpus/oss-repos/express/lib/express.js +81 -0
  312. package/tests/fixtures/corpus/oss-repos/express/lib/request.js +514 -0
  313. package/tests/fixtures/corpus/oss-repos/express/lib/response.js +1053 -0
  314. package/tests/fixtures/corpus/oss-repos/express/lib/utils.js +271 -0
  315. package/tests/fixtures/corpus/oss-repos/express/lib/view.js +205 -0
  316. package/tests/fixtures/corpus/oss-repos/express/package.json +99 -0
  317. package/tests/fixtures/corpus/oss-repos/express/test/Route.js +274 -0
  318. package/tests/fixtures/corpus/oss-repos/express/test/Router.js +636 -0
  319. package/tests/fixtures/corpus/oss-repos/express/test/acceptance/auth.js +117 -0
  320. package/tests/fixtures/corpus/oss-repos/express/test/acceptance/content-negotiation.js +49 -0
  321. package/tests/fixtures/corpus/oss-repos/express/test/acceptance/cookie-sessions.js +38 -0
  322. package/tests/fixtures/corpus/oss-repos/express/test/acceptance/cookies.js +71 -0
  323. package/tests/fixtures/corpus/oss-repos/express/test/acceptance/downloads.js +47 -0
  324. package/tests/fixtures/corpus/oss-repos/express/test/acceptance/ejs.js +17 -0
  325. package/tests/fixtures/corpus/oss-repos/express/test/acceptance/error-pages.js +99 -0
  326. package/tests/fixtures/corpus/oss-repos/express/test/acceptance/error.js +29 -0
  327. package/tests/fixtures/corpus/oss-repos/express/test/acceptance/hello-world.js +21 -0
  328. package/tests/fixtures/corpus/oss-repos/express/test/acceptance/markdown.js +21 -0
  329. package/tests/fixtures/corpus/oss-repos/express/test/acceptance/multi-router.js +44 -0
  330. package/tests/fixtures/corpus/oss-repos/express/test/acceptance/mvc.js +132 -0
  331. package/tests/fixtures/corpus/oss-repos/express/test/acceptance/params.js +44 -0
  332. package/tests/fixtures/corpus/oss-repos/express/test/acceptance/resource.js +68 -0
  333. package/tests/fixtures/corpus/oss-repos/express/test/acceptance/route-map.js +45 -0
  334. package/tests/fixtures/corpus/oss-repos/express/test/acceptance/route-separation.js +97 -0
  335. package/tests/fixtures/corpus/oss-repos/express/test/acceptance/vhost.js +46 -0
  336. package/tests/fixtures/corpus/oss-repos/express/test/acceptance/web-service.js +105 -0
  337. package/tests/fixtures/corpus/oss-repos/express/test/app.all.js +38 -0
  338. package/tests/fixtures/corpus/oss-repos/express/test/app.engine.js +83 -0
  339. package/tests/fixtures/corpus/oss-repos/express/test/app.head.js +66 -0
  340. package/tests/fixtures/corpus/oss-repos/express/test/app.js +120 -0
  341. package/tests/fixtures/corpus/oss-repos/express/test/app.listen.js +55 -0
  342. package/tests/fixtures/corpus/oss-repos/express/test/app.locals.js +26 -0
  343. package/tests/fixtures/corpus/oss-repos/express/test/app.options.js +116 -0
  344. package/tests/fixtures/corpus/oss-repos/express/test/app.param.js +323 -0
  345. package/tests/fixtures/corpus/oss-repos/express/test/app.render.js +374 -0
  346. package/tests/fixtures/corpus/oss-repos/express/test/app.request.js +143 -0
  347. package/tests/fixtures/corpus/oss-repos/express/test/app.response.js +143 -0
  348. package/tests/fixtures/corpus/oss-repos/express/test/app.route.js +197 -0
  349. package/tests/fixtures/corpus/oss-repos/express/test/app.router.js +1217 -0
  350. package/tests/fixtures/corpus/oss-repos/express/test/app.routes.error.js +62 -0
  351. package/tests/fixtures/corpus/oss-repos/express/test/app.use.js +542 -0
  352. package/tests/fixtures/corpus/oss-repos/express/test/config.js +207 -0
  353. package/tests/fixtures/corpus/oss-repos/express/test/exports.js +82 -0
  354. package/tests/fixtures/corpus/oss-repos/express/test/express.json.js +755 -0
  355. package/tests/fixtures/corpus/oss-repos/express/test/express.raw.js +513 -0
  356. package/tests/fixtures/corpus/oss-repos/express/test/express.static.js +815 -0
  357. package/tests/fixtures/corpus/oss-repos/express/test/express.text.js +566 -0
  358. package/tests/fixtures/corpus/oss-repos/express/test/express.urlencoded.js +828 -0
  359. package/tests/fixtures/corpus/oss-repos/express/test/fixtures/% of dogs.txt +1 -0
  360. package/tests/fixtures/corpus/oss-repos/express/test/fixtures/.name +1 -0
  361. package/tests/fixtures/corpus/oss-repos/express/test/fixtures/blog/index.html +1 -0
  362. package/tests/fixtures/corpus/oss-repos/express/test/fixtures/blog/post/index.tmpl +1 -0
  363. package/tests/fixtures/corpus/oss-repos/express/test/fixtures/broken.send +0 -0
  364. package/tests/fixtures/corpus/oss-repos/express/test/fixtures/default_layout/name.tmpl +1 -0
  365. package/tests/fixtures/corpus/oss-repos/express/test/fixtures/default_layout/user.tmpl +1 -0
  366. package/tests/fixtures/corpus/oss-repos/express/test/fixtures/email.tmpl +1 -0
  367. package/tests/fixtures/corpus/oss-repos/express/test/fixtures/empty.txt +0 -0
  368. package/tests/fixtures/corpus/oss-repos/express/test/fixtures/local_layout/user.tmpl +1 -0
  369. package/tests/fixtures/corpus/oss-repos/express/test/fixtures/name.tmpl +1 -0
  370. package/tests/fixtures/corpus/oss-repos/express/test/fixtures/name.txt +1 -0
  371. package/tests/fixtures/corpus/oss-repos/express/test/fixtures/nums.txt +1 -0
  372. package/tests/fixtures/corpus/oss-repos/express/test/fixtures/pets/names.txt +1 -0
  373. package/tests/fixtures/corpus/oss-repos/express/test/fixtures/snow /342/230/203/.gitkeep +0 -0
  374. package/tests/fixtures/corpus/oss-repos/express/test/fixtures/todo.html +1 -0
  375. package/tests/fixtures/corpus/oss-repos/express/test/fixtures/todo.txt +1 -0
  376. package/tests/fixtures/corpus/oss-repos/express/test/fixtures/user.html +1 -0
  377. package/tests/fixtures/corpus/oss-repos/express/test/fixtures/user.tmpl +1 -0
  378. package/tests/fixtures/corpus/oss-repos/express/test/fixtures/users/index.html +1 -0
  379. package/tests/fixtures/corpus/oss-repos/express/test/fixtures/users/tobi.txt +1 -0
  380. package/tests/fixtures/corpus/oss-repos/express/test/middleware.basic.js +42 -0
  381. package/tests/fixtures/corpus/oss-repos/express/test/regression.js +20 -0
  382. package/tests/fixtures/corpus/oss-repos/express/test/req.accepts.js +125 -0
  383. package/tests/fixtures/corpus/oss-repos/express/test/req.acceptsCharsets.js +50 -0
  384. package/tests/fixtures/corpus/oss-repos/express/test/req.acceptsEncodings.js +39 -0
  385. package/tests/fixtures/corpus/oss-repos/express/test/req.acceptsLanguages.js +57 -0
  386. package/tests/fixtures/corpus/oss-repos/express/test/req.baseUrl.js +88 -0
  387. package/tests/fixtures/corpus/oss-repos/express/test/req.fresh.js +70 -0
  388. package/tests/fixtures/corpus/oss-repos/express/test/req.get.js +60 -0
  389. package/tests/fixtures/corpus/oss-repos/express/test/req.host.js +156 -0
  390. package/tests/fixtures/corpus/oss-repos/express/test/req.hostname.js +188 -0
  391. package/tests/fixtures/corpus/oss-repos/express/test/req.ip.js +113 -0
  392. package/tests/fixtures/corpus/oss-repos/express/test/req.ips.js +71 -0
  393. package/tests/fixtures/corpus/oss-repos/express/test/req.is.js +169 -0
  394. package/tests/fixtures/corpus/oss-repos/express/test/req.path.js +20 -0
  395. package/tests/fixtures/corpus/oss-repos/express/test/req.protocol.js +113 -0
  396. package/tests/fixtures/corpus/oss-repos/express/test/req.query.js +106 -0
  397. package/tests/fixtures/corpus/oss-repos/express/test/req.range.js +104 -0
  398. package/tests/fixtures/corpus/oss-repos/express/test/req.route.js +28 -0
  399. package/tests/fixtures/corpus/oss-repos/express/test/req.secure.js +101 -0
  400. package/tests/fixtures/corpus/oss-repos/express/test/req.signedCookies.js +37 -0
  401. package/tests/fixtures/corpus/oss-repos/express/test/req.stale.js +50 -0
  402. package/tests/fixtures/corpus/oss-repos/express/test/req.subdomains.js +173 -0
  403. package/tests/fixtures/corpus/oss-repos/express/test/req.xhr.js +42 -0
  404. package/tests/fixtures/corpus/oss-repos/express/test/res.append.js +116 -0
  405. package/tests/fixtures/corpus/oss-repos/express/test/res.attachment.js +79 -0
  406. package/tests/fixtures/corpus/oss-repos/express/test/res.clearCookie.js +62 -0
  407. package/tests/fixtures/corpus/oss-repos/express/test/res.cookie.js +295 -0
  408. package/tests/fixtures/corpus/oss-repos/express/test/res.download.js +487 -0
  409. package/tests/fixtures/corpus/oss-repos/express/test/res.format.js +248 -0
  410. package/tests/fixtures/corpus/oss-repos/express/test/res.get.js +21 -0
  411. package/tests/fixtures/corpus/oss-repos/express/test/res.json.js +186 -0
  412. package/tests/fixtures/corpus/oss-repos/express/test/res.jsonp.js +344 -0
  413. package/tests/fixtures/corpus/oss-repos/express/test/res.links.js +65 -0
  414. package/tests/fixtures/corpus/oss-repos/express/test/res.locals.js +40 -0
  415. package/tests/fixtures/corpus/oss-repos/express/test/res.location.js +316 -0
  416. package/tests/fixtures/corpus/oss-repos/express/test/res.redirect.js +214 -0
  417. package/tests/fixtures/corpus/oss-repos/express/test/res.render.js +367 -0
  418. package/tests/fixtures/corpus/oss-repos/express/test/res.send.js +569 -0
  419. package/tests/fixtures/corpus/oss-repos/express/test/res.sendFile.js +913 -0
  420. package/tests/fixtures/corpus/oss-repos/express/test/res.sendStatus.js +44 -0
  421. package/tests/fixtures/corpus/oss-repos/express/test/res.set.js +124 -0
  422. package/tests/fixtures/corpus/oss-repos/express/test/res.status.js +206 -0
  423. package/tests/fixtures/corpus/oss-repos/express/test/res.type.js +46 -0
  424. package/tests/fixtures/corpus/oss-repos/express/test/res.vary.js +90 -0
  425. package/tests/fixtures/corpus/oss-repos/express/test/support/env.js +3 -0
  426. package/tests/fixtures/corpus/oss-repos/express/test/support/tmpl.js +36 -0
  427. package/tests/fixtures/corpus/oss-repos/express/test/support/utils.js +86 -0
  428. package/tests/fixtures/corpus/oss-repos/express/test/utils.js +83 -0
  429. package/tests/fixtures/corpus/oss-repos/hono/.devcontainer/Dockerfile +11 -0
  430. package/tests/fixtures/corpus/oss-repos/hono/.devcontainer/devcontainer.json +21 -0
  431. package/tests/fixtures/corpus/oss-repos/hono/.devcontainer/docker-compose.yml +18 -0
  432. package/tests/fixtures/corpus/oss-repos/hono/.eslintignore +1 -0
  433. package/tests/fixtures/corpus/oss-repos/hono/.eslintrc.cjs +9 -0
  434. package/tests/fixtures/corpus/oss-repos/hono/.gitpod.yml +9 -0
  435. package/tests/fixtures/corpus/oss-repos/hono/.prettierrc +9 -0
  436. package/tests/fixtures/corpus/oss-repos/hono/.vitest.config/jsx-runtime-default.ts +15 -0
  437. package/tests/fixtures/corpus/oss-repos/hono/.vitest.config/jsx-runtime-dom.ts +15 -0
  438. package/tests/fixtures/corpus/oss-repos/hono/.vitest.config/setup-vitest.ts +47 -0
  439. package/tests/fixtures/corpus/oss-repos/hono/LICENSE +21 -0
  440. package/tests/fixtures/corpus/oss-repos/hono/README.md +91 -0
  441. package/tests/fixtures/corpus/oss-repos/hono/build.ts +80 -0
  442. package/tests/fixtures/corpus/oss-repos/hono/bun.lockb +0 -0
  443. package/tests/fixtures/corpus/oss-repos/hono/bunfig.toml +7 -0
  444. package/tests/fixtures/corpus/oss-repos/hono/codecov.yml +13 -0
  445. package/tests/fixtures/corpus/oss-repos/hono/docs/CODE_OF_CONDUCT.md +128 -0
  446. package/tests/fixtures/corpus/oss-repos/hono/docs/CONTRIBUTING.md +62 -0
  447. package/tests/fixtures/corpus/oss-repos/hono/docs/MIGRATION.md +295 -0
  448. package/tests/fixtures/corpus/oss-repos/hono/docs/images/hono-logo.png +0 -0
  449. package/tests/fixtures/corpus/oss-repos/hono/docs/images/hono-logo.pxm +0 -0
  450. package/tests/fixtures/corpus/oss-repos/hono/docs/images/hono-logo.svg +6 -0
  451. package/tests/fixtures/corpus/oss-repos/hono/docs/images/hono-title.png +0 -0
  452. package/tests/fixtures/corpus/oss-repos/hono/docs/images/hono-title.pxm +0 -0
  453. package/tests/fixtures/corpus/oss-repos/hono/jsr.json +119 -0
  454. package/tests/fixtures/corpus/oss-repos/hono/package.cjs.json +3 -0
  455. package/tests/fixtures/corpus/oss-repos/hono/package.json +650 -0
  456. package/tests/fixtures/corpus/oss-repos/hono/src/adapter/aws-lambda/handler.ts +492 -0
  457. package/tests/fixtures/corpus/oss-repos/hono/src/adapter/aws-lambda/index.ts +13 -0
  458. package/tests/fixtures/corpus/oss-repos/hono/src/adapter/aws-lambda/types.ts +144 -0
  459. package/tests/fixtures/corpus/oss-repos/hono/src/adapter/bun/conninfo.ts +28 -0
  460. package/tests/fixtures/corpus/oss-repos/hono/src/adapter/bun/index.ts +9 -0
  461. package/tests/fixtures/corpus/oss-repos/hono/src/adapter/bun/serve-static.ts +35 -0
  462. package/tests/fixtures/corpus/oss-repos/hono/src/adapter/bun/server.ts +30 -0
  463. package/tests/fixtures/corpus/oss-repos/hono/src/adapter/bun/ssg.ts +27 -0
  464. package/tests/fixtures/corpus/oss-repos/hono/src/adapter/bun/websocket.ts +110 -0
  465. package/tests/fixtures/corpus/oss-repos/hono/src/adapter/cloudflare-pages/handler.ts +120 -0
  466. package/tests/fixtures/corpus/oss-repos/hono/src/adapter/cloudflare-pages/index.ts +7 -0
  467. package/tests/fixtures/corpus/oss-repos/hono/src/adapter/cloudflare-workers/conninfo.ts +7 -0
  468. package/tests/fixtures/corpus/oss-repos/hono/src/adapter/cloudflare-workers/index.ts +8 -0
  469. package/tests/fixtures/corpus/oss-repos/hono/src/adapter/cloudflare-workers/serve-static-module.ts +12 -0
  470. package/tests/fixtures/corpus/oss-repos/hono/src/adapter/cloudflare-workers/serve-static.ts +39 -0
  471. package/tests/fixtures/corpus/oss-repos/hono/src/adapter/cloudflare-workers/utils.ts +50 -0
  472. package/tests/fixtures/corpus/oss-repos/hono/src/adapter/cloudflare-workers/websocket.ts +50 -0
  473. package/tests/fixtures/corpus/oss-repos/hono/src/adapter/deno/conninfo.ts +17 -0
  474. package/tests/fixtures/corpus/oss-repos/hono/src/adapter/deno/deno.d.ts +28 -0
  475. package/tests/fixtures/corpus/oss-repos/hono/src/adapter/deno/index.ts +9 -0
  476. package/tests/fixtures/corpus/oss-repos/hono/src/adapter/deno/serve-static.ts +40 -0
  477. package/tests/fixtures/corpus/oss-repos/hono/src/adapter/deno/ssg.ts +27 -0
  478. package/tests/fixtures/corpus/oss-repos/hono/src/adapter/deno/websocket.ts +51 -0
  479. package/tests/fixtures/corpus/oss-repos/hono/src/adapter/lambda-edge/conninfo.ts +15 -0
  480. package/tests/fixtures/corpus/oss-repos/hono/src/adapter/lambda-edge/handler.ts +189 -0
  481. package/tests/fixtures/corpus/oss-repos/hono/src/adapter/lambda-edge/index.ts +14 -0
  482. package/tests/fixtures/corpus/oss-repos/hono/src/adapter/netlify/handler.ts +10 -0
  483. package/tests/fixtures/corpus/oss-repos/hono/src/adapter/netlify/index.ts +6 -0
  484. package/tests/fixtures/corpus/oss-repos/hono/src/adapter/netlify/mod.ts +1 -0
  485. package/tests/fixtures/corpus/oss-repos/hono/src/adapter/service-worker/handler.ts +34 -0
  486. package/tests/fixtures/corpus/oss-repos/hono/src/adapter/service-worker/index.ts +5 -0
  487. package/tests/fixtures/corpus/oss-repos/hono/src/adapter/service-worker/types.ts +14 -0
  488. package/tests/fixtures/corpus/oss-repos/hono/src/adapter/vercel/conninfo.ts +8 -0
  489. package/tests/fixtures/corpus/oss-repos/hono/src/adapter/vercel/handler.ts +9 -0
  490. package/tests/fixtures/corpus/oss-repos/hono/src/adapter/vercel/index.ts +7 -0
  491. package/tests/fixtures/corpus/oss-repos/hono/src/client/client.ts +214 -0
  492. package/tests/fixtures/corpus/oss-repos/hono/src/client/index.ts +14 -0
  493. package/tests/fixtures/corpus/oss-repos/hono/src/client/types.ts +180 -0
  494. package/tests/fixtures/corpus/oss-repos/hono/src/client/utils.ts +54 -0
  495. package/tests/fixtures/corpus/oss-repos/hono/src/compose.ts +94 -0
  496. package/tests/fixtures/corpus/oss-repos/hono/src/context.ts +914 -0
  497. package/tests/fixtures/corpus/oss-repos/hono/src/helper/accepts/accepts.ts +81 -0
  498. package/tests/fixtures/corpus/oss-repos/hono/src/helper/accepts/index.ts +6 -0
  499. package/tests/fixtures/corpus/oss-repos/hono/src/helper/adapter/index.ts +85 -0
  500. package/tests/fixtures/corpus/oss-repos/hono/src/helper/conninfo/index.ts +6 -0
  501. package/tests/fixtures/corpus/oss-repos/hono/src/helper/conninfo/types.ts +45 -0
  502. package/tests/fixtures/corpus/oss-repos/hono/src/helper/cookie/index.ts +130 -0
  503. package/tests/fixtures/corpus/oss-repos/hono/src/helper/css/common.ts +243 -0
  504. package/tests/fixtures/corpus/oss-repos/hono/src/helper/css/index.ts +220 -0
  505. package/tests/fixtures/corpus/oss-repos/hono/src/helper/dev/index.ts +79 -0
  506. package/tests/fixtures/corpus/oss-repos/hono/src/helper/factory/index.ts +246 -0
  507. package/tests/fixtures/corpus/oss-repos/hono/src/helper/html/index.ts +56 -0
  508. package/tests/fixtures/corpus/oss-repos/hono/src/helper/ssg/index.ts +13 -0
  509. package/tests/fixtures/corpus/oss-repos/hono/src/helper/ssg/middleware.ts +79 -0
  510. package/tests/fixtures/corpus/oss-repos/hono/src/helper/ssg/ssg.ts +388 -0
  511. package/tests/fixtures/corpus/oss-repos/hono/src/helper/ssg/utils.ts +71 -0
  512. package/tests/fixtures/corpus/oss-repos/hono/src/helper/streaming/index.ts +9 -0
  513. package/tests/fixtures/corpus/oss-repos/hono/src/helper/streaming/sse.ts +89 -0
  514. package/tests/fixtures/corpus/oss-repos/hono/src/helper/streaming/stream.ts +36 -0
  515. package/tests/fixtures/corpus/oss-repos/hono/src/helper/streaming/text.ts +15 -0
  516. package/tests/fixtures/corpus/oss-repos/hono/src/helper/testing/index.ts +26 -0
  517. package/tests/fixtures/corpus/oss-repos/hono/src/helper/websocket/index.ts +57 -0
  518. package/tests/fixtures/corpus/oss-repos/hono/src/hono-base.ts +523 -0
  519. package/tests/fixtures/corpus/oss-repos/hono/src/hono.ts +34 -0
  520. package/tests/fixtures/corpus/oss-repos/hono/src/http-exception.ts +78 -0
  521. package/tests/fixtures/corpus/oss-repos/hono/src/index.ts +51 -0
  522. package/tests/fixtures/corpus/oss-repos/hono/src/jsx/base.ts +419 -0
  523. package/tests/fixtures/corpus/oss-repos/hono/src/jsx/children.ts +20 -0
  524. package/tests/fixtures/corpus/oss-repos/hono/src/jsx/components.ts +195 -0
  525. package/tests/fixtures/corpus/oss-repos/hono/src/jsx/constants.ts +5 -0
  526. package/tests/fixtures/corpus/oss-repos/hono/src/jsx/context.ts +50 -0
  527. package/tests/fixtures/corpus/oss-repos/hono/src/jsx/dom/client.ts +89 -0
  528. package/tests/fixtures/corpus/oss-repos/hono/src/jsx/dom/components.ts +39 -0
  529. package/tests/fixtures/corpus/oss-repos/hono/src/jsx/dom/context.ts +52 -0
  530. package/tests/fixtures/corpus/oss-repos/hono/src/jsx/dom/css.ts +246 -0
  531. package/tests/fixtures/corpus/oss-repos/hono/src/jsx/dom/hooks/index.ts +91 -0
  532. package/tests/fixtures/corpus/oss-repos/hono/src/jsx/dom/index.ts +159 -0
  533. package/tests/fixtures/corpus/oss-repos/hono/src/jsx/dom/intrinsic-element/components.ts +398 -0
  534. package/tests/fixtures/corpus/oss-repos/hono/src/jsx/dom/jsx-dev-runtime.ts +22 -0
  535. package/tests/fixtures/corpus/oss-repos/hono/src/jsx/dom/jsx-runtime.ts +7 -0
  536. package/tests/fixtures/corpus/oss-repos/hono/src/jsx/dom/render.ts +772 -0
  537. package/tests/fixtures/corpus/oss-repos/hono/src/jsx/dom/server.ts +70 -0
  538. package/tests/fixtures/corpus/oss-repos/hono/src/jsx/dom/utils.ts +7 -0
  539. package/tests/fixtures/corpus/oss-repos/hono/src/jsx/hooks/index.ts +426 -0
  540. package/tests/fixtures/corpus/oss-repos/hono/src/jsx/index.ts +114 -0
  541. package/tests/fixtures/corpus/oss-repos/hono/src/jsx/intrinsic-element/common.ts +11 -0
  542. package/tests/fixtures/corpus/oss-repos/hono/src/jsx/intrinsic-element/components.ts +196 -0
  543. package/tests/fixtures/corpus/oss-repos/hono/src/jsx/intrinsic-elements.ts +924 -0
  544. package/tests/fixtures/corpus/oss-repos/hono/src/jsx/jsx-dev-runtime.ts +26 -0
  545. package/tests/fixtures/corpus/oss-repos/hono/src/jsx/jsx-runtime.ts +18 -0
  546. package/tests/fixtures/corpus/oss-repos/hono/src/jsx/streaming.ts +184 -0
  547. package/tests/fixtures/corpus/oss-repos/hono/src/jsx/types.ts +41 -0
  548. package/tests/fixtures/corpus/oss-repos/hono/src/jsx/utils.ts +36 -0
  549. package/tests/fixtures/corpus/oss-repos/hono/src/middleware/basic-auth/index.ts +128 -0
  550. package/tests/fixtures/corpus/oss-repos/hono/src/middleware/bearer-auth/index.ts +159 -0
  551. package/tests/fixtures/corpus/oss-repos/hono/src/middleware/body-limit/index.ts +115 -0
  552. package/tests/fixtures/corpus/oss-repos/hono/src/middleware/cache/index.ts +127 -0
  553. package/tests/fixtures/corpus/oss-repos/hono/src/middleware/combine/index.ts +153 -0
  554. package/tests/fixtures/corpus/oss-repos/hono/src/middleware/compress/index.ts +79 -0
  555. package/tests/fixtures/corpus/oss-repos/hono/src/middleware/context-storage/index.ts +55 -0
  556. package/tests/fixtures/corpus/oss-repos/hono/src/middleware/cors/index.ts +141 -0
  557. package/tests/fixtures/corpus/oss-repos/hono/src/middleware/csrf/index.ts +90 -0
  558. package/tests/fixtures/corpus/oss-repos/hono/src/middleware/etag/index.ts +88 -0
  559. package/tests/fixtures/corpus/oss-repos/hono/src/middleware/ip-restriction/index.ts +178 -0
  560. package/tests/fixtures/corpus/oss-repos/hono/src/middleware/jsx-renderer/index.ts +158 -0
  561. package/tests/fixtures/corpus/oss-repos/hono/src/middleware/jwt/index.ts +8 -0
  562. package/tests/fixtures/corpus/oss-repos/hono/src/middleware/jwt/jwt.ts +159 -0
  563. package/tests/fixtures/corpus/oss-repos/hono/src/middleware/logger/index.ts +93 -0
  564. package/tests/fixtures/corpus/oss-repos/hono/src/middleware/method-override/index.ts +146 -0
  565. package/tests/fixtures/corpus/oss-repos/hono/src/middleware/powered-by/index.ts +13 -0
  566. package/tests/fixtures/corpus/oss-repos/hono/src/middleware/pretty-json/index.ts +50 -0
  567. package/tests/fixtures/corpus/oss-repos/hono/src/middleware/request-id/index.ts +8 -0
  568. package/tests/fixtures/corpus/oss-repos/hono/src/middleware/request-id/request-id.ts +59 -0
  569. package/tests/fixtures/corpus/oss-repos/hono/src/middleware/secure-headers/index.ts +8 -0
  570. package/tests/fixtures/corpus/oss-repos/hono/src/middleware/secure-headers/permissions-policy.ts +86 -0
  571. package/tests/fixtures/corpus/oss-repos/hono/src/middleware/secure-headers/secure-headers.ts +319 -0
  572. package/tests/fixtures/corpus/oss-repos/hono/src/middleware/serve-static/index.ts +140 -0
  573. package/tests/fixtures/corpus/oss-repos/hono/src/middleware/timeout/index.ts +58 -0
  574. package/tests/fixtures/corpus/oss-repos/hono/src/middleware/timing/index.ts +7 -0
  575. package/tests/fixtures/corpus/oss-repos/hono/src/middleware/timing/timing.ts +225 -0
  576. package/tests/fixtures/corpus/oss-repos/hono/src/middleware/trailing-slash/index.ts +71 -0
  577. package/tests/fixtures/corpus/oss-repos/hono/src/preset/quick.ts +24 -0
  578. package/tests/fixtures/corpus/oss-repos/hono/src/preset/tiny.ts +20 -0
  579. package/tests/fixtures/corpus/oss-repos/hono/src/request.ts +403 -0
  580. package/tests/fixtures/corpus/oss-repos/hono/src/router/linear-router/index.ts +6 -0
  581. package/tests/fixtures/corpus/oss-repos/hono/src/router/linear-router/router.ts +132 -0
  582. package/tests/fixtures/corpus/oss-repos/hono/src/router/pattern-router/index.ts +6 -0
  583. package/tests/fixtures/corpus/oss-repos/hono/src/router/pattern-router/router.ts +54 -0
  584. package/tests/fixtures/corpus/oss-repos/hono/src/router/reg-exp-router/index.ts +6 -0
  585. package/tests/fixtures/corpus/oss-repos/hono/src/router/reg-exp-router/node.ts +159 -0
  586. package/tests/fixtures/corpus/oss-repos/hono/src/router/reg-exp-router/router.ts +274 -0
  587. package/tests/fixtures/corpus/oss-repos/hono/src/router/reg-exp-router/trie.ts +74 -0
  588. package/tests/fixtures/corpus/oss-repos/hono/src/router/smart-router/index.ts +6 -0
  589. package/tests/fixtures/corpus/oss-repos/hono/src/router/smart-router/router.ts +69 -0
  590. package/tests/fixtures/corpus/oss-repos/hono/src/router/trie-router/index.ts +6 -0
  591. package/tests/fixtures/corpus/oss-repos/hono/src/router/trie-router/node.ts +205 -0
  592. package/tests/fixtures/corpus/oss-repos/hono/src/router/trie-router/router.ts +28 -0
  593. package/tests/fixtures/corpus/oss-repos/hono/src/router.ts +103 -0
  594. package/tests/fixtures/corpus/oss-repos/hono/src/types.ts +2009 -0
  595. package/tests/fixtures/corpus/oss-repos/hono/src/utils/basic-auth.ts +26 -0
  596. package/tests/fixtures/corpus/oss-repos/hono/src/utils/body.ts +225 -0
  597. package/tests/fixtures/corpus/oss-repos/hono/src/utils/buffer.ts +65 -0
  598. package/tests/fixtures/corpus/oss-repos/hono/src/utils/color.ts +26 -0
  599. package/tests/fixtures/corpus/oss-repos/hono/src/utils/concurrent.ts +55 -0
  600. package/tests/fixtures/corpus/oss-repos/hono/src/utils/cookie.ts +230 -0
  601. package/tests/fixtures/corpus/oss-repos/hono/src/utils/crypto.ts +65 -0
  602. package/tests/fixtures/corpus/oss-repos/hono/src/utils/encode.ts +34 -0
  603. package/tests/fixtures/corpus/oss-repos/hono/src/utils/filepath.ts +56 -0
  604. package/tests/fixtures/corpus/oss-repos/hono/src/utils/handler.ts +15 -0
  605. package/tests/fixtures/corpus/oss-repos/hono/src/utils/html.ts +182 -0
  606. package/tests/fixtures/corpus/oss-repos/hono/src/utils/http-status.ts +69 -0
  607. package/tests/fixtures/corpus/oss-repos/hono/src/utils/ipaddr.ts +113 -0
  608. package/tests/fixtures/corpus/oss-repos/hono/src/utils/jwt/index.ts +7 -0
  609. package/tests/fixtures/corpus/oss-repos/hono/src/utils/jwt/jwa.ts +23 -0
  610. package/tests/fixtures/corpus/oss-repos/hono/src/utils/jwt/jws.ts +226 -0
  611. package/tests/fixtures/corpus/oss-repos/hono/src/utils/jwt/jwt.ts +114 -0
  612. package/tests/fixtures/corpus/oss-repos/hono/src/utils/jwt/types.ts +83 -0
  613. package/tests/fixtures/corpus/oss-repos/hono/src/utils/jwt/utf8.ts +7 -0
  614. package/tests/fixtures/corpus/oss-repos/hono/src/utils/mime.ts +142 -0
  615. package/tests/fixtures/corpus/oss-repos/hono/src/utils/stream.ts +96 -0
  616. package/tests/fixtures/corpus/oss-repos/hono/src/utils/types.ts +105 -0
  617. package/tests/fixtures/corpus/oss-repos/hono/src/utils/url.ts +310 -0
  618. package/tests/fixtures/corpus/oss-repos/hono/src/validator/index.ts +7 -0
  619. package/tests/fixtures/corpus/oss-repos/hono/src/validator/validator.ts +151 -0
  620. package/tests/fixtures/corpus/oss-repos/hono/tsconfig.build.json +23 -0
  621. package/tests/fixtures/corpus/oss-repos/hono/tsconfig.json +28 -0
  622. package/tests/fixtures/corpus/oss-repos/hono/vitest.config.ts +34 -0
  623. package/tests/fixtures/corpus/oss-repos/hono/yarn.lock +6232 -0
  624. package/tests/fixtures/documentation/api-reference.md +412 -0
  625. package/tests/fixtures/documentation/architecture.md +214 -0
  626. package/tests/fixtures/documentation/deployment-guide.md +420 -0
  627. package/tests/fixtures/github-readmes/express.md +133 -0
  628. package/tests/fixtures/github-readmes/nextjs.md +106 -0
  629. package/tests/fixtures/github-readmes/react.md +74 -0
  630. package/tests/fixtures/github-readmes/typescript.md +93 -0
  631. package/tests/fixtures/github-readmes/vite.md +79 -0
  632. package/tests/fixtures/queries/core.json +125 -0
  633. package/tests/fixtures/queries/extended.json +427 -0
  634. package/tests/fixtures/queries/generated/.gitkeep +0 -0
  635. package/tests/fixtures/test-server.ts +267 -0
  636. package/tests/helpers/performance-metrics.ts +387 -0
  637. package/tests/helpers/search-relevance.ts +381 -0
  638. package/tests/integration/cli-consistency.test.ts +299 -0
  639. package/tests/integration/cli.test.ts +69 -0
  640. package/tests/integration/e2e-workflow.test.ts +612 -0
  641. package/tests/integration/python-bridge.test.ts +183 -0
  642. package/tests/integration/search-quality.test.ts +718 -0
  643. package/tests/integration/stress.test.ts +326 -0
  644. package/tests/mcp/server.test.ts +15 -0
  645. package/tests/scripts/schemas/evaluation.json +44 -0
  646. package/tests/scripts/schemas/query-generation.json +21 -0
  647. package/tests/services/code-unit.service.test.ts +47 -0
  648. package/tests/services/search.progressive-context.test.ts +35 -0
  649. package/tsconfig.json +34 -0
  650. package/tsup.config.ts +15 -0
  651. package/turndown-plugin-gfm.d.ts +29 -0
  652. package/vitest.config.ts +79 -0
@@ -0,0 +1,892 @@
1
+ import type { LanceStore } from '../db/lance.js';
2
+ import type { EmbeddingEngine } from '../db/embeddings.js';
3
+ import type { SearchQuery, SearchResponse, SearchResult, DetailLevel } from '../types/search.js';
4
+ import type { StoreId } from '../types/brands.js';
5
+ import { CodeUnitService } from './code-unit.service.js';
6
+ import type { CodeUnit } from '../types/search.js';
7
+ import type { CodeGraphService } from './code-graph.service.js';
8
+ import type { CodeGraph } from '../analysis/code-graph.js';
9
+
10
+ /**
11
+ * Query intent classification for context-aware ranking.
12
+ * Phase 1: Different intents prioritize different content types.
13
+ */
14
+ export type QueryIntent = 'how-to' | 'implementation' | 'conceptual' | 'comparison' | 'debugging';
15
+
16
+ /**
17
+ * Intent-based file type multipliers - CONSERVATIVE version.
18
+ * Applied on top of base file-type boosts.
19
+ * Lessons learned: Too-aggressive penalties hurt when corpus lacks ideal content.
20
+ * These values provide gentle guidance rather than dramatic reranking.
21
+ */
22
+ const INTENT_FILE_BOOSTS: Record<QueryIntent, Record<string, number>> = {
23
+ 'how-to': {
24
+ 'documentation-primary': 1.3, // Strong boost for docs
25
+ 'documentation': 1.2,
26
+ 'example': 1.5, // Examples are ideal for "how to"
27
+ 'source': 0.85, // Moderate penalty - source might still have good content
28
+ 'source-internal': 0.7, // Stronger penalty - internal code less useful
29
+ 'test': 0.8,
30
+ 'config': 0.7,
31
+ 'other': 0.9,
32
+ },
33
+ 'implementation': {
34
+ 'documentation-primary': 0.95,
35
+ 'documentation': 1.0,
36
+ 'example': 1.0,
37
+ 'source': 1.1, // Slight boost for source code
38
+ 'source-internal': 1.05, // Internal code can be relevant
39
+ 'test': 1.0,
40
+ 'config': 0.95,
41
+ 'other': 1.0,
42
+ },
43
+ 'conceptual': {
44
+ 'documentation-primary': 1.1,
45
+ 'documentation': 1.05,
46
+ 'example': 1.0,
47
+ 'source': 0.95,
48
+ 'source-internal': 0.9,
49
+ 'test': 0.9,
50
+ 'config': 0.85,
51
+ 'other': 0.95,
52
+ },
53
+ 'comparison': {
54
+ 'documentation-primary': 1.15,
55
+ 'documentation': 1.1,
56
+ 'example': 1.05,
57
+ 'source': 0.9,
58
+ 'source-internal': 0.85,
59
+ 'test': 0.9,
60
+ 'config': 0.85,
61
+ 'other': 0.95,
62
+ },
63
+ 'debugging': {
64
+ 'documentation-primary': 1.0,
65
+ 'documentation': 1.0,
66
+ 'example': 1.05,
67
+ 'source': 1.0, // Source code helps with debugging
68
+ 'source-internal': 0.95,
69
+ 'test': 1.05, // Tests can show expected behavior
70
+ 'config': 0.9,
71
+ 'other': 1.0,
72
+ },
73
+ };
74
+
75
+ // Known frameworks/technologies for context-aware boosting
76
+ const FRAMEWORK_PATTERNS: Array<{ pattern: RegExp; terms: string[] }> = [
77
+ { pattern: /\bexpress\b/i, terms: ['express', 'expressjs', 'express.js'] },
78
+ { pattern: /\bhono\b/i, terms: ['hono'] },
79
+ { pattern: /\bzod\b/i, terms: ['zod'] },
80
+ { pattern: /\breact\b/i, terms: ['react', 'reactjs', 'react.js'] },
81
+ { pattern: /\bvue\b/i, terms: ['vue', 'vuejs', 'vue.js', 'vue3'] },
82
+ { pattern: /\bnode\b/i, terms: ['node', 'nodejs', 'node.js'] },
83
+ { pattern: /\btypescript\b/i, terms: ['typescript', 'ts'] },
84
+ { pattern: /\bjwt\b/i, terms: ['jwt', 'jsonwebtoken', 'json-web-token'] },
85
+ ];
86
+
87
+ /**
88
+ * Classify the intent of a search query.
89
+ * This helps adjust ranking based on what kind of answer the user wants.
90
+ */
91
+ function classifyQueryIntent(query: string): QueryIntent {
92
+ const q = query.toLowerCase();
93
+
94
+ // How-to patterns: user wants to learn how to use/do something
95
+ const howToPatterns = [
96
+ /how (do|can|should|would) (i|you|we)/i,
97
+ /how to\b/i,
98
+ /what('s| is) the (best |right |correct )?(way|approach) to/i,
99
+ /i (need|want|have) to/i,
100
+ /show me how/i,
101
+ /\bwhat's the syntax\b/i,
102
+ /\bhow do i (use|create|make|set up|configure|implement|add|get)\b/i,
103
+ /\bi'm (trying|building|creating|making)\b/i,
104
+ ];
105
+
106
+ // Implementation patterns: user wants to understand internals
107
+ const implementationPatterns = [
108
+ /how (does|is) .* (implemented|work internally)/i,
109
+ /\binternal(ly)?\b/i,
110
+ /\bsource code\b/i,
111
+ /\bunder the hood\b/i,
112
+ /\bimplementation (of|details?)\b/i,
113
+ ];
114
+
115
+ // Comparison patterns: user is deciding between options
116
+ const comparisonPatterns = [
117
+ /\b(vs\.?|versus)\b/i,
118
+ /\bdifference(s)? between\b/i,
119
+ /\bcompare\b/i,
120
+ /\bshould (i|we) use .* or\b/i,
121
+ /\bwhat's the difference\b/i,
122
+ /\bwhich (one|is better)\b/i,
123
+ /\bwhen (should|to) use\b/i,
124
+ ];
125
+
126
+ // Debugging patterns: user is troubleshooting a problem
127
+ const debuggingPatterns = [
128
+ /\b(error|bug|issue|problem|crash|fail|broken|wrong)\b/i,
129
+ /\bdoesn't (work|compile|run)\b/i,
130
+ /\bisn't (working|updating|rendering)\b/i,
131
+ /\bwhy (is|does|doesn't|isn't)\b/i,
132
+ /\bwhat('s| is) (wrong|happening|going on)\b/i,
133
+ /\bwhat am i doing wrong\b/i,
134
+ /\bnot (working|updating|showing)\b/i,
135
+ /\bhow do i (fix|debug|solve|resolve)\b/i,
136
+ ];
137
+
138
+ // Conceptual patterns: user wants to understand a concept
139
+ const conceptualPatterns = [
140
+ /\bwhat (is|are)\b/i,
141
+ /\bexplain\b/i,
142
+ /\bwhat does .* (mean|do)\b/i,
143
+ /\bhow does .* work\b/i,
144
+ /\bwhat('s| is) the (purpose|point|idea)\b/i,
145
+ ];
146
+
147
+ // Check patterns in order of specificity
148
+ if (implementationPatterns.some(p => p.test(q))) {
149
+ return 'implementation';
150
+ }
151
+
152
+ if (debuggingPatterns.some(p => p.test(q))) {
153
+ return 'debugging';
154
+ }
155
+
156
+ if (comparisonPatterns.some(p => p.test(q))) {
157
+ return 'comparison';
158
+ }
159
+
160
+ if (howToPatterns.some(p => p.test(q))) {
161
+ return 'how-to';
162
+ }
163
+
164
+ if (conceptualPatterns.some(p => p.test(q))) {
165
+ return 'conceptual';
166
+ }
167
+
168
+ // Default to how-to as most queries are seeking practical usage
169
+ return 'how-to';
170
+ }
171
+
172
+ interface RRFConfig {
173
+ k: number;
174
+ vectorWeight: number;
175
+ ftsWeight: number;
176
+ }
177
+
178
+ export class SearchService {
179
+ private readonly lanceStore: LanceStore;
180
+ private readonly embeddingEngine: EmbeddingEngine;
181
+ private readonly rrfConfig: RRFConfig;
182
+ private readonly codeUnitService: CodeUnitService;
183
+ private readonly codeGraphService: CodeGraphService | undefined;
184
+ private readonly graphCache: Map<string, CodeGraph | null>;
185
+
186
+ constructor(
187
+ lanceStore: LanceStore,
188
+ embeddingEngine: EmbeddingEngine,
189
+ // Lower k value (20 vs 60) produces more differentiated scores for top results
190
+ rrfConfig: RRFConfig = { k: 20, vectorWeight: 0.6, ftsWeight: 0.4 },
191
+ codeGraphService?: CodeGraphService
192
+ ) {
193
+ this.lanceStore = lanceStore;
194
+ this.embeddingEngine = embeddingEngine;
195
+ this.rrfConfig = rrfConfig;
196
+ this.codeUnitService = new CodeUnitService();
197
+ this.codeGraphService = codeGraphService;
198
+ this.graphCache = new Map();
199
+ }
200
+
201
+ /**
202
+ * Load code graph for a store, with caching.
203
+ * Returns null if no graph is available.
204
+ */
205
+ private async loadGraphForStore(storeId: StoreId): Promise<CodeGraph | null> {
206
+ if (!this.codeGraphService) return null;
207
+
208
+ const cached = this.graphCache.get(storeId);
209
+ if (cached !== undefined) return cached;
210
+
211
+ const graph = await this.codeGraphService.loadGraph(storeId);
212
+ const result = graph ?? null;
213
+ this.graphCache.set(storeId, result);
214
+ return result;
215
+ }
216
+
217
+ async search(query: SearchQuery): Promise<SearchResponse> {
218
+ const startTime = Date.now();
219
+ const mode = query.mode ?? 'hybrid';
220
+ const limit = query.limit ?? 10;
221
+ const stores = query.stores ?? [];
222
+ const detail = query.detail ?? 'minimal';
223
+
224
+ let allResults: SearchResult[] = [];
225
+
226
+ // Fetch more results than needed to allow for deduplication
227
+ const fetchLimit = limit * 3;
228
+
229
+ if (mode === 'vector') {
230
+ allResults = await this.vectorSearch(query.query, stores, fetchLimit, query.threshold);
231
+ } else if (mode === 'fts') {
232
+ allResults = await this.ftsSearch(query.query, stores, fetchLimit);
233
+ } else {
234
+ // Hybrid: combine vector and FTS with RRF
235
+ allResults = await this.hybridSearch(query.query, stores, fetchLimit, query.threshold);
236
+ }
237
+
238
+ // Deduplicate by source file - keep best chunk per source (considers query relevance)
239
+ const dedupedResults = this.deduplicateBySource(allResults, query.query);
240
+ const resultsToEnhance = dedupedResults.slice(0, limit);
241
+
242
+ // Load code graphs for stores in results (for contextual/full detail levels)
243
+ const graphs = new Map<string, CodeGraph | null>();
244
+ if (detail === 'contextual' || detail === 'full') {
245
+ const storeIds = new Set(resultsToEnhance.map(r => r.metadata.storeId));
246
+ for (const storeId of storeIds) {
247
+ graphs.set(storeId, await this.loadGraphForStore(storeId));
248
+ }
249
+ }
250
+
251
+ // Enhance results with progressive context
252
+ const enhancedResults = resultsToEnhance.map(r => {
253
+ const graph = graphs.get(r.metadata.storeId) ?? null;
254
+ return this.addProgressiveContext(r, query.query, detail, graph);
255
+ });
256
+
257
+ return {
258
+ query: query.query,
259
+ mode,
260
+ stores,
261
+ results: enhancedResults,
262
+ totalResults: enhancedResults.length,
263
+ timeMs: Date.now() - startTime,
264
+ };
265
+ }
266
+
267
+ /**
268
+ * Deduplicate results by source file path.
269
+ * Keeps the best chunk for each unique source, considering both score and query relevance.
270
+ */
271
+ private deduplicateBySource(results: SearchResult[], query: string): SearchResult[] {
272
+ const bySource = new Map<string, SearchResult>();
273
+ const queryTerms = query.toLowerCase().split(/\s+/).filter(t => t.length > 2);
274
+
275
+ for (const result of results) {
276
+ // Use file path as the source key, fallback to document ID
277
+ const sourceKey = result.metadata.path ?? result.metadata.url ?? result.id;
278
+
279
+ const existing = bySource.get(sourceKey);
280
+ if (!existing) {
281
+ bySource.set(sourceKey, result);
282
+ } else {
283
+ // Compare: prefer chunk with more query terms in content
284
+ const existingTermCount = this.countQueryTerms(existing.content, queryTerms);
285
+ const newTermCount = this.countQueryTerms(result.content, queryTerms);
286
+
287
+ // Prefer chunk with more query terms, or higher score if same
288
+ if (newTermCount > existingTermCount ||
289
+ (newTermCount === existingTermCount && result.score > existing.score)) {
290
+ bySource.set(sourceKey, result);
291
+ }
292
+ }
293
+ }
294
+
295
+ // Return results sorted by score
296
+ return Array.from(bySource.values()).sort((a, b) => b.score - a.score);
297
+ }
298
+
299
+ /**
300
+ * Count how many query terms appear in the content.
301
+ */
302
+ private countQueryTerms(content: string, queryTerms: string[]): number {
303
+ const lowerContent = content.toLowerCase();
304
+ return queryTerms.filter(term => lowerContent.includes(term)).length;
305
+ }
306
+
307
+ private async vectorSearch(
308
+ query: string,
309
+ stores: readonly StoreId[],
310
+ limit: number,
311
+ threshold?: number
312
+ ): Promise<SearchResult[]> {
313
+ const queryVector = await this.embeddingEngine.embed(query);
314
+ const results: SearchResult[] = [];
315
+
316
+ for (const storeId of stores) {
317
+ const hits = await this.lanceStore.search(storeId, queryVector, limit, threshold);
318
+ results.push(...hits.map(r => ({
319
+ id: r.id,
320
+ score: r.score,
321
+ content: r.content,
322
+ metadata: r.metadata,
323
+ })));
324
+ }
325
+
326
+ return results.sort((a, b) => b.score - a.score).slice(0, limit);
327
+ }
328
+
329
+ private async ftsSearch(
330
+ query: string,
331
+ stores: readonly StoreId[],
332
+ limit: number
333
+ ): Promise<SearchResult[]> {
334
+ const results: SearchResult[] = [];
335
+
336
+ for (const storeId of stores) {
337
+ const hits = await this.lanceStore.fullTextSearch(storeId, query, limit);
338
+ results.push(...hits.map(r => ({
339
+ id: r.id,
340
+ score: r.score,
341
+ content: r.content,
342
+ metadata: r.metadata,
343
+ })));
344
+ }
345
+
346
+ return results.sort((a, b) => b.score - a.score).slice(0, limit);
347
+ }
348
+
349
+ private async hybridSearch(
350
+ query: string,
351
+ stores: readonly StoreId[],
352
+ limit: number,
353
+ threshold?: number
354
+ ): Promise<SearchResult[]> {
355
+ // Phase 1: Classify query intent for context-aware ranking
356
+ const intent = classifyQueryIntent(query);
357
+
358
+ // Get both result sets
359
+ const [vectorResults, ftsResults] = await Promise.all([
360
+ this.vectorSearch(query, stores, limit * 2, threshold),
361
+ this.ftsSearch(query, stores, limit * 2),
362
+ ]);
363
+
364
+ // Build rank maps
365
+ const vectorRanks = new Map<string, number>();
366
+ const ftsRanks = new Map<string, number>();
367
+ const allDocs = new Map<string, SearchResult>();
368
+
369
+ vectorResults.forEach((r, i) => {
370
+ vectorRanks.set(r.id, i + 1);
371
+ allDocs.set(r.id, r);
372
+ });
373
+
374
+ ftsResults.forEach((r, i) => {
375
+ ftsRanks.set(r.id, i + 1);
376
+ if (!allDocs.has(r.id)) {
377
+ allDocs.set(r.id, r);
378
+ }
379
+ });
380
+
381
+ // Calculate RRF scores with file-type boosting and preserve ranking metadata
382
+ const rrfScores: Array<{
383
+ id: string;
384
+ score: number;
385
+ result: SearchResult;
386
+ metadata: {
387
+ vectorRank?: number;
388
+ ftsRank?: number;
389
+ vectorRRF: number;
390
+ ftsRRF: number;
391
+ fileTypeBoost: number;
392
+ frameworkBoost: number;
393
+ };
394
+ }> = [];
395
+ const { k, vectorWeight, ftsWeight } = this.rrfConfig;
396
+
397
+ for (const [id, result] of allDocs) {
398
+ const vectorRank = vectorRanks.get(id) ?? Infinity;
399
+ const ftsRank = ftsRanks.get(id) ?? Infinity;
400
+
401
+ const vectorRRF = vectorRank !== Infinity ? vectorWeight / (k + vectorRank) : 0;
402
+ const ftsRRF = ftsRank !== Infinity ? ftsWeight / (k + ftsRank) : 0;
403
+
404
+ // Apply file-type boost (base + intent-adjusted)
405
+ const fileTypeBoost = this.getFileTypeBoost(
406
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
407
+ result.metadata['fileType'] as string | undefined,
408
+ intent
409
+ );
410
+
411
+ // Apply framework context boost
412
+ const frameworkBoost = this.getFrameworkContextBoost(query, result);
413
+
414
+ const metadata: {
415
+ vectorRank?: number;
416
+ ftsRank?: number;
417
+ vectorRRF: number;
418
+ ftsRRF: number;
419
+ fileTypeBoost: number;
420
+ frameworkBoost: number;
421
+ } = {
422
+ vectorRRF,
423
+ ftsRRF,
424
+ fileTypeBoost,
425
+ frameworkBoost,
426
+ };
427
+
428
+ if (vectorRank !== Infinity) {
429
+ metadata.vectorRank = vectorRank;
430
+ }
431
+ if (ftsRank !== Infinity) {
432
+ metadata.ftsRank = ftsRank;
433
+ }
434
+
435
+ rrfScores.push({
436
+ id,
437
+ score: (vectorRRF + ftsRRF) * fileTypeBoost * frameworkBoost,
438
+ result,
439
+ metadata,
440
+ });
441
+ }
442
+
443
+ // Sort by RRF score
444
+ const sorted = rrfScores.sort((a, b) => b.score - a.score).slice(0, limit);
445
+
446
+ // Normalize scores to 0-1 range for better interpretability
447
+ if (sorted.length > 0) {
448
+ const first = sorted[0];
449
+ const last = sorted[sorted.length - 1];
450
+ if (first === undefined || last === undefined) {
451
+ return sorted.map(r => ({
452
+ ...r.result,
453
+ score: r.score,
454
+ rankingMetadata: r.metadata,
455
+ }));
456
+ }
457
+ const maxScore = first.score;
458
+ const minScore = last.score;
459
+ const range = maxScore - minScore;
460
+
461
+ if (range > 0) {
462
+ return sorted.map(r => ({
463
+ ...r.result,
464
+ score: (r.score - minScore) / range,
465
+ rankingMetadata: r.metadata,
466
+ }));
467
+ }
468
+ }
469
+
470
+ return sorted.map(r => ({
471
+ ...r.result,
472
+ score: r.score,
473
+ rankingMetadata: r.metadata,
474
+ }));
475
+ }
476
+
477
+ async searchAllStores(
478
+ query: SearchQuery,
479
+ storeIds: StoreId[]
480
+ ): Promise<SearchResponse> {
481
+ return this.search({
482
+ ...query,
483
+ stores: storeIds,
484
+ });
485
+ }
486
+
487
+ /**
488
+ * Get a score multiplier based on file type and query intent.
489
+ * Documentation files get a strong boost to surface them higher.
490
+ * Phase 4: Strengthened boosts for better documentation ranking.
491
+ * Phase 1: Intent-based adjustments for context-aware ranking.
492
+ */
493
+ private getFileTypeBoost(fileType: string | undefined, intent: QueryIntent): number {
494
+ // Base file-type boosts
495
+ let baseBoost: number;
496
+ switch (fileType) {
497
+ case 'documentation-primary':
498
+ baseBoost = 1.8; // README, guides get very strong boost
499
+ break;
500
+ case 'documentation':
501
+ baseBoost = 1.5; // docs/, tutorials/ get strong boost
502
+ break;
503
+ case 'example':
504
+ baseBoost = 1.4; // examples/, demos/ are highly valuable
505
+ break;
506
+ case 'source':
507
+ baseBoost = 1.0; // Source code baseline
508
+ break;
509
+ case 'source-internal':
510
+ baseBoost = 0.75; // Internal implementation files (not too harsh)
511
+ break;
512
+ case 'test':
513
+ baseBoost = 0.7; // Tests significantly lower
514
+ break;
515
+ case 'config':
516
+ baseBoost = 0.5; // Config files rarely answer questions
517
+ break;
518
+ default:
519
+ baseBoost = 1.0;
520
+ }
521
+
522
+ // Apply intent-based multiplier
523
+ const intentBoosts = INTENT_FILE_BOOSTS[intent];
524
+ const intentMultiplier = intentBoosts[fileType ?? 'other'] ?? 1.0;
525
+
526
+ return baseBoost * intentMultiplier;
527
+ }
528
+
529
+ /**
530
+ * Get a score multiplier based on framework context.
531
+ * If query mentions a framework, boost results from that framework's files.
532
+ */
533
+ private getFrameworkContextBoost(query: string, result: SearchResult): number {
534
+ const path = result.metadata.path ?? result.metadata.url ?? '';
535
+ const content = result.content.toLowerCase();
536
+ const pathLower = path.toLowerCase();
537
+
538
+ // Check if query mentions any known frameworks
539
+ for (const { pattern, terms } of FRAMEWORK_PATTERNS) {
540
+ if (pattern.test(query)) {
541
+ // Query mentions this framework - check if result is from that framework
542
+ const resultMatchesFramework = terms.some(term =>
543
+ pathLower.includes(term) || content.includes(term)
544
+ );
545
+
546
+ if (resultMatchesFramework) {
547
+ return 1.5; // Strong boost for matching framework
548
+ } else {
549
+ return 0.8; // Moderate penalty for non-matching when framework is specified
550
+ }
551
+ }
552
+ }
553
+
554
+ return 1.0; // No framework context in query
555
+ }
556
+
557
+ private addProgressiveContext(
558
+ result: SearchResult,
559
+ query: string,
560
+ detail: DetailLevel,
561
+ graph: CodeGraph | null
562
+ ): SearchResult {
563
+ const enhanced = { ...result };
564
+
565
+ // Layer 1: Always add summary
566
+ const path = result.metadata.path ?? result.metadata.url ?? 'unknown';
567
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
568
+ const fileType = result.metadata['fileType'] as string | undefined;
569
+
570
+ // Try to extract code unit
571
+ const codeUnit = this.extractCodeUnitFromResult(result);
572
+ const symbolName = codeUnit?.name ?? this.extractSymbolName(result.content);
573
+
574
+ enhanced.summary = {
575
+ type: this.inferType(fileType, codeUnit),
576
+ name: symbolName,
577
+ signature: codeUnit?.signature ?? '',
578
+ purpose: this.generatePurpose(result.content, query),
579
+ location: `${path}${codeUnit ? ':' + String(codeUnit.startLine) : ''}`,
580
+ relevanceReason: this.generateRelevanceReason(result, query)
581
+ };
582
+
583
+ // Layer 2: Add context if requested
584
+ if (detail === 'contextual' || detail === 'full') {
585
+ // Get usage stats from code graph if available
586
+ const usage = this.getUsageFromGraph(graph, path, symbolName);
587
+
588
+ enhanced.context = {
589
+ interfaces: this.extractInterfaces(result.content),
590
+ keyImports: this.extractImports(result.content),
591
+ relatedConcepts: this.extractConcepts(result.content, query),
592
+ usage
593
+ };
594
+ }
595
+
596
+ // Layer 3: Add full context if requested
597
+ if (detail === 'full') {
598
+ // Get related code from graph if available
599
+ const relatedCode = this.getRelatedCodeFromGraph(graph, path, symbolName);
600
+
601
+ enhanced.full = {
602
+ completeCode: codeUnit?.fullContent ?? result.content,
603
+ relatedCode,
604
+ documentation: this.extractDocumentation(result.content),
605
+ tests: undefined
606
+ };
607
+ }
608
+
609
+ return enhanced;
610
+ }
611
+
612
+ private extractCodeUnitFromResult(result: SearchResult): CodeUnit | undefined {
613
+ const path = result.metadata.path;
614
+ if (path === undefined || path === '') return undefined;
615
+
616
+ const ext = path.split('.').pop() ?? '';
617
+ const language = ext === 'ts' || ext === 'tsx' ? 'typescript' :
618
+ ext === 'js' || ext === 'jsx' ? 'javascript' : ext;
619
+
620
+ // Try to find a symbol name in the content
621
+ const symbolName = this.extractSymbolName(result.content);
622
+ if (symbolName === '') return undefined;
623
+
624
+ return this.codeUnitService.extractCodeUnit(result.content, symbolName, language);
625
+ }
626
+
627
+ private extractSymbolName(content: string): string {
628
+ // Extract function or class name
629
+ const funcMatch = content.match(/(?:export\s+)?(?:async\s+)?function\s+(\w+)/);
630
+ if (funcMatch !== null && funcMatch[1] !== undefined && funcMatch[1] !== '') return funcMatch[1];
631
+
632
+ const classMatch = content.match(/(?:export\s+)?class\s+(\w+)/);
633
+ if (classMatch !== null && classMatch[1] !== undefined && classMatch[1] !== '') return classMatch[1];
634
+
635
+ const constMatch = content.match(/(?:export\s+)?const\s+(\w+)/);
636
+ if (constMatch !== null && constMatch[1] !== undefined && constMatch[1] !== '') return constMatch[1];
637
+
638
+ // Fallback: return "(anonymous)" for unnamed symbols
639
+ return '(anonymous)';
640
+ }
641
+
642
+ private inferType(fileType: string | undefined, codeUnit: CodeUnit | undefined): import('../types/search.js').ResultSummary['type'] {
643
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
644
+ if (codeUnit) return codeUnit.type as import('../types/search.js').ResultSummary['type'];
645
+ if (fileType === 'documentation' || fileType === 'documentation-primary') return 'documentation';
646
+ return 'function';
647
+ }
648
+
649
+ private generatePurpose(content: string, query: string): string {
650
+ // Extract first line of JSDoc comment if present
651
+ const docMatch = content.match(/\/\*\*\s*\n\s*\*\s*([^\n]+)/);
652
+ if (docMatch !== null && docMatch[1] !== undefined && docMatch[1] !== '') return docMatch[1].trim();
653
+
654
+ const lines = content.split('\n');
655
+ const queryTerms = query.toLowerCase().split(/\s+/).filter(t => t.length > 2);
656
+
657
+ // Helper to check if line is skippable (imports, declarations)
658
+ const shouldSkip = (cleaned: string): boolean => {
659
+ return cleaned.startsWith('import ') ||
660
+ cleaned.startsWith('export ') ||
661
+ cleaned.startsWith('interface ') ||
662
+ cleaned.startsWith('type ');
663
+ };
664
+
665
+ // Helper to score a line based on query term matches
666
+ const scoreLine = (cleaned: string): number => {
667
+ const lowerLine = cleaned.toLowerCase();
668
+ return queryTerms.filter(term => lowerLine.includes(term)).length;
669
+ };
670
+
671
+ // Helper to check if line is meaningful (length, not a comment)
672
+ const isMeaningful = (cleaned: string): boolean => {
673
+ if (cleaned.length === 0) return false;
674
+ if (cleaned.startsWith('//') || cleaned.startsWith('/*')) return false;
675
+ // Accept Markdown headings
676
+ if (cleaned.startsWith('#') && cleaned.length > 3) return true;
677
+ // Accept lines 15+ chars
678
+ return cleaned.length >= 15;
679
+ };
680
+
681
+ // First pass: find lines with query terms, preferring complete sentences
682
+ let bestLine: string | null = null;
683
+ let bestScore = 0;
684
+
685
+ for (const line of lines) {
686
+ const cleaned = line.trim();
687
+ if (shouldSkip(cleaned) || !isMeaningful(cleaned)) continue;
688
+
689
+ let score = scoreLine(cleaned);
690
+
691
+ // Boost score for complete sentences (end with period, !, ?)
692
+ if (/[.!?]$/.test(cleaned)) {
693
+ score += 0.5;
694
+ }
695
+
696
+ // Boost score for code examples (contains function calls or assignments)
697
+ // Favor complete patterns: function calls WITH arguments, assignments with values
698
+ if (/\w+\([^)]*\)|=\s*\w+\(|=>/.test(cleaned)) {
699
+ score += 0.6; // Enhanced boost to preserve code examples in snippets
700
+ }
701
+
702
+ if (score > bestScore) {
703
+ bestScore = score;
704
+ bestLine = cleaned;
705
+ }
706
+ }
707
+
708
+ // If we found a line with query terms, use it
709
+ if (bestLine !== null && bestLine !== '' && bestScore > 0) {
710
+ if (bestLine.length > 150) {
711
+ const firstSentence = bestLine.match(/^[^.!?]+[.!?]/);
712
+ if (firstSentence && firstSentence[0].length >= 20 && firstSentence[0].length <= 150) {
713
+ return firstSentence[0].trim();
714
+ }
715
+ return bestLine.substring(0, 147) + '...';
716
+ }
717
+ return bestLine;
718
+ }
719
+
720
+ // Fallback: first meaningful line (original logic)
721
+ for (const line of lines) {
722
+ const cleaned = line.trim();
723
+ if (shouldSkip(cleaned) || !isMeaningful(cleaned)) continue;
724
+
725
+ if (cleaned.length > 150) {
726
+ const firstSentence = cleaned.match(/^[^.!?]+[.!?]/);
727
+ if (firstSentence && firstSentence[0].length >= 20 && firstSentence[0].length <= 150) {
728
+ return firstSentence[0].trim();
729
+ }
730
+ return cleaned.substring(0, 147) + '...';
731
+ }
732
+
733
+ return cleaned;
734
+ }
735
+
736
+ return 'Code related to query';
737
+ }
738
+
739
+ private generateRelevanceReason(result: SearchResult, query: string): string {
740
+ const queryTerms = query.toLowerCase().split(/\s+/).filter(t => t.length > 2);
741
+ const contentLower = result.content.toLowerCase();
742
+
743
+ const matchedTerms = queryTerms.filter(term => contentLower.includes(term));
744
+
745
+ if (matchedTerms.length > 0) {
746
+ return `Matches: ${matchedTerms.join(', ')}`;
747
+ }
748
+
749
+ return 'Semantically similar to query';
750
+ }
751
+
752
+ private extractInterfaces(content: string): string[] {
753
+ const interfaces: string[] = [];
754
+ const matches = content.matchAll(/interface\s+(\w+)/g);
755
+ for (const match of matches) {
756
+ if (match[1] !== undefined && match[1] !== '') interfaces.push(match[1]);
757
+ }
758
+ return interfaces;
759
+ }
760
+
761
+ private extractImports(content: string): string[] {
762
+ const imports: string[] = [];
763
+ const matches = content.matchAll(/import\s+.*?from\s+['"]([^'"]+)['"]/g);
764
+ for (const match of matches) {
765
+ if (match[1] !== undefined && match[1] !== '') imports.push(match[1]);
766
+ }
767
+ return imports.slice(0, 5); // Top 5
768
+ }
769
+
770
+ private extractConcepts(content: string, _query: string): string[] {
771
+ // TODO: Use _query parameter to prioritize query-related concepts in future enhancement
772
+
773
+ // Common stopwords to filter out
774
+ const stopwords = new Set([
775
+ 'this', 'that', 'these', 'those', 'from', 'with', 'have', 'will',
776
+ 'would', 'should', 'could', 'about', 'been', 'were', 'being',
777
+ 'function', 'return', 'const', 'import', 'export', 'default',
778
+ 'type', 'interface', 'class', 'extends', 'implements', 'async',
779
+ 'await', 'then', 'catch', 'throw', 'error', 'undefined', 'null',
780
+ 'true', 'false', 'void', 'number', 'string', 'boolean', 'object',
781
+ 'array', 'promise', 'callback', 'resolve', 'reject', 'value',
782
+ 'param', 'params', 'args', 'props', 'options', 'config', 'data'
783
+ ]);
784
+
785
+ // Simple keyword extraction
786
+ const words = content.toLowerCase().match(/\b[a-z]{4,}\b/g) ?? [];
787
+ const frequency = new Map<string, number>();
788
+
789
+ for (const word of words) {
790
+ // Skip stopwords
791
+ if (stopwords.has(word)) continue;
792
+
793
+ frequency.set(word, (frequency.get(word) ?? 0) + 1);
794
+ }
795
+
796
+ return Array.from(frequency.entries())
797
+ .sort((a, b) => b[1] - a[1])
798
+ .slice(0, 5)
799
+ .map(([word]) => word);
800
+ }
801
+
802
+ private extractDocumentation(content: string): string {
803
+ const docMatch = content.match(/\/\*\*([\s\S]*?)\*\//);
804
+ if (docMatch !== null && docMatch[1] !== undefined && docMatch[1] !== '') {
805
+ return docMatch[1]
806
+ .split('\n')
807
+ .map(line => line.replace(/^\s*\*\s?/, '').trim())
808
+ .filter(line => line.length > 0)
809
+ .join('\n');
810
+ }
811
+ return '';
812
+ }
813
+
814
+ /**
815
+ * Get usage stats from code graph.
816
+ * Returns default values if no graph is available.
817
+ */
818
+ private getUsageFromGraph(
819
+ graph: CodeGraph | null,
820
+ filePath: string,
821
+ symbolName: string
822
+ ): { calledBy: number; calls: number } {
823
+ if (!graph || symbolName === '' || symbolName === '(anonymous)') {
824
+ return { calledBy: 0, calls: 0 };
825
+ }
826
+
827
+ const nodeId = `${filePath}:${symbolName}`;
828
+ return {
829
+ calledBy: graph.getCalledByCount(nodeId),
830
+ calls: graph.getCallsCount(nodeId)
831
+ };
832
+ }
833
+
834
+ /**
835
+ * Get related code from graph.
836
+ * Returns callers and callees for the symbol.
837
+ */
838
+ private getRelatedCodeFromGraph(
839
+ graph: CodeGraph | null,
840
+ filePath: string,
841
+ symbolName: string
842
+ ): Array<{ file: string; summary: string; relationship: string }> {
843
+ if (!graph || symbolName === '' || symbolName === '(anonymous)') {
844
+ return [];
845
+ }
846
+
847
+ const nodeId = `${filePath}:${symbolName}`;
848
+ const related: Array<{ file: string; summary: string; relationship: string }> = [];
849
+
850
+ // Get callers (incoming edges)
851
+ const incoming = graph.getIncomingEdges(nodeId);
852
+ for (const edge of incoming) {
853
+ if (edge.type === 'calls') {
854
+ // Parse file:symbol from edge.from
855
+ const [file, symbol] = this.parseNodeId(edge.from);
856
+ related.push({
857
+ file,
858
+ summary: symbol ? `${symbol}()` : 'unknown',
859
+ relationship: 'calls this'
860
+ });
861
+ }
862
+ }
863
+
864
+ // Get callees (outgoing edges)
865
+ const outgoing = graph.getEdges(nodeId);
866
+ for (const edge of outgoing) {
867
+ if (edge.type === 'calls') {
868
+ // Parse file:symbol from edge.to
869
+ const [file, symbol] = this.parseNodeId(edge.to);
870
+ related.push({
871
+ file,
872
+ summary: symbol ? `${symbol}()` : 'unknown',
873
+ relationship: 'called by this'
874
+ });
875
+ }
876
+ }
877
+
878
+ // Limit to top 10 related items
879
+ return related.slice(0, 10);
880
+ }
881
+
882
+ /**
883
+ * Parse a node ID into file path and symbol name.
884
+ */
885
+ private parseNodeId(nodeId: string): [string, string] {
886
+ const lastColon = nodeId.lastIndexOf(':');
887
+ if (lastColon === -1) {
888
+ return [nodeId, ''];
889
+ }
890
+ return [nodeId.substring(0, lastColon), nodeId.substring(lastColon + 1)];
891
+ }
892
+ }