codebase-onboarder 0.5.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 +196 -47
  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 +449 -0
  8. package/cli/explorer/advanced.js.map +1 -0
  9. package/cli/explorer/app.d.ts +1 -0
  10. package/cli/explorer/app.js +396 -229
  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 +400 -162
  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 +73 -0
  23. package/cli/explorer/github.js.map +1 -0
  24. package/cli/explorer/graphs.d.ts +7 -0
  25. package/cli/explorer/graphs.js +173 -0
  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 +184 -95
  35. package/cli/explorer/session.js.map +1 -0
  36. package/cli/explorer/views.d.ts +19 -0
  37. package/cli/explorer/views.js +496 -412
  38. package/cli/explorer/views.js.map +1 -0
  39. package/cli/explorer/wrap.d.ts +1 -0
  40. package/cli/explorer/wrap.js +33 -0
  41. package/cli/explorer/wrap.js.map +1 -0
  42. package/cli/main.d.ts +1 -0
  43. package/cli/main.js +235 -138
  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 +55 -35
  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 +165 -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 +60 -0
  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 -37
  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 +79 -0
  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
package/public/js/llm.js CHANGED
@@ -1,292 +1,257 @@
1
1
  // LLM settings and prompt assembly. The key lives in localStorage and only
2
2
  // ever travels to the local server, which forwards it to whatever
3
3
  // OpenAI-compatible endpoint the user pointed at.
4
-
5
4
  const STORE_KEY = 'onboarder.llm.v1';
6
-
7
5
  // No endpoint, model, or key ships with the repo. Anything saved in the
8
6
  // API-key drawer overrides these empty defaults (localStorage wins); without
9
7
  // a saved endpoint the app stays on the offline graph explanations.
10
8
  export const DEFAULT_SETTINGS = {
11
- baseUrl: '',
12
- apiKey: '',
13
- model: '',
9
+ baseUrl: '',
10
+ apiKey: '',
11
+ model: '',
14
12
  };
15
-
16
13
  export function getSettings() {
17
- try {
18
- return { ...DEFAULT_SETTINGS, ...JSON.parse(localStorage.getItem(STORE_KEY) || '{}') };
19
- } catch {
20
- return { ...DEFAULT_SETTINGS };
21
- }
14
+ try {
15
+ return { ...DEFAULT_SETTINGS, ...JSON.parse(localStorage.getItem(STORE_KEY) || '{}') };
16
+ }
17
+ catch {
18
+ return { ...DEFAULT_SETTINGS };
19
+ }
22
20
  }
23
-
24
21
  export function saveSettings(settings) {
25
- localStorage.setItem(STORE_KEY, JSON.stringify({
26
- baseUrl: (settings.baseUrl || '').trim().replace(/\/+$/, ''),
27
- apiKey: settings.apiKey || '',
28
- model: (settings.model || '').trim(),
29
- }));
22
+ localStorage.setItem(STORE_KEY, JSON.stringify({
23
+ baseUrl: (settings.baseUrl || '').trim().replace(/\/+$/, ''),
24
+ apiKey: settings.apiKey || '',
25
+ model: (settings.model || '').trim(),
26
+ }));
30
27
  }
31
-
32
28
  export function isConfigured() {
33
- const s = getSettings();
34
- return Boolean(s.baseUrl && s.model);
29
+ const s = getSettings();
30
+ return Boolean(s.baseUrl && s.model);
35
31
  }
36
-
37
32
  // Azure OpenAI speaks a slightly different dialect than the rest: api-key
38
33
  // header (handled server-side) and no `reasoning` request parameter.
39
34
  export function isAzureHost(baseUrl) {
40
- return /\.openai\.azure\.com|\.cognitiveservices\.azure\.com/i.test(baseUrl || '');
35
+ return /\.openai\.azure\.com|\.cognitiveservices\.azure\.com/i.test(baseUrl || '');
41
36
  }
42
-
43
37
  const SYSTEM_PROMPT = [
44
- 'You are a senior engineer walking a new teammate through a codebase they have never seen.',
45
- 'Write like a person, not a product page: plain sentences, concrete names, no hype, no bullet-point cosplay unless a list is genuinely clearer.',
46
- 'Keep it under 180 words. Refer to files and functions by their real names in backticks.',
47
- 'If something looks risky to change, say so plainly.',
38
+ 'You are a senior engineer walking a new teammate through a codebase they have never seen.',
39
+ 'Write like a person, not a product page: plain sentences, concrete names, no hype, no bullet-point cosplay unless a list is genuinely clearer.',
40
+ 'Keep it under 180 words. Refer to files and functions by their real names in backticks.',
41
+ 'If something looks risky to change, say so plainly.',
48
42
  ].join(' ');
49
-
50
43
  export function fileMessages({ repoName, overview, path, role, fanIn, fanOut, importers, imports, functions, exports_, source }) {
51
- const context = [
52
- `Repository: ${repoName}`,
53
- overview ? `Big picture: ${overview}` : '',
54
- '',
55
- `File: ${path} (role: ${role})`,
56
- `Imported by ${fanIn} files: ${importers.slice(0, 8).join(', ') || 'none'}`,
57
- `Imports ${fanOut} files: ${imports.slice(0, 8).join(', ') || 'none'}`,
58
- functions?.length ? `Functions: ${functions.slice(0, 14).join(', ')}` : '',
59
- exports_?.length ? `Exports: ${exports_.slice(0, 10).join(', ')}` : '',
60
- ].filter(Boolean).join('\n');
61
-
62
- const user = source
63
- ? `${context}\n\nHere is the source, possibly truncated:\n\`\`\`\n${source.slice(0, 12000)}\n\`\`\`\n\nExplain what this file does, how it fits into the repo, and what breaks if it is deleted.`
64
- : `${context}\n\n(Source was not available.) Explain what this file most likely does, how it fits into the repo, and what breaks if it is deleted. Say what you are inferring versus what the graph proves.`;
65
-
66
- return [
67
- { role: 'system', content: SYSTEM_PROMPT },
68
- { role: 'user', content: user },
69
- ];
44
+ const context = [
45
+ `Repository: ${repoName}`,
46
+ overview ? `Big picture: ${overview}` : '',
47
+ '',
48
+ `File: ${path} (role: ${role})`,
49
+ `Imported by ${fanIn} files: ${importers.slice(0, 8).join(', ') || 'none'}`,
50
+ `Imports ${fanOut} files: ${imports.slice(0, 8).join(', ') || 'none'}`,
51
+ functions?.length ? `Functions: ${functions.slice(0, 14).join(', ')}` : '',
52
+ exports_?.length ? `Exports: ${exports_.slice(0, 10).join(', ')}` : '',
53
+ ].filter(Boolean).join('\n');
54
+ const user = source
55
+ ? `${context}\n\nHere is the source, possibly truncated:\n\`\`\`\n${source.slice(0, 12000)}\n\`\`\`\n\nExplain what this file does, how it fits into the repo, and what breaks if it is deleted.`
56
+ : `${context}\n\n(Source was not available.) Explain what this file most likely does, how it fits into the repo, and what breaks if it is deleted. Say what you are inferring versus what the graph proves.`;
57
+ return [
58
+ { role: 'system', content: SYSTEM_PROMPT },
59
+ { role: 'user', content: user },
60
+ ];
70
61
  }
71
-
72
62
  export function overviewMessages({ repoName, overview, entries, hubs, services, cycles, orphans, languages }) {
73
- const user = [
74
- `Repository: ${repoName}`,
75
- `Languages: ${languages}`,
76
- overview ? `Static notes: ${overview}` : '',
77
- entries?.length ? `Entry points: ${entries.slice(0, 5).join(', ')}` : '',
78
- hubs?.length ? `Most-depended-on files: ${hubs.slice(0, 5).map((h) => h.path + ' (' + h.fanIn + ')').join(', ')}` : '',
79
- services?.length ? `Services: ${services.map((s) => s.name).join(', ')}` : '',
80
- cycles?.length ? `${cycles.length} circular dependencies` : '',
81
- orphans?.length ? `${orphans.length} files imported by nothing` : '',
82
- '',
83
- 'Give a new teammate the orientation you would give on their first day: what this thing is, where to start reading, and which files to treat with respect.',
84
- ].filter(Boolean).join('\n');
85
-
86
- return [
87
- { role: 'system', content: SYSTEM_PROMPT },
88
- { role: 'user', content: user },
89
- ];
63
+ const user = [
64
+ `Repository: ${repoName}`,
65
+ `Languages: ${languages}`,
66
+ overview ? `Static notes: ${overview}` : '',
67
+ entries?.length ? `Entry points: ${entries.slice(0, 5).join(', ')}` : '',
68
+ hubs?.length ? `Most-depended-on files: ${hubs.slice(0, 5).map((h) => h.path + ' (' + h.fanIn + ')').join(', ')}` : '',
69
+ services?.length ? `Services: ${services.map((s) => s.name).join(', ')}` : '',
70
+ cycles?.length ? `${cycles.length} circular dependencies` : '',
71
+ orphans?.length ? `${orphans.length} files imported by nothing` : '',
72
+ '',
73
+ 'Give a new teammate the orientation you would give on their first day: what this thing is, where to start reading, and which files to treat with respect.',
74
+ ].filter(Boolean).join('\n');
75
+ return [
76
+ { role: 'system', content: SYSTEM_PROMPT },
77
+ { role: 'user', content: user },
78
+ ];
90
79
  }
91
-
92
80
  // Diagram generation prompts. The model gets compact graph facts and returns
93
81
  // a Mermaid flowchart with a caption; the theme is injected by us afterwards
94
82
  // so AI drafts look exactly like the hand-drawn ones.
95
-
96
83
  const DIAGRAM_PROMPT = [
97
- 'You turn codebase facts into Mermaid flowcharts that teach.',
98
- 'Output format, exactly: first line `%% caption: <one honest sentence about what the diagram shows>`, then the flowchart source. Nothing else — no fences, no commentary, no sign-off.',
99
- 'Rules: start with `flowchart LR` or `flowchart TD` on its own line; use short alphanumeric ids (a1, b2); put every label in "double quotes"; at most 36 nodes; group with subgraphs where it helps; A --> B means A depends on B; no click, style or linkStyle statements.',
100
- 'Where you can infer what a group of files is FOR, name the cluster by its purpose instead of repeating folder names.',
84
+ 'You turn codebase facts into Mermaid flowcharts that teach.',
85
+ 'Output format, exactly: first line `%% caption: <one honest sentence about what the diagram shows>`, then the flowchart source. Nothing else — no fences, no commentary, no sign-off.',
86
+ 'Rules: start with `flowchart LR` or `flowchart TD` on its own line; use short alphanumeric ids (a1, b2); put every label in "double quotes"; at most 36 nodes; group with subgraphs where it helps; A --> B means A depends on B; no click, style or linkStyle statements.',
87
+ 'Where you can infer what a group of files is FOR, name the cluster by its purpose instead of repeating folder names.',
101
88
  ].join(' ');
102
-
103
89
  export function diagramMessages({ repoName, kind, facts }) {
104
- const user = [
105
- `Repository: ${repoName}`,
106
- `Diagram to draw: ${kind}`,
107
- 'Facts:',
108
- facts.join('\n'),
109
- '',
110
- `Draw the most useful ${kind} for someone who has never seen this codebase.`,
111
- ].join('\n');
112
-
113
- return [
114
- { role: 'system', content: DIAGRAM_PROMPT },
115
- { role: 'user', content: user },
116
- ];
90
+ const user = [
91
+ `Repository: ${repoName}`,
92
+ `Diagram to draw: ${kind}`,
93
+ 'Facts:',
94
+ facts.join('\n'),
95
+ '',
96
+ `Draw the most useful ${kind} for someone who has never seen this codebase.`,
97
+ ].join('\n');
98
+ return [
99
+ { role: 'system', content: DIAGRAM_PROMPT },
100
+ { role: 'user', content: user },
101
+ ];
117
102
  }
118
-
119
103
  // ---- documentation prompts -------------------------------------------------
120
-
121
104
  const DOC_SYSTEM = [
122
- 'You write documentation for a codebase as a senior engineer would: concrete, calm, specific.',
123
- 'Plain sentences. Real names. No hype, no filler, no "this file plays a crucial role".',
105
+ 'You write documentation for a codebase as a senior engineer would: concrete, calm, specific.',
106
+ 'Plain sentences. Real names. No hype, no filler, no "this file plays a crucial role".',
124
107
  ].join(' ');
125
-
126
108
  // Detailed reference notes for one file or folder, opened as a tab in Docs.
127
109
  const FILE_DOC_SYSTEM = [
128
- 'You write detailed reference notes for one file in a codebase, as a senior engineer would for a new teammate.',
129
- 'Concrete and specific: real names, real numbers, no filler. Answer in Markdown with exactly these sections, in this order:',
130
- '## Purpose',
131
- '## How it fits',
132
- '## Key parts',
133
- '## Handle with care',
134
- 'Keep "Key parts" a short bullet list of the functions or exports that matter. Under 350 words total. If a section honestly has nothing to say, one line saying so.',
110
+ 'You write detailed reference notes for one file in a codebase, as a senior engineer would for a new teammate.',
111
+ 'Concrete and specific: real names, real numbers, no filler. Answer in Markdown with exactly these sections, in this order:',
112
+ '## Purpose',
113
+ '## How it fits',
114
+ '## Key parts',
115
+ '## Handle with care',
116
+ 'Keep "Key parts" a short bullet list of the functions or exports that matter. Under 350 words total. If a section honestly has nothing to say, one line saying so.',
135
117
  ].join('\n');
136
-
137
118
  const FOLDER_DOC_SYSTEM = [
138
- 'You write detailed reference notes for one folder in a codebase, as a senior engineer would for a new teammate.',
139
- 'Concrete and specific: real names, no filler. Answer in Markdown with exactly these sections, in this order:',
140
- '## Purpose',
141
- '## How the parts cooperate',
142
- '## The files that matter',
143
- '## Handle with care',
144
- 'Under 300 words total. Say what you infer from names and import facts versus what you know.',
119
+ 'You write detailed reference notes for one folder in a codebase, as a senior engineer would for a new teammate.',
120
+ 'Concrete and specific: real names, no filler. Answer in Markdown with exactly these sections, in this order:',
121
+ '## Purpose',
122
+ '## How the parts cooperate',
123
+ '## The files that matter',
124
+ '## Handle with care',
125
+ 'Under 300 words total. Say what you infer from names and import facts versus what you know.',
145
126
  ].join('\n');
146
-
147
127
  export function fileDocMessages({ repoName, overview, file }) {
148
- const blocks = [
149
- `Repository: ${repoName}`,
150
- overview ? `Big picture: ${overview}` : '',
151
- `File: ${file.path} (role: ${file.role})`,
152
- `Imported by ${file.fanIn} files: ${file.importers.slice(0, 8).join(', ') || 'none'}`,
153
- `Imports ${file.fanOut} files: ${file.imports.slice(0, 8).join(', ') || 'none'}`,
154
- file.functions?.length ? `Functions: ${file.functions.slice(0, 14).join(', ')}` : '',
155
- file.exports_?.length ? `Exports: ${file.exports_.slice(0, 10).join(', ')}` : '',
156
- file.source
157
- ? `Source, possibly truncated:\n\`\`\`\n${file.source.slice(0, 12000)}\n\`\`\``
158
- : '(Source unavailable — write from the graph facts and say what you are inferring.)',
159
- ].filter(Boolean);
160
- return [
161
- { role: 'system', content: FILE_DOC_SYSTEM },
162
- { role: 'user', content: blocks.join('\n') },
163
- ];
128
+ const blocks = [
129
+ `Repository: ${repoName}`,
130
+ overview ? `Big picture: ${overview}` : '',
131
+ `File: ${file.path} (role: ${file.role})`,
132
+ `Imported by ${file.fanIn} files: ${file.importers.slice(0, 8).join(', ') || 'none'}`,
133
+ `Imports ${file.fanOut} files: ${file.imports.slice(0, 8).join(', ') || 'none'}`,
134
+ file.functions?.length ? `Functions: ${file.functions.slice(0, 14).join(', ')}` : '',
135
+ file.exports_?.length ? `Exports: ${file.exports_.slice(0, 10).join(', ')}` : '',
136
+ file.source
137
+ ? `Source, possibly truncated:\n\`\`\`\n${file.source.slice(0, 12000)}\n\`\`\``
138
+ : '(Source unavailable — write from the graph facts and say what you are inferring.)',
139
+ ].filter(Boolean);
140
+ return [
141
+ { role: 'system', content: FILE_DOC_SYSTEM },
142
+ { role: 'user', content: blocks.join('\n') },
143
+ ];
164
144
  }
165
-
166
145
  export function folderDocDetailedMessages({ repoName, folder, subfolders, files }) {
167
- const lines = files.map((f) =>
168
- `- ${f.name} — ${f.fanIn} dependents, pulls in ${f.fanOut}` +
169
- (f.role !== 'module' ? `, role: ${f.role}` : '') +
170
- (f.functions.length ? `, functions: ${f.functions.slice(0, 5).join(', ')}` : '')
171
- );
172
- const user = [
173
- `Repository: ${repoName}`,
174
- `Folder: ${folder || '(repo root)'}`,
175
- subfolders?.length ? `Subfolders: ${subfolders.join(', ')}` : '',
176
- 'Files with import-graph facts:',
177
- lines.join('\n') || '(no files directly here)',
178
- ].filter(Boolean).join('\n');
179
- return [
180
- { role: 'system', content: FOLDER_DOC_SYSTEM },
181
- { role: 'user', content: user },
182
- ];
146
+ const lines = files.map((f) => `- ${f.name} — ${f.fanIn} dependents, pulls in ${f.fanOut}` +
147
+ (f.role !== 'module' ? `, role: ${f.role}` : '') +
148
+ (f.functions.length ? `, functions: ${f.functions.slice(0, 5).join(', ')}` : ''));
149
+ const user = [
150
+ `Repository: ${repoName}`,
151
+ `Folder: ${folder || '(repo root)'}`,
152
+ subfolders?.length ? `Subfolders: ${subfolders.join(', ')}` : '',
153
+ 'Files with import-graph facts:',
154
+ lines.join('\n') || '(no files directly here)',
155
+ ].filter(Boolean).join('\n');
156
+ return [
157
+ { role: 'system', content: FOLDER_DOC_SYSTEM },
158
+ { role: 'user', content: user },
159
+ ];
183
160
  }
184
-
185
161
  export function repoDocMessages({ repoName, overview, readmeExcerpt, entries, hubs }) {
186
- const user = [
187
- `Repository: ${repoName}`,
188
- overview ? `Static analysis notes: ${overview}` : '',
189
- entries?.length ? `Entry points: ${entries.slice(0, 5).join(', ')}` : '',
190
- hubs?.length ? `Most depended-on files: ${hubs.slice(0, 5).map((h) => h.path + ' (' + h.fanIn + ')').join(', ')}` : '',
191
- readmeExcerpt ? `The project's own README begins:\n"""\n${readmeExcerpt.slice(0, 1500)}\n"""` : '(No README found.)',
192
- '',
193
- 'Write 3–4 sentences of high-level overview for a brand-new teammate: what this project is, how it is organized at the top level, and where to start reading. Plain prose only — no headings, no bullets.',
194
- ].filter(Boolean).join('\n');
195
-
196
- return [
197
- { role: 'system', content: DOC_SYSTEM },
198
- { role: 'user', content: user },
199
- ];
162
+ const user = [
163
+ `Repository: ${repoName}`,
164
+ overview ? `Static analysis notes: ${overview}` : '',
165
+ entries?.length ? `Entry points: ${entries.slice(0, 5).join(', ')}` : '',
166
+ hubs?.length ? `Most depended-on files: ${hubs.slice(0, 5).map((h) => h.path + ' (' + h.fanIn + ')').join(', ')}` : '',
167
+ readmeExcerpt ? `The project's own README begins:\n"""\n${readmeExcerpt.slice(0, 1500)}\n"""` : '(No README found.)',
168
+ '',
169
+ 'Write 3–4 sentences of high-level overview for a brand-new teammate: what this project is, how it is organized at the top level, and where to start reading. Plain prose only — no headings, no bullets.',
170
+ ].filter(Boolean).join('\n');
171
+ return [
172
+ { role: 'system', content: DOC_SYSTEM },
173
+ { role: 'user', content: user },
174
+ ];
200
175
  }
201
-
202
176
  export function folderDocMessages({ repoName, folder, subfolders, files }) {
203
- const fileLines = files.map((f) => {
204
- if (!f.parsed) return `- ${f.name} — not parsed (asset or data)`;
205
- const bits = [`${f.fanIn} dependents`, `pulls in ${f.fanOut}`];
206
- if (f.role !== 'module') bits.push('role: ' + f.role);
207
- if (f.functions.length) bits.push('functions: ' + f.functions.slice(0, 5).join(', '));
208
- return `- ${f.name} — ${bits.join(', ')}`;
209
- });
210
-
211
- const user = [
212
- `Repository: ${repoName}`,
213
- `Folder under review: ${folder || '(repo root)'}`,
214
- subfolders?.length ? `Subfolders inside it: ${subfolders.join(', ')}` : '',
215
- 'Files (with import-graph facts):',
216
- fileLines.join('\n') || '(no files directly here)',
217
- '',
218
- 'Write complete documentation for this folder, in exactly this format, no preamble, no fences:',
219
- 'FOLDER: <3-5 sentences — what lives here, why it exists, how the parts cooperate, and what a newcomer should read first>',
220
- ...files.filter((f) => f.parsed).map((f) => `FILE: ${f.name}: <2-3 sentences — what this file is for, who it talks to, and what to handle with care>`),
221
- ].filter(Boolean).join('\n');
222
-
223
- return [
224
- { role: 'system', content: DOC_SYSTEM },
225
- { role: 'user', content: user },
226
- ];
177
+ const fileLines = files.map((f) => {
178
+ if (!f.parsed)
179
+ return `- ${f.name} — not parsed (asset or data)`;
180
+ const bits = [`${f.fanIn} dependents`, `pulls in ${f.fanOut}`];
181
+ if (f.role !== 'module')
182
+ bits.push('role: ' + f.role);
183
+ if (f.functions.length)
184
+ bits.push('functions: ' + f.functions.slice(0, 5).join(', '));
185
+ return `- ${f.name} — ${bits.join(', ')}`;
186
+ });
187
+ const user = [
188
+ `Repository: ${repoName}`,
189
+ `Folder under review: ${folder || '(repo root)'}`,
190
+ subfolders?.length ? `Subfolders inside it: ${subfolders.join(', ')}` : '',
191
+ 'Files (with import-graph facts):',
192
+ fileLines.join('\n') || '(no files directly here)',
193
+ '',
194
+ 'Write complete documentation for this folder, in exactly this format, no preamble, no fences:',
195
+ 'FOLDER: <3-5 sentences — what lives here, why it exists, how the parts cooperate, and what a newcomer should read first>',
196
+ ...files.filter((f) => f.parsed).map((f) => `FILE: ${f.name}: <2-3 sentences — what this file is for, who it talks to, and what to handle with care>`),
197
+ ].filter(Boolean).join('\n');
198
+ return [
199
+ { role: 'system', content: DOC_SYSTEM },
200
+ { role: 'user', content: user },
201
+ ];
227
202
  }
228
-
229
203
  const QUESTION_PROMPT = [
230
- 'You are a senior engineer answering a teammate\'s question about a codebase.',
231
- 'Answer directly and concretely, citing real file and function names in backticks.',
232
- 'If the answer is not in the graph facts or source you were given, say so plainly and name the file you would open next to find out.',
233
- 'Keep it under 200 words unless the question genuinely needs more.',
204
+ 'You are a senior engineer answering a teammate\'s question about a codebase.',
205
+ 'Answer directly and concretely, citing real file and function names in backticks.',
206
+ 'If the answer is not in the graph facts or source you were given, say so plainly and name the file you would open next to find out.',
207
+ 'Keep it under 200 words unless the question genuinely needs more.',
234
208
  ].join(' ');
235
-
236
209
  // A free-form question. When the user has a file selected, its facts and
237
210
  // source ride along; otherwise the model reasons from the repo overview.
238
211
  export function questionMessages({ repoName, overview, question, file }) {
239
- const blocks = [
240
- `Repository: ${repoName}`,
241
- overview ? `Big picture: ${overview}` : '',
242
- ];
243
-
244
- if (file) {
245
- blocks.push(
246
- `The user is currently looking at: ${file.path} (role: ${file.role})`,
247
- `Imported by ${file.fanIn} files: ${file.importers.slice(0, 8).join(', ') || 'none'}`,
248
- `Imports ${file.fanOut} files: ${file.imports.slice(0, 8).join(', ') || 'none'}`
249
- );
250
- if (file.functions?.length) blocks.push(`Functions: ${file.functions.slice(0, 14).join(', ')}`);
251
- if (file.exports_?.length) blocks.push(`Exports: ${file.exports_.slice(0, 10).join(', ')}`);
252
- if (file.source) {
253
- blocks.push(`Source of ${file.path}, possibly truncated:\n\`\`\`\n${file.source.slice(0, 12000)}\n\`\`\``);
254
- } else {
255
- blocks.push('(Source for that file was not available — answer from the graph facts and say so.)');
212
+ const blocks = [
213
+ `Repository: ${repoName}`,
214
+ overview ? `Big picture: ${overview}` : '',
215
+ ];
216
+ if (file) {
217
+ blocks.push(`The user is currently looking at: ${file.path} (role: ${file.role})`, `Imported by ${file.fanIn} files: ${file.importers.slice(0, 8).join(', ') || 'none'}`, `Imports ${file.fanOut} files: ${file.imports.slice(0, 8).join(', ') || 'none'}`);
218
+ if (file.functions?.length)
219
+ blocks.push(`Functions: ${file.functions.slice(0, 14).join(', ')}`);
220
+ if (file.exports_?.length)
221
+ blocks.push(`Exports: ${file.exports_.slice(0, 10).join(', ')}`);
222
+ if (file.source) {
223
+ blocks.push(`Source of ${file.path}, possibly truncated:\n\`\`\`\n${file.source.slice(0, 12000)}\n\`\`\``);
224
+ }
225
+ else {
226
+ blocks.push('(Source for that file was not available — answer from the graph facts and say so.)');
227
+ }
256
228
  }
257
- }
258
-
259
- blocks.push(`Question: ${question}`);
260
-
261
- return [
262
- { role: 'system', content: QUESTION_PROMPT },
263
- { role: 'user', content: blocks.filter(Boolean).join('\n') },
264
- ];
229
+ blocks.push(`Question: ${question}`);
230
+ return [
231
+ { role: 'system', content: QUESTION_PROMPT },
232
+ { role: 'user', content: blocks.filter(Boolean).join('\n') },
233
+ ];
265
234
  }
266
-
267
-
268
235
  // Used by the About tab to summarize a detected framework/library: the model
269
236
  // reasons from the official docs excerpt (when fetched) plus the repo's own
270
237
  // context. docsText may be empty — the prompt says so and falls back to
271
238
  // general knowledge.
272
239
  export function stackSummaryMessages({ repoName, item, docsText, repoNote }) {
273
- const system =
274
- 'You are a senior developer writing compact field notes for a codebase onboarding tool. Be specific and honest; distinguish between what the docs state and what you infer. No headings, no "Sure" / "Absolutely" openers, no filler.';
275
- const declared = item.version
276
- ? `The project declares ${item.name} ${item.version} (${item.category}, ${item.lang}${item.dev ? ', dev dependency' : ''}).`
277
- : `The project uses ${item.name} (${item.category}, ${item.lang}).`;
278
- const user = [
279
- `Repository: ${repoName}.`,
280
- declared,
281
- `Repo context: ${repoNote}`,
282
- docsText
283
- ? `Official docs excerpt:\n${docsText}`
284
- : 'No official docs could be fetched for this dependency — rely on your own knowledge and say so in one short clause.',
285
- 'In 2-4 sentences: what this is, why the project likely chose it, and anything a new teammate should know about using it here.',
286
- ].join('\n\n');
287
- return [{ role: 'system', content: system }, { role: 'user', content: user }];
240
+ const system = 'You are a senior developer writing compact field notes for a codebase onboarding tool. Be specific and honest; distinguish between what the docs state and what you infer. No headings, no "Sure" / "Absolutely" openers, no filler.';
241
+ const declared = item.version
242
+ ? `The project declares ${item.name} ${item.version} (${item.category}, ${item.lang}${item.dev ? ', dev dependency' : ''}).`
243
+ : `The project uses ${item.name} (${item.category}, ${item.lang}).`;
244
+ const user = [
245
+ `Repository: ${repoName}.`,
246
+ declared,
247
+ `Repo context: ${repoNote}`,
248
+ docsText
249
+ ? `Official docs excerpt:\n${docsText}`
250
+ : 'No official docs could be fetched for this dependency — rely on your own knowledge and say so in one short clause.',
251
+ 'In 2-4 sentences: what this is, why the project likely chose it, and anything a new teammate should know about using it here.',
252
+ ].join('\n\n');
253
+ return [{ role: 'system', content: system }, { role: 'user', content: user }];
288
254
  }
289
-
290
255
  // The Deep Analysis report, read back by the model. Two jobs in one builder: a
291
256
  // report is either *explained* (no question — prioritize what to fix) or asked
292
257
  // about ("is the eval finding actually reachable?"). The engine list is part of
@@ -294,52 +259,48 @@ export function stackSummaryMessages({ repoName, item, docsText, repoNote }) {
294
259
  // answer, and a model that does not know a tool was missing will invent
295
260
  // confidence it has not earned.
296
261
  const ANALYSIS_SYSTEM = [
297
- 'You are a senior engineer walking the owner of a codebase through a static-analysis report.',
298
- 'Be concrete and calm. Name real files, rules and line numbers in backticks.',
299
- 'Prioritize: what must be fixed now, what can wait, and what is noise. Say plainly when a finding looks like a false positive and why.',
300
- 'Never invent a finding that is not in the list you were given. If the list is empty, say so — and say what that does and does not prove.',
301
- 'If some engines did not run or are not installed, say what that leaves unchecked.',
302
- 'Keep it under 220 words unless the question genuinely needs more.',
262
+ 'You are a senior engineer walking the owner of a codebase through a static-analysis report.',
263
+ 'Be concrete and calm. Name real files, rules and line numbers in backticks.',
264
+ 'Prioritize: what must be fixed now, what can wait, and what is noise. Say plainly when a finding looks like a false positive and why.',
265
+ 'Never invent a finding that is not in the list you were given. If the list is empty, say so — and say what that does and does not prove.',
266
+ 'If some engines did not run or are not installed, say what that leaves unchecked.',
267
+ 'Keep it under 220 words unless the question genuinely needs more.',
303
268
  ].join(' ');
304
-
305
269
  export function analysisMessages({ repoName, grade, score, counts, engines, findings, question }) {
306
- const engineLines = (engines || []).map((e) => {
307
- if (e.ran) return `- ${e.label}: ran, ${e.findings} finding(s) in ${e.ms}ms`;
308
- if (e.failed) return `- ${e.label}: ran but failed — ${e.failure || 'no reason given'}`;
309
- if (e.available) return `- ${e.label}: installed but not run`;
310
- return `- ${e.label}: NOT INSTALLED (${e.reason || 'unknown'})`;
311
- });
312
-
313
- const findingLines = (findings || []).slice(0, 40).map(
314
- (f) => `- [${f.severity}] ${f.path}:${f.line} — ${f.message} (${f.tool} · ${f.rule})`,
315
- );
316
-
317
- const user = [
318
- `Repository: ${repoName}`,
319
- grade ? `Built-in security grade: ${grade} (${score}/100)` : '',
320
- counts
321
- ? `Findings: ${counts.total} total — ${counts.critical} critical, ${counts.high} high, ${counts.medium} medium, ${counts.low} low. ${counts.external} came from external engines, ${counts.builtin} from the built-in scanner.`
322
- : '',
323
- engineLines.length ? `Engines:\n${engineLines.join('\n')}` : '',
324
- findingLines.length
325
- ? `Findings, worst first:\n${findingLines.join('\n')}`
326
- : 'No findings were reported by anything.',
327
- question
328
- ? `Question: ${question}`
329
- : 'Explain this report: what matters most, what to fix first, and what the engines could not see.',
330
- ].filter(Boolean).join('\n\n');
331
-
332
- return [
333
- { role: 'system', content: ANALYSIS_SYSTEM },
334
- { role: 'user', content: user },
335
- ];
270
+ const engineLines = (engines || []).map((e) => {
271
+ if (e.ran)
272
+ return `- ${e.label}: ran, ${e.findings} finding(s) in ${e.ms}ms`;
273
+ if (e.failed)
274
+ return `- ${e.label}: ran but failed — ${e.failure || 'no reason given'}`;
275
+ if (e.available)
276
+ return `- ${e.label}: installed but not run`;
277
+ return `- ${e.label}: NOT INSTALLED (${e.reason || 'unknown'})`;
278
+ });
279
+ const findingLines = (findings || []).slice(0, 40).map((f) => `- [${f.severity}] ${f.path}:${f.line} — ${f.message} (${f.tool} · ${f.rule})`);
280
+ const user = [
281
+ `Repository: ${repoName}`,
282
+ grade ? `Built-in security grade: ${grade} (${score}/100)` : '',
283
+ counts
284
+ ? `Findings: ${counts.total} total — ${counts.critical} critical, ${counts.high} high, ${counts.medium} medium, ${counts.low} low. ${counts.external} came from external engines, ${counts.builtin} from the built-in scanner.`
285
+ : '',
286
+ engineLines.length ? `Engines:\n${engineLines.join('\n')}` : '',
287
+ findingLines.length
288
+ ? `Findings, worst first:\n${findingLines.join('\n')}`
289
+ : 'No findings were reported by anything.',
290
+ question
291
+ ? `Question: ${question}`
292
+ : 'Explain this report: what matters most, what to fix first, and what the engines could not see.',
293
+ ].filter(Boolean).join('\n\n');
294
+ return [
295
+ { role: 'system', content: ANALYSIS_SYSTEM },
296
+ { role: 'user', content: user },
297
+ ];
336
298
  }
337
-
338
299
  export async function streamTokens(container, text) {
339
- container.innerHTML = '';
340
- for (let i = 0; i < text.length; i++) {
341
- container.innerHTML += text[i];
342
- await new Promise(r => setTimeout(r, 10));
343
- }
300
+ container.innerHTML = '';
301
+ for (let i = 0; i < text.length; i++) {
302
+ container.innerHTML += text[i];
303
+ await new Promise(r => setTimeout(r, 10));
304
+ }
344
305
  }
345
-
306
+ //# sourceMappingURL=llm.js.map