codebase-onboarder 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (448) hide show
  1. package/README.md +174 -46
  2. package/bin/build-if-source.js +23 -0
  3. package/cli/commands.d.ts +26 -0
  4. package/cli/commands.js +836 -811
  5. package/cli/commands.js.map +1 -0
  6. package/cli/explorer/advanced.d.ts +14 -0
  7. package/cli/explorer/advanced.js +321 -329
  8. package/cli/explorer/advanced.js.map +1 -0
  9. package/cli/explorer/app.d.ts +1 -0
  10. package/cli/explorer/app.js +384 -313
  11. package/cli/explorer/app.js.map +1 -0
  12. package/cli/explorer/assistant.d.ts +9 -0
  13. package/cli/explorer/assistant.js +58 -0
  14. package/cli/explorer/assistant.js.map +1 -0
  15. package/cli/explorer/commands.d.ts +17 -0
  16. package/cli/explorer/commands.js +368 -302
  17. package/cli/explorer/commands.js.map +1 -0
  18. package/cli/explorer/featureViews.d.ts +124 -0
  19. package/cli/explorer/featureViews.js +179 -0
  20. package/cli/explorer/featureViews.js.map +1 -0
  21. package/cli/explorer/github.d.ts +21 -0
  22. package/cli/explorer/github.js +42 -44
  23. package/cli/explorer/github.js.map +1 -0
  24. package/cli/explorer/graphs.d.ts +7 -0
  25. package/cli/explorer/graphs.js +90 -95
  26. package/cli/explorer/graphs.js.map +1 -0
  27. package/cli/explorer/picker.d.ts +22 -0
  28. package/cli/explorer/picker.js +150 -0
  29. package/cli/explorer/picker.js.map +1 -0
  30. package/cli/explorer/report.d.ts +85 -0
  31. package/cli/explorer/report.js +60 -0
  32. package/cli/explorer/report.js.map +1 -0
  33. package/cli/explorer/session.d.ts +449 -0
  34. package/cli/explorer/session.js +143 -144
  35. package/cli/explorer/session.js.map +1 -0
  36. package/cli/explorer/views.d.ts +19 -0
  37. package/cli/explorer/views.js +465 -482
  38. package/cli/explorer/views.js.map +1 -0
  39. package/cli/explorer/wrap.d.ts +1 -0
  40. package/cli/explorer/wrap.js +28 -44
  41. package/cli/explorer/wrap.js.map +1 -0
  42. package/cli/main.d.ts +1 -0
  43. package/cli/main.js +214 -161
  44. package/cli/main.js.map +1 -0
  45. package/cli/prompt.d.ts +5 -0
  46. package/cli/prompt.js +84 -80
  47. package/cli/prompt.js.map +1 -0
  48. package/cli/scanOptions.d.ts +2 -0
  49. package/cli/scanOptions.js +11 -0
  50. package/cli/scanOptions.js.map +1 -0
  51. package/cli/ui.d.ts +33 -0
  52. package/cli/ui.js +35 -44
  53. package/cli/ui.js.map +1 -0
  54. package/cli/wizard.d.ts +187 -0
  55. package/cli/wizard.js +304 -284
  56. package/cli/wizard.js.map +1 -0
  57. package/package.json +15 -4
  58. package/public/app.d.ts +1 -0
  59. package/public/app.js +1057 -1009
  60. package/public/app.js.map +1 -0
  61. package/public/browser.d.ts +68 -0
  62. package/public/browser.js +2 -0
  63. package/public/browser.js.map +1 -0
  64. package/public/index.html +30 -13
  65. package/public/js/about.d.ts +6 -0
  66. package/public/js/about.js +152 -172
  67. package/public/js/about.js.map +1 -0
  68. package/public/js/aiDraft.d.ts +3 -0
  69. package/public/js/aiDraft.js +116 -124
  70. package/public/js/aiDraft.js.map +1 -0
  71. package/public/js/analysisPanel.d.ts +7 -0
  72. package/public/js/analysisPanel.js +166 -166
  73. package/public/js/analysisPanel.js.map +1 -0
  74. package/public/js/analysisReport.d.ts +38 -0
  75. package/public/js/analysisReport.js +105 -110
  76. package/public/js/analysisReport.js.map +1 -0
  77. package/public/js/api.d.ts +26 -0
  78. package/public/js/api.js +176 -167
  79. package/public/js/api.js.map +1 -0
  80. package/public/js/atlas.d.ts +6 -0
  81. package/public/js/atlas.js +50 -58
  82. package/public/js/atlas.js.map +1 -0
  83. package/public/js/blameView.d.ts +2 -0
  84. package/public/js/blameView.js +36 -37
  85. package/public/js/blameView.js.map +1 -0
  86. package/public/js/codeTab.d.ts +3 -0
  87. package/public/js/codeTab.js +175 -180
  88. package/public/js/codeTab.js.map +1 -0
  89. package/public/js/codeViewer.d.ts +5 -0
  90. package/public/js/codeViewer.js +162 -150
  91. package/public/js/codeViewer.js.map +1 -0
  92. package/public/js/components/FileChip.d.ts +9 -0
  93. package/public/js/components/FileChip.js +45 -49
  94. package/public/js/components/FileChip.js.map +1 -0
  95. package/public/js/components/MetricSparkline.d.ts +7 -0
  96. package/public/js/components/MetricSparkline.js +35 -44
  97. package/public/js/components/MetricSparkline.js.map +1 -0
  98. package/public/js/components/RiskBadge.d.ts +9 -0
  99. package/public/js/components/RiskBadge.js +55 -63
  100. package/public/js/components/RiskBadge.js.map +1 -0
  101. package/public/js/deepAnalysisView.d.ts +99 -0
  102. package/public/js/deepAnalysisView.js +282 -302
  103. package/public/js/deepAnalysisView.js.map +1 -0
  104. package/public/js/diagramPane.d.ts +8 -0
  105. package/public/js/diagramPane.js +133 -135
  106. package/public/js/diagramPane.js.map +1 -0
  107. package/public/js/diffView.d.ts +6 -0
  108. package/public/js/diffView.js +222 -209
  109. package/public/js/diffView.js.map +1 -0
  110. package/public/js/docsView.d.ts +2 -0
  111. package/public/js/docsView.js +441 -442
  112. package/public/js/docsView.js.map +1 -0
  113. package/public/js/dom.d.ts +189 -0
  114. package/public/js/dom.js +5 -0
  115. package/public/js/dom.js.map +1 -0
  116. package/public/js/fileSourceBrowser.d.ts +5 -0
  117. package/public/js/fileSourceBrowser.js +33 -41
  118. package/public/js/fileSourceBrowser.js.map +1 -0
  119. package/public/js/flameGraph.d.ts +5 -0
  120. package/public/js/flameGraph.js +62 -72
  121. package/public/js/flameGraph.js.map +1 -0
  122. package/public/js/forceGraph.d.ts +10 -0
  123. package/public/js/forceGraph.js +581 -556
  124. package/public/js/forceGraph.js.map +1 -0
  125. package/public/js/heatmap.d.ts +4 -0
  126. package/public/js/heatmap.js +142 -164
  127. package/public/js/heatmap.js.map +1 -0
  128. package/public/js/highlight.d.ts +2 -0
  129. package/public/js/highlight.js +116 -107
  130. package/public/js/highlight.js.map +1 -0
  131. package/public/js/html.d.ts +2 -0
  132. package/public/js/html.js +14 -44
  133. package/public/js/html.js.map +1 -0
  134. package/public/js/insightsView.d.ts +5 -0
  135. package/public/js/insightsView.js +93 -111
  136. package/public/js/insightsView.js.map +1 -0
  137. package/public/js/inspector.d.ts +37 -0
  138. package/public/js/inspector.js +416 -445
  139. package/public/js/inspector.js.map +1 -0
  140. package/public/js/llm.d.ts +113 -0
  141. package/public/js/llm.js +233 -272
  142. package/public/js/llm.js.map +1 -0
  143. package/public/js/mapView.d.ts +3 -0
  144. package/public/js/mapView.js +121 -120
  145. package/public/js/mapView.js.map +1 -0
  146. package/public/js/markdown.d.ts +3 -0
  147. package/public/js/markdown.js +84 -91
  148. package/public/js/markdown.js.map +1 -0
  149. package/public/js/mindmap.d.ts +32 -0
  150. package/public/js/mindmap.js +244 -259
  151. package/public/js/mindmap.js.map +1 -0
  152. package/public/js/mobilePanels.d.ts +5 -0
  153. package/public/js/mobilePanels.js +50 -0
  154. package/public/js/mobilePanels.js.map +1 -0
  155. package/public/js/repoFiles.d.ts +12 -0
  156. package/public/js/repoFiles.js +28 -27
  157. package/public/js/repoFiles.js.map +1 -0
  158. package/public/js/reviewView.d.ts +28 -0
  159. package/public/js/reviewView.js +256 -0
  160. package/public/js/reviewView.js.map +1 -0
  161. package/public/js/sbomView.d.ts +3 -0
  162. package/public/js/sbomView.js +59 -67
  163. package/public/js/sbomView.js.map +1 -0
  164. package/public/js/scanCache.d.ts +16 -0
  165. package/public/js/scanCache.js +67 -65
  166. package/public/js/scanCache.js.map +1 -0
  167. package/public/js/search.d.ts +7 -0
  168. package/public/js/search.js +868 -800
  169. package/public/js/search.js.map +1 -0
  170. package/public/js/searchLocal.d.ts +42 -0
  171. package/public/js/searchLocal.js +87 -0
  172. package/public/js/searchLocal.js.map +1 -0
  173. package/public/js/serverSettings.d.ts +5 -0
  174. package/public/js/serverSettings.js +153 -164
  175. package/public/js/serverSettings.js.map +1 -0
  176. package/public/js/state.d.ts +798 -0
  177. package/public/js/state.js +114 -122
  178. package/public/js/state.js.map +1 -0
  179. package/public/js/tour.d.ts +6 -0
  180. package/public/js/tour.js +5 -7
  181. package/public/js/tour.js.map +1 -0
  182. package/public/js/transitions.d.ts +2 -0
  183. package/public/js/transitions.js +9 -10
  184. package/public/js/transitions.js.map +1 -0
  185. package/public/js/tree.d.ts +12 -0
  186. package/public/js/tree.js +157 -154
  187. package/public/js/tree.js.map +1 -0
  188. package/public/js/workflowsView.d.ts +3 -0
  189. package/public/js/workflowsView.js +15 -22
  190. package/public/js/workflowsView.js.map +1 -0
  191. package/public/search.css +495 -0
  192. package/public/styles.css +163 -346
  193. package/public/workbench.css +166 -0
  194. package/server/apiAuth.d.ts +3 -0
  195. package/server/apiAuth.js +18 -20
  196. package/server/apiAuth.js.map +1 -0
  197. package/server/apiDiff.d.ts +2 -0
  198. package/server/apiDiff.js +20 -18
  199. package/server/apiDiff.js.map +1 -0
  200. package/server/apiDocs.d.ts +2 -0
  201. package/server/apiDocs.js +38 -40
  202. package/server/apiDocs.js.map +1 -0
  203. package/server/apiFile.d.ts +1 -0
  204. package/server/apiFile.js +14 -17
  205. package/server/apiFile.js.map +1 -0
  206. package/server/apiGitBlame.d.ts +2 -0
  207. package/server/apiGitBlame.js +50 -51
  208. package/server/apiGitBlame.js.map +1 -0
  209. package/server/apiMcp.d.ts +4 -0
  210. package/server/apiMcp.js +64 -66
  211. package/server/apiMcp.js.map +1 -0
  212. package/server/apiReview.d.ts +2 -0
  213. package/server/apiReview.js +45 -0
  214. package/server/apiReview.js.map +1 -0
  215. package/server/apiScan.d.ts +5 -0
  216. package/server/apiScan.js +90 -71
  217. package/server/apiScan.js.map +1 -0
  218. package/server/apiSearch.d.ts +33 -0
  219. package/server/apiSearch.js +184 -200
  220. package/server/apiSearch.js.map +1 -0
  221. package/server/apiSettings.d.ts +4 -0
  222. package/server/apiSettings.js +84 -85
  223. package/server/apiSettings.js.map +1 -0
  224. package/server/apiTools.d.ts +3 -0
  225. package/server/apiTools.js +55 -56
  226. package/server/apiTools.js.map +1 -0
  227. package/server/auth.d.ts +5 -0
  228. package/server/auth.js +54 -51
  229. package/server/auth.js.map +1 -0
  230. package/server/config.d.ts +42 -0
  231. package/server/config.js +189 -194
  232. package/server/config.js.map +1 -0
  233. package/server/daemon.d.ts +12 -0
  234. package/server/daemon.js +124 -114
  235. package/server/daemon.js.map +1 -0
  236. package/server/fileSourceNode.d.ts +2 -0
  237. package/server/fileSourceNode.js +34 -36
  238. package/server/fileSourceNode.js.map +1 -0
  239. package/server/gitClone.d.ts +9 -0
  240. package/server/gitClone.js +59 -61
  241. package/server/gitClone.js.map +1 -0
  242. package/server/gitDiff.d.ts +36 -0
  243. package/server/gitDiff.js +271 -169
  244. package/server/gitDiff.js.map +1 -0
  245. package/server/gitHistory.d.ts +12 -0
  246. package/server/gitHistory.js +80 -80
  247. package/server/gitHistory.js.map +1 -0
  248. package/server/gitRemote.d.ts +12 -0
  249. package/server/gitRemote.js +37 -38
  250. package/server/gitRemote.js.map +1 -0
  251. package/server/htmlText.d.ts +4 -0
  252. package/server/htmlText.js +16 -23
  253. package/server/htmlText.js.map +1 -0
  254. package/server/http.d.ts +5 -0
  255. package/server/http.js +27 -30
  256. package/server/http.js.map +1 -0
  257. package/server/httpGuards.d.ts +2 -0
  258. package/server/httpGuards.js +47 -43
  259. package/server/httpGuards.js.map +1 -0
  260. package/server/https.d.ts +34 -0
  261. package/server/https.js +121 -111
  262. package/server/https.js.map +1 -0
  263. package/server/index.d.ts +40 -0
  264. package/server/index.js +139 -147
  265. package/server/index.js.map +1 -0
  266. package/server/layout.d.ts +26 -0
  267. package/server/layout.js +59 -64
  268. package/server/layout.js.map +1 -0
  269. package/server/llmProxy.d.ts +3 -0
  270. package/server/llmProxy.js +137 -135
  271. package/server/llmProxy.js.map +1 -0
  272. package/server/logger.d.ts +38 -0
  273. package/server/logger.js +198 -211
  274. package/server/logger.js.map +1 -0
  275. package/server/mcp/analysis.d.ts +29 -0
  276. package/server/mcp/analysis.js +99 -120
  277. package/server/mcp/analysis.js.map +1 -0
  278. package/server/mcp/http.d.ts +9 -0
  279. package/server/mcp/http.js +128 -137
  280. package/server/mcp/http.js.map +1 -0
  281. package/server/mcp/runner.d.ts +68 -0
  282. package/server/mcp/runner.js +208 -218
  283. package/server/mcp/runner.js.map +1 -0
  284. package/server/mcp/server.d.ts +29 -0
  285. package/server/mcp/server.js +166 -179
  286. package/server/mcp/server.js.map +1 -0
  287. package/server/mcp/standalone.d.ts +1 -0
  288. package/server/mcp/standalone.js +8 -10
  289. package/server/mcp/standalone.js.map +1 -0
  290. package/server/mcp/tools.d.ts +2020 -0
  291. package/server/mcp/tools.js +523 -574
  292. package/server/mcp/tools.js.map +1 -0
  293. package/server/paths.d.ts +3 -0
  294. package/server/paths.js +17 -15
  295. package/server/paths.js.map +1 -0
  296. package/server/pidfile.d.ts +9 -0
  297. package/server/pidfile.js +43 -45
  298. package/server/pidfile.js.map +1 -0
  299. package/server/review.d.ts +5 -0
  300. package/server/review.js +35 -0
  301. package/server/review.js.map +1 -0
  302. package/server/router.d.ts +33 -0
  303. package/server/router.js +191 -197
  304. package/server/router.js.map +1 -0
  305. package/server/scanRequest.d.ts +3 -0
  306. package/server/scanRequest.js +36 -0
  307. package/server/scanRequest.js.map +1 -0
  308. package/server/searchIndex.d.ts +17 -0
  309. package/server/searchIndex.js +83 -80
  310. package/server/searchIndex.js.map +1 -0
  311. package/server/sessions.d.ts +14 -0
  312. package/server/sessions.js +62 -70
  313. package/server/sessions.js.map +1 -0
  314. package/server/startup.d.ts +118 -0
  315. package/server/startup.js +143 -148
  316. package/server/startup.js.map +1 -0
  317. package/server/static.d.ts +6 -0
  318. package/server/static.js +28 -31
  319. package/server/static.js.map +1 -0
  320. package/server/tools/install.d.ts +4 -0
  321. package/server/tools/install.js +176 -185
  322. package/server/tools/install.js.map +1 -0
  323. package/server/tools/parse.d.ts +8 -0
  324. package/server/tools/parse.js +112 -114
  325. package/server/tools/parse.js.map +1 -0
  326. package/server/tools/platform.d.ts +9 -0
  327. package/server/tools/platform.js +49 -47
  328. package/server/tools/platform.js.map +1 -0
  329. package/server/tools/registry.d.ts +137 -0
  330. package/server/tools/registry.js +173 -172
  331. package/server/tools/registry.js.map +1 -0
  332. package/server/tools/scan.d.ts +34 -0
  333. package/server/tools/scan.js +89 -98
  334. package/server/tools/scan.js.map +1 -0
  335. package/server/tools.d.ts +34 -0
  336. package/server/tools.js +94 -107
  337. package/server/tools.js.map +1 -0
  338. package/server/tunnel.d.ts +29 -0
  339. package/server/tunnel.js +61 -66
  340. package/server/tunnel.js.map +1 -0
  341. package/shared/analyzer/docs.d.ts +16 -0
  342. package/shared/analyzer/docs.js +99 -93
  343. package/shared/analyzer/docs.js.map +1 -0
  344. package/shared/analyzer/explainLocal.d.ts +4 -0
  345. package/shared/analyzer/explainLocal.js +122 -142
  346. package/shared/analyzer/explainLocal.js.map +1 -0
  347. package/shared/analyzer/github.d.ts +37 -0
  348. package/shared/analyzer/github.js +41 -43
  349. package/shared/analyzer/github.js.map +1 -0
  350. package/shared/analyzer/graph.d.ts +41 -0
  351. package/shared/analyzer/graph.js +393 -400
  352. package/shared/analyzer/graph.js.map +1 -0
  353. package/shared/analyzer/health.d.ts +33 -0
  354. package/shared/analyzer/health.js +197 -193
  355. package/shared/analyzer/health.js.map +1 -0
  356. package/shared/analyzer/history.d.ts +29 -0
  357. package/shared/analyzer/history.js +110 -111
  358. package/shared/analyzer/history.js.map +1 -0
  359. package/shared/analyzer/jsonConfig.d.ts +2 -0
  360. package/shared/analyzer/jsonConfig.js +61 -0
  361. package/shared/analyzer/jsonConfig.js.map +1 -0
  362. package/shared/analyzer/languages/csharp.d.ts +26 -0
  363. package/shared/analyzer/languages/csharp.js +83 -88
  364. package/shared/analyzer/languages/csharp.js.map +1 -0
  365. package/shared/analyzer/languages/generic.d.ts +23 -0
  366. package/shared/analyzer/languages/generic.js +94 -105
  367. package/shared/analyzer/languages/generic.js.map +1 -0
  368. package/shared/analyzer/languages/go.d.ts +24 -0
  369. package/shared/analyzer/languages/go.js +45 -54
  370. package/shared/analyzer/languages/go.js.map +1 -0
  371. package/shared/analyzer/languages/index.d.ts +6 -0
  372. package/shared/analyzer/languages/index.js +19 -20
  373. package/shared/analyzer/languages/index.js.map +1 -0
  374. package/shared/analyzer/languages/java.d.ts +20 -0
  375. package/shared/analyzer/languages/java.js +73 -78
  376. package/shared/analyzer/languages/java.js.map +1 -0
  377. package/shared/analyzer/languages/javascript.d.ts +12 -0
  378. package/shared/analyzer/languages/javascript.js +258 -209
  379. package/shared/analyzer/languages/javascript.js.map +1 -0
  380. package/shared/analyzer/languages/python.d.ts +23 -0
  381. package/shared/analyzer/languages/python.js +92 -100
  382. package/shared/analyzer/languages/python.js.map +1 -0
  383. package/shared/analyzer/languages/rust.d.ts +17 -0
  384. package/shared/analyzer/languages/rust.js +96 -98
  385. package/shared/analyzer/languages/rust.js.map +1 -0
  386. package/shared/analyzer/languages/typescript.d.ts +11 -0
  387. package/shared/analyzer/languages/typescript.js +117 -116
  388. package/shared/analyzer/languages/typescript.js.map +1 -0
  389. package/shared/analyzer/licenses.d.ts +18 -0
  390. package/shared/analyzer/licenses.js +130 -133
  391. package/shared/analyzer/licenses.js.map +1 -0
  392. package/shared/analyzer/metrics.d.ts +20 -0
  393. package/shared/analyzer/metrics.js +112 -104
  394. package/shared/analyzer/metrics.js.map +1 -0
  395. package/shared/analyzer/pathUtil.d.ts +10 -0
  396. package/shared/analyzer/pathUtil.js +29 -35
  397. package/shared/analyzer/pathUtil.js.map +1 -0
  398. package/shared/analyzer/patterns.d.ts +11 -0
  399. package/shared/analyzer/patterns.js +231 -253
  400. package/shared/analyzer/patterns.js.map +1 -0
  401. package/shared/analyzer/scan.d.ts +62 -0
  402. package/shared/analyzer/scan.js +451 -442
  403. package/shared/analyzer/scan.js.map +1 -0
  404. package/shared/analyzer/scanControl.d.ts +11 -0
  405. package/shared/analyzer/scanControl.js +62 -0
  406. package/shared/analyzer/scanControl.js.map +1 -0
  407. package/shared/analyzer/security.d.ts +18 -0
  408. package/shared/analyzer/security.js +159 -159
  409. package/shared/analyzer/security.js.map +1 -0
  410. package/shared/analyzer/services.d.ts +5 -0
  411. package/shared/analyzer/services.js +141 -138
  412. package/shared/analyzer/services.js.map +1 -0
  413. package/shared/analyzer/stack.d.ts +6 -0
  414. package/shared/analyzer/stack.js +134 -141
  415. package/shared/analyzer/stack.js.map +1 -0
  416. package/shared/analyzer/tour.d.ts +2 -0
  417. package/shared/analyzer/tour.js +45 -53
  418. package/shared/analyzer/tour.js.map +1 -0
  419. package/shared/analyzer/util.d.ts +8 -0
  420. package/shared/analyzer/util.js +130 -76
  421. package/shared/analyzer/util.js.map +1 -0
  422. package/shared/analyzer/workflows.d.ts +8 -0
  423. package/shared/analyzer/workflows.js +139 -134
  424. package/shared/analyzer/workflows.js.map +1 -0
  425. package/shared/contracts.d.ts +250 -0
  426. package/shared/contracts.js +2 -0
  427. package/shared/contracts.js.map +1 -0
  428. package/shared/diagram/aiFacts.d.ts +35 -0
  429. package/shared/diagram/aiFacts.js +102 -105
  430. package/shared/diagram/aiFacts.js.map +1 -0
  431. package/shared/diagram/aiMermaid.d.ts +5 -0
  432. package/shared/diagram/aiMermaid.js +46 -45
  433. package/shared/diagram/aiMermaid.js.map +1 -0
  434. package/shared/diagram/atlas.d.ts +16 -0
  435. package/shared/diagram/atlas.js +51 -60
  436. package/shared/diagram/atlas.js.map +1 -0
  437. package/shared/diagram/mermaid.d.ts +43 -0
  438. package/shared/diagram/mermaid.js +348 -370
  439. package/shared/diagram/mermaid.js.map +1 -0
  440. package/shared/review/contracts.d.ts +95 -0
  441. package/shared/review/contracts.js +2 -0
  442. package/shared/review/contracts.js.map +1 -0
  443. package/shared/review/review.d.ts +10 -0
  444. package/shared/review/review.js +184 -0
  445. package/shared/review/review.js.map +1 -0
  446. package/shared/search/query.d.ts +32 -0
  447. package/shared/search/query.js +395 -388
  448. package/shared/search/query.js.map +1 -0
@@ -16,238 +16,222 @@
16
16
  // palette uses) and enforces anything the person actually decided: filters,
17
17
  // phrases, regexes, the case toggle. A half-remembered name should still find
18
18
  // the file; `ext:js -vendor` should not be negotiated with.
19
-
20
19
  import { getSession } from './sessions.js';
21
20
  import { sendError, sendJSON } from './http.js';
22
- import {
23
- isAdvanced, lineOfIndex, matchesPathFilters, parseQuery, queryIsEmpty,
24
- scoreContent, scorePath, snippetAt,
25
- } from '../shared/search/query.js';
26
-
21
+ import { isAdvanced, lineOfIndex, matchesPathFilters, parseQuery, queryIsEmpty, scoreContent, scorePath, snippetAt, } from '../shared/search/query.js';
27
22
  export function buildTfIdfIndex(documents) {
28
- // documents: [{ path, content }]
29
- const index = new Map();
30
- const docCounts = new Map();
31
- let totalDocs = 0;
32
-
33
- for (const doc of documents) {
34
- if (!doc.content || typeof doc.content !== 'string') continue;
35
- const tokens = doc.content.toLowerCase().split(/\W+/).filter((t) => t.length > 1);
36
- if (!tokens.length) continue;
37
- totalDocs++;
38
-
39
- const tf = new Map();
40
- for (const t of tokens) {
41
- tf.set(t, (tf.get(t) || 0) + 1);
42
- }
43
- for (const t of tf.keys()) {
44
- docCounts.set(t, (docCounts.get(t) || 0) + 1);
23
+ // documents: [{ path, content }]
24
+ const index = new Map();
25
+ const docCounts = new Map();
26
+ let totalDocs = 0;
27
+ for (const doc of documents) {
28
+ if (!doc.content || typeof doc.content !== 'string')
29
+ continue;
30
+ const tokens = doc.content.toLowerCase().split(/\W+/).filter((t) => t.length > 1);
31
+ if (!tokens.length)
32
+ continue;
33
+ totalDocs++;
34
+ const tf = new Map();
35
+ for (const t of tokens) {
36
+ tf.set(t, (tf.get(t) || 0) + 1);
37
+ }
38
+ for (const t of tf.keys()) {
39
+ docCounts.set(t, (docCounts.get(t) || 0) + 1);
40
+ }
41
+ index.set(doc.path, { tf, content: doc.content, tokenCount: tokens.length });
45
42
  }
46
- index.set(doc.path, { tf, content: doc.content, tokenCount: tokens.length });
47
- }
48
-
49
- return { index, docCounts, totalDocs };
43
+ return { index, docCounts, totalDocs };
50
44
  }
51
-
52
45
  export function searchIndex(indexData, queryString, limit = 10) {
53
- if (!indexData || !queryString) return [];
54
- const terms = queryString.toLowerCase().split(/\s+/).filter((t) => t.length > 0);
55
- if (!terms.length) return [];
56
-
57
- const { index, docCounts, totalDocs } = indexData;
58
- if (!totalDocs) return [];
59
-
60
- const idf = new Map();
61
- for (const t of terms) {
62
- const df = docCounts.get(t) || 0;
63
- idf.set(t, df === 0 ? 0 : Math.log(1 + totalDocs / df));
64
- }
65
-
66
- const results = [];
67
- for (const [docPath, data] of index.entries()) {
68
- let score = 0;
69
- let matchCount = 0;
46
+ if (!indexData || !queryString)
47
+ return [];
48
+ const terms = queryString.toLowerCase().split(/\s+/).filter((t) => t.length > 0);
49
+ if (!terms.length)
50
+ return [];
51
+ const { index, docCounts, totalDocs } = indexData;
52
+ if (!totalDocs)
53
+ return [];
54
+ const idf = new Map();
70
55
  for (const t of terms) {
71
- const tf = data.tf.get(t) || 0;
72
- if (tf > 0) {
73
- matchCount++;
74
- // Normalized TF * IDF
75
- score += (tf / Math.sqrt(data.tokenCount)) * (idf.get(t) || 1);
76
- }
56
+ const df = docCounts.get(t) || 0;
57
+ idf.set(t, df === 0 ? 0 : Math.log(1 + totalDocs / df));
77
58
  }
78
-
79
- if (score > 0) {
80
- // Find best snippet
81
- const lowerContent = data.content.toLowerCase();
82
- let bestIdx = -1;
83
- for (const t of terms) {
84
- const idx = lowerContent.indexOf(t);
85
- if (idx !== -1 && (bestIdx === -1 || idx < bestIdx)) {
86
- bestIdx = idx;
59
+ const results = [];
60
+ for (const [docPath, data] of index.entries()) {
61
+ let score = 0;
62
+ let matchCount = 0;
63
+ for (const t of terms) {
64
+ const tf = data.tf.get(t) || 0;
65
+ if (tf > 0) {
66
+ matchCount++;
67
+ // Normalized TF * IDF
68
+ score += (tf / Math.sqrt(data.tokenCount)) * (idf.get(t) || 1);
69
+ }
70
+ }
71
+ if (score > 0) {
72
+ // Find best snippet
73
+ const lowerContent = data.content.toLowerCase();
74
+ let bestIdx = -1;
75
+ for (const t of terms) {
76
+ const idx = lowerContent.indexOf(t);
77
+ if (idx !== -1 && (bestIdx === -1 || idx < bestIdx)) {
78
+ bestIdx = idx;
79
+ }
80
+ }
81
+ let snippet = '';
82
+ let line = 1;
83
+ if (bestIdx !== -1) {
84
+ const linesBefore = data.content.slice(0, bestIdx).split('\n');
85
+ line = linesBefore.length;
86
+ const allLines = data.content.split('\n');
87
+ const targetLine = (allLines[line - 1] || '').trim();
88
+ snippet = targetLine.length > 120 ? targetLine.slice(0, 117) + '…' : targetLine;
89
+ }
90
+ results.push({
91
+ path: docPath,
92
+ score: score * (matchCount / terms.length), // Boost docs containing all terms
93
+ snippet,
94
+ line,
95
+ });
87
96
  }
88
- }
89
-
90
- let snippet = '';
91
- let line = 1;
92
- if (bestIdx !== -1) {
93
- const linesBefore = data.content.slice(0, bestIdx).split('\n');
94
- line = linesBefore.length;
95
- const allLines = data.content.split('\n');
96
- const targetLine = (allLines[line - 1] || '').trim();
97
- snippet = targetLine.length > 120 ? targetLine.slice(0, 117) + '…' : targetLine;
98
- }
99
-
100
- results.push({
101
- path: docPath,
102
- score: score * (matchCount / terms.length), // Boost docs containing all terms
103
- snippet,
104
- line,
105
- });
106
97
  }
107
- }
108
-
109
- results.sort((a, b) => b.score - a.score);
110
- return results.slice(0, limit);
98
+ results.sort((a, b) => b.score - a.score);
99
+ return results.slice(0, limit);
111
100
  }
112
-
113
101
  // The strict pass: filters are gates, not hints, and every term has to land.
114
102
  // Ranking is positional — `scorePath` and `scoreContent` reward the file whose
115
103
  // name matches and the file where the word appears early — because a query with
116
104
  // a regex or a filter in it is a person who knows what they want, and does not
117
105
  // need the corpus statistics of `searchIndex` second-guessing them.
118
106
  function strictSearch(indexData, parsed) {
119
- // `kind:` is a statement about symbols, and content cannot answer it. A query
120
- // that is *only* a kind filter is answered by the palette's symbol pass and
121
- // by nothing here, which is the honest result rather than "every file".
122
- const kindOnly = parsed.kinds.length > 0
123
- && !parsed.terms.length && !parsed.phrases.length && !parsed.regex;
124
-
125
- const results = [];
126
- for (const [docPath, doc] of indexData.index.entries()) {
127
- if (kindOnly) break;
128
- if (!matchesPathFilters(parsed, docPath)) continue;
129
-
130
- const pathScore = scorePath(parsed, docPath);
131
- const content = scoreContent(parsed, doc.content);
132
- if (!pathScore && !content.score) continue;
133
-
134
- const at = content.index;
135
- results.push({
136
- path: docPath,
137
- score: pathScore + content.score,
138
- line: at >= 0 ? lineOfIndex(doc.content, at) : 1,
139
- snippet: snippetAt(doc.content, at >= 0 ? at : 0),
140
- });
141
- }
142
-
143
- results.sort((a, b) => b.score - a.score || a.path.localeCompare(b.path));
144
- return results;
107
+ // `kind:` is a statement about symbols, and content cannot answer it. A query
108
+ // that is *only* a kind filter is answered by the palette's symbol pass and
109
+ // by nothing here, which is the honest result rather than "every file".
110
+ const kindOnly = parsed.kinds.length > 0
111
+ && !parsed.terms.length && !parsed.phrases.length && !parsed.regex;
112
+ const results = [];
113
+ for (const [docPath, doc] of indexData.index.entries()) {
114
+ if (kindOnly)
115
+ break;
116
+ if (!matchesPathFilters(parsed, docPath))
117
+ continue;
118
+ const pathScore = scorePath(parsed, docPath);
119
+ const content = scoreContent(parsed, doc.content);
120
+ if (!pathScore && !content.score)
121
+ continue;
122
+ const at = content.index;
123
+ results.push({
124
+ path: docPath,
125
+ score: pathScore + content.score,
126
+ line: at >= 0 ? lineOfIndex(doc.content, at) : 1,
127
+ snippet: snippetAt(doc.content, at >= 0 ? at : 0),
128
+ });
129
+ }
130
+ results.sort((a, b) => b.score - a.score || a.path.localeCompare(b.path));
131
+ return results;
145
132
  }
146
-
147
133
  // What the index could not read, in the shape the palette can say out loud —
148
134
  // "searched 127 files, 3 skipped" beats a mystery file that never turns up.
149
135
  function indexStats(indexData) {
150
- const skipped = indexData && indexData.skipped;
151
- if (!skipped) return null;
152
- return { bytes: indexData.totalBytes ?? 0, skipped: { ...skipped }, cap: indexData.cap ?? null };
136
+ const skipped = indexData && indexData.skipped;
137
+ if (!skipped)
138
+ return null;
139
+ return { bytes: indexData.totalBytes ?? 0, skipped: { ...skipped }, cap: indexData.cap ?? null };
153
140
  }
154
-
155
141
  // The serializable half of a parsed query. `parsed.regex` is a RegExp and would
156
142
  // go over the wire as `{}`, so the pattern travels as the text it was typed as.
157
143
  function querySummary(parsed) {
158
- return {
159
- terms: parsed.terms,
160
- phrases: parsed.phrases,
161
- negatives: parsed.negatives,
162
- exts: parsed.exts,
163
- paths: parsed.paths,
164
- kinds: parsed.kinds,
165
- isTest: parsed.isTest,
166
- isSource: parsed.isSource,
167
- regex: parsed.regexSource ? `/${parsed.regexSource}/${parsed.regexFlags}` : null,
168
- caseSensitive: parsed.caseSensitive,
169
- advanced: isAdvanced(parsed),
170
- };
144
+ return {
145
+ terms: parsed.terms,
146
+ phrases: parsed.phrases,
147
+ negatives: parsed.negatives,
148
+ exts: parsed.exts,
149
+ paths: parsed.paths,
150
+ kinds: parsed.kinds,
151
+ isTest: parsed.isTest,
152
+ isSource: parsed.isSource,
153
+ regex: parsed.regexSource ? `/${parsed.regexSource}/${parsed.regexFlags}` : null,
154
+ caseSensitive: parsed.caseSensitive,
155
+ advanced: isAdvanced(parsed),
156
+ };
171
157
  }
172
-
173
158
  // The one entry point the route uses, kept separate from `searchIndex` so the
174
159
  // forgiving ranking that shipped first survives intact: a query of bare words
175
160
  // is still answered by that function, partial matches and all. Only a query the
176
161
  // person made decisions in — a filter, a phrase, a regex, the case toggle —
177
162
  // goes down the strict path, where those decisions are enforced.
178
163
  export function searchDocuments(indexData, rawQuery, options = {}) {
179
- const limit = Number.isFinite(options.limit) ? Math.max(1, Math.floor(options.limit)) : 15;
180
- const parsed = parseQuery(rawQuery, { caseSensitive: !!options.caseSensitive });
181
- const advanced = isAdvanced(parsed);
182
- const base = {
183
- results: [],
184
- total: 0,
185
- indexed: indexData?.totalDocs ?? 0,
186
- capped: false,
187
- advanced,
188
- query: querySummary(parsed),
189
- error: parsed.error,
190
- stats: indexStats(indexData),
191
- };
192
-
193
- if (!indexData || !indexData.totalDocs) return base;
194
- if (queryIsEmpty(parsed)) return base;
195
- // A pattern that would not compile is the whole answer. Reporting "no
196
- // results" instead would send someone hunting for a file sitting right there.
197
- if (parsed.error) return base;
198
-
199
- if (!advanced) {
200
- const ranked = searchIndex(indexData, parsed.terms.join(' '), limit);
201
- return { ...base, results: ranked, total: ranked.length, capped: ranked.length >= limit };
202
- }
203
-
204
- const all = strictSearch(indexData, parsed);
205
- return {
206
- ...base,
207
- results: all.slice(0, limit),
208
- total: all.length,
209
- capped: all.length > limit,
210
- };
164
+ const limit = Number.isFinite(options.limit) ? Math.max(1, Math.floor(options.limit)) : 15;
165
+ const parsed = parseQuery(rawQuery, { caseSensitive: !!options.caseSensitive });
166
+ const advanced = isAdvanced(parsed);
167
+ const base = {
168
+ results: [],
169
+ total: 0,
170
+ indexed: indexData?.totalDocs ?? 0,
171
+ capped: false,
172
+ advanced,
173
+ query: querySummary(parsed),
174
+ error: parsed.error,
175
+ stats: indexStats(indexData),
176
+ };
177
+ if (!indexData || !indexData.totalDocs)
178
+ return base;
179
+ if (queryIsEmpty(parsed))
180
+ return base;
181
+ // A pattern that would not compile is the whole answer. Reporting "no
182
+ // results" instead would send someone hunting for a file sitting right there.
183
+ if (parsed.error)
184
+ return base;
185
+ if (!advanced) {
186
+ const ranked = searchIndex(indexData, parsed.terms.join(' '), limit);
187
+ return { ...base, results: ranked, total: ranked.length, capped: ranked.length >= limit };
188
+ }
189
+ const all = strictSearch(indexData, parsed);
190
+ return {
191
+ ...base,
192
+ results: all.slice(0, limit),
193
+ total: all.length,
194
+ capped: all.length > limit,
195
+ };
211
196
  }
212
-
213
197
  export async function handleSearch(res, body) {
214
- const { scanId, query, limit = 15, caseSensitive = false } = body || {};
215
- if (!scanId) return sendError(res, 400, 'Missing scanId.');
216
- const session = getSession(scanId);
217
- if (!session) return sendError(res, 404, 'Scan not found.');
218
-
219
- const q = (query || '').trim();
220
- if (!q) {
221
- return sendJSON(res, 200, { results: [], total: 0, indexed: session.searchIndex?.totalDocs ?? 0 });
222
- }
223
-
224
- // No index means the scan was opened before this change shipped, or the
225
- // caller is using a session that was never given a scan-time index. The
226
- // honest answer is "no results" rather than rebuilding the whole thing on
227
- // the request thread.
228
- if (!session.searchIndex || session.searchIndex.totalDocs === 0) {
229
- return sendJSON(res, 200, {
230
- results: [],
231
- total: 0,
232
- indexed: 0,
233
- note: 'Nothing was indexed for this scan.',
234
- });
235
- }
236
-
237
- try {
238
- const out = searchDocuments(session.searchIndex, q, { limit, caseSensitive });
239
- return sendJSON(res, 200, {
240
- results: out.results,
241
- total: out.total,
242
- indexed: out.indexed,
243
- capped: out.capped,
244
- advanced: out.advanced,
245
- query: out.query,
246
- error: out.error || null,
247
- stats: out.stats || null,
248
- });
249
- } catch (err) {
250
- return sendError(res, 500, 'Search failed: ' + err.message);
251
- }
198
+ const { scanId, query, limit = 15, caseSensitive = false } = body || {};
199
+ if (!scanId)
200
+ return sendError(res, 400, 'Missing scanId.');
201
+ const session = getSession(scanId);
202
+ if (!session)
203
+ return sendError(res, 404, 'Scan not found.');
204
+ const q = (query || '').trim();
205
+ if (!q) {
206
+ return sendJSON(res, 200, { results: [], total: 0, indexed: session.searchIndex?.totalDocs ?? 0 });
207
+ }
208
+ // No index means the scan was opened before this change shipped, or the
209
+ // caller is using a session that was never given a scan-time index. The
210
+ // honest answer is "no results" rather than rebuilding the whole thing on
211
+ // the request thread.
212
+ if (!session.searchIndex || session.searchIndex.totalDocs === 0) {
213
+ return sendJSON(res, 200, {
214
+ results: [],
215
+ total: 0,
216
+ indexed: 0,
217
+ note: 'Nothing was indexed for this scan.',
218
+ });
219
+ }
220
+ try {
221
+ const out = searchDocuments(session.searchIndex, q, { limit, caseSensitive });
222
+ return sendJSON(res, 200, {
223
+ results: out.results,
224
+ total: out.total,
225
+ indexed: out.indexed,
226
+ capped: out.capped,
227
+ advanced: out.advanced,
228
+ query: out.query,
229
+ error: out.error || null,
230
+ stats: out.stats || null,
231
+ });
232
+ }
233
+ catch (err) {
234
+ return sendError(res, 500, 'Search failed: ' + err.message);
235
+ }
252
236
  }
253
-
237
+ //# sourceMappingURL=apiSearch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apiSearch.js","sourceRoot":"","sources":["../src/server/apiSearch.ts"],"names":[],"mappings":"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","sourcesContent":["// POST /api/search — runs a TF-IDF query against the index built at scan\n// time. The work that used to live here (re-listing the tree, re-reading\n// every file, parsing its tokens) now lives in `searchIndex.js`, which\n// `apiScan.js` invokes once when the scan finishes. What is left in this\n// module is the request shape: validate, look up the session, score, send.\n//\n// The pure scoring functions (`buildTfIdfIndex` for one-off in-memory\n// indexes used by tests, and `searchIndex` for the score-and-snippet pass)\n// are still exported so the front end and tests can construct indexes\n// directly when they need to.\n//\n// There are two ways through, and which one a query takes is the point:\n// `searchIndex` answers a query of bare words the forgiving way it always\n// did — partial matches, ranked by TF-IDF — while `searchDocuments` parses\n// the shared query language (`shared/search/query.js`, the same module the\n// palette uses) and enforces anything the person actually decided: filters,\n// phrases, regexes, the case toggle. A half-remembered name should still find\n// the file; `ext:js -vendor` should not be negotiated with.\n\nimport { getSession } from './sessions.js';\nimport { sendError, sendJSON } from './http.js';\nimport {\n isAdvanced, lineOfIndex, matchesPathFilters, parseQuery, queryIsEmpty,\n scoreContent, scorePath, snippetAt,\n} from '../shared/search/query.js';\n\nexport function buildTfIdfIndex(documents) {\n // documents: [{ path, content }]\n const index = new Map();\n const docCounts = new Map();\n let totalDocs = 0;\n\n for (const doc of documents) {\n if (!doc.content || typeof doc.content !== 'string') continue;\n const tokens = doc.content.toLowerCase().split(/\\W+/).filter((t) => t.length > 1);\n if (!tokens.length) continue;\n totalDocs++;\n\n const tf = new Map();\n for (const t of tokens) {\n tf.set(t, (tf.get(t) || 0) + 1);\n }\n for (const t of tf.keys()) {\n docCounts.set(t, (docCounts.get(t) || 0) + 1);\n }\n index.set(doc.path, { tf, content: doc.content, tokenCount: tokens.length });\n }\n\n return { index, docCounts, totalDocs };\n}\n\nexport function searchIndex(indexData, queryString, limit = 10) {\n if (!indexData || !queryString) return [];\n const terms = queryString.toLowerCase().split(/\\s+/).filter((t) => t.length > 0);\n if (!terms.length) return [];\n\n const { index, docCounts, totalDocs } = indexData;\n if (!totalDocs) return [];\n\n const idf = new Map();\n for (const t of terms) {\n const df = docCounts.get(t) || 0;\n idf.set(t, df === 0 ? 0 : Math.log(1 + totalDocs / df));\n }\n\n const results = [];\n for (const [docPath, data] of index.entries()) {\n let score = 0;\n let matchCount = 0;\n for (const t of terms) {\n const tf = data.tf.get(t) || 0;\n if (tf > 0) {\n matchCount++;\n // Normalized TF * IDF\n score += (tf / Math.sqrt(data.tokenCount)) * (idf.get(t) || 1);\n }\n }\n\n if (score > 0) {\n // Find best snippet\n const lowerContent = data.content.toLowerCase();\n let bestIdx = -1;\n for (const t of terms) {\n const idx = lowerContent.indexOf(t);\n if (idx !== -1 && (bestIdx === -1 || idx < bestIdx)) {\n bestIdx = idx;\n }\n }\n\n let snippet = '';\n let line = 1;\n if (bestIdx !== -1) {\n const linesBefore = data.content.slice(0, bestIdx).split('\\n');\n line = linesBefore.length;\n const allLines = data.content.split('\\n');\n const targetLine = (allLines[line - 1] || '').trim();\n snippet = targetLine.length > 120 ? targetLine.slice(0, 117) + '…' : targetLine;\n }\n\n results.push({\n path: docPath,\n score: score * (matchCount / terms.length), // Boost docs containing all terms\n snippet,\n line,\n });\n }\n }\n\n results.sort((a, b) => b.score - a.score);\n return results.slice(0, limit);\n}\n\n// The strict pass: filters are gates, not hints, and every term has to land.\n// Ranking is positional — `scorePath` and `scoreContent` reward the file whose\n// name matches and the file where the word appears early — because a query with\n// a regex or a filter in it is a person who knows what they want, and does not\n// need the corpus statistics of `searchIndex` second-guessing them.\nfunction strictSearch(indexData, parsed) {\n // `kind:` is a statement about symbols, and content cannot answer it. A query\n // that is *only* a kind filter is answered by the palette's symbol pass and\n // by nothing here, which is the honest result rather than \"every file\".\n const kindOnly = parsed.kinds.length > 0\n && !parsed.terms.length && !parsed.phrases.length && !parsed.regex;\n\n const results = [];\n for (const [docPath, doc] of indexData.index.entries()) {\n if (kindOnly) break;\n if (!matchesPathFilters(parsed, docPath)) continue;\n\n const pathScore = scorePath(parsed, docPath);\n const content = scoreContent(parsed, doc.content);\n if (!pathScore && !content.score) continue;\n\n const at = content.index;\n results.push({\n path: docPath,\n score: pathScore + content.score,\n line: at >= 0 ? lineOfIndex(doc.content, at) : 1,\n snippet: snippetAt(doc.content, at >= 0 ? at : 0),\n });\n }\n\n results.sort((a, b) => b.score - a.score || a.path.localeCompare(b.path));\n return results;\n}\n\n// What the index could not read, in the shape the palette can say out loud —\n// \"searched 127 files, 3 skipped\" beats a mystery file that never turns up.\nfunction indexStats(indexData) {\n const skipped = indexData && indexData.skipped;\n if (!skipped) return null;\n return { bytes: indexData.totalBytes ?? 0, skipped: { ...skipped }, cap: indexData.cap ?? null };\n}\n\n// The serializable half of a parsed query. `parsed.regex` is a RegExp and would\n// go over the wire as `{}`, so the pattern travels as the text it was typed as.\nfunction querySummary(parsed) {\n return {\n terms: parsed.terms,\n phrases: parsed.phrases,\n negatives: parsed.negatives,\n exts: parsed.exts,\n paths: parsed.paths,\n kinds: parsed.kinds,\n isTest: parsed.isTest,\n isSource: parsed.isSource,\n regex: parsed.regexSource ? `/${parsed.regexSource}/${parsed.regexFlags}` : null,\n caseSensitive: parsed.caseSensitive,\n advanced: isAdvanced(parsed),\n };\n}\n\n// The one entry point the route uses, kept separate from `searchIndex` so the\n// forgiving ranking that shipped first survives intact: a query of bare words\n// is still answered by that function, partial matches and all. Only a query the\n// person made decisions in — a filter, a phrase, a regex, the case toggle —\n// goes down the strict path, where those decisions are enforced.\nexport function searchDocuments(indexData, rawQuery, options: Record<string, any> = {}) {\n const limit = Number.isFinite(options.limit) ? Math.max(1, Math.floor(options.limit)) : 15;\n const parsed = parseQuery(rawQuery, { caseSensitive: !!options.caseSensitive });\n const advanced = isAdvanced(parsed);\n const base = {\n results: [],\n total: 0,\n indexed: indexData?.totalDocs ?? 0,\n capped: false,\n advanced,\n query: querySummary(parsed),\n error: parsed.error,\n stats: indexStats(indexData),\n };\n\n if (!indexData || !indexData.totalDocs) return base;\n if (queryIsEmpty(parsed)) return base;\n // A pattern that would not compile is the whole answer. Reporting \"no\n // results\" instead would send someone hunting for a file sitting right there.\n if (parsed.error) return base;\n\n if (!advanced) {\n const ranked = searchIndex(indexData, parsed.terms.join(' '), limit);\n return { ...base, results: ranked, total: ranked.length, capped: ranked.length >= limit };\n }\n\n const all = strictSearch(indexData, parsed);\n return {\n ...base,\n results: all.slice(0, limit),\n total: all.length,\n capped: all.length > limit,\n };\n}\n\nexport async function handleSearch(res, body) {\n const { scanId, query, limit = 15, caseSensitive = false } = body || {};\n if (!scanId) return sendError(res, 400, 'Missing scanId.');\n const session = getSession(scanId);\n if (!session) return sendError(res, 404, 'Scan not found.');\n\n const q = (query || '').trim();\n if (!q) {\n return sendJSON(res, 200, { results: [], total: 0, indexed: session.searchIndex?.totalDocs ?? 0 });\n }\n\n // No index means the scan was opened before this change shipped, or the\n // caller is using a session that was never given a scan-time index. The\n // honest answer is \"no results\" rather than rebuilding the whole thing on\n // the request thread.\n if (!session.searchIndex || session.searchIndex.totalDocs === 0) {\n return sendJSON(res, 200, {\n results: [],\n total: 0,\n indexed: 0,\n note: 'Nothing was indexed for this scan.',\n });\n }\n\n try {\n const out = searchDocuments(session.searchIndex, q, { limit, caseSensitive });\n return sendJSON(res, 200, {\n results: out.results,\n total: out.total,\n indexed: out.indexed,\n capped: out.capped,\n advanced: out.advanced,\n query: out.query,\n error: out.error || null,\n stats: out.stats || null,\n });\n } catch (err) {\n return sendError(res, 500, 'Search failed: ' + err.message);\n }\n}\n\n"]}
@@ -0,0 +1,4 @@
1
+ export declare function handleGetSettings(req: any, res: any, config: any): Promise<void>;
2
+ export declare function handleUpdateSettings(res: any, body: any, config: any): Promise<void>;
3
+ export declare function handleRotateAccessKey(req: any, res: any, config: any): Promise<void>;
4
+ export declare function validatePatch(patch: any): import("../shared/contracts.js").Settings;