codebase-onboarder 0.6.0 → 1.0.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 (526) hide show
  1. package/README.md +284 -53
  2. package/bin/build-if-source.js +23 -0
  3. package/bin/onboarder.js +0 -0
  4. package/cli/agent/command.d.ts +71 -0
  5. package/cli/agent/command.js +177 -0
  6. package/cli/agent/command.js.map +1 -0
  7. package/cli/agent/config.d.ts +31 -0
  8. package/cli/agent/config.js +98 -0
  9. package/cli/agent/config.js.map +1 -0
  10. package/cli/agent/contracts.d.ts +77 -0
  11. package/cli/agent/contracts.js +2 -0
  12. package/cli/agent/contracts.js.map +1 -0
  13. package/cli/agent/files.d.ts +19 -0
  14. package/cli/agent/files.js +109 -0
  15. package/cli/agent/files.js.map +1 -0
  16. package/cli/agent/gitSource.d.ts +18 -0
  17. package/cli/agent/gitSource.js +69 -0
  18. package/cli/agent/gitSource.js.map +1 -0
  19. package/cli/agent/github.d.ts +21 -0
  20. package/cli/agent/github.js +94 -0
  21. package/cli/agent/github.js.map +1 -0
  22. package/cli/agent/mcp.d.ts +15 -0
  23. package/cli/agent/mcp.js +78 -0
  24. package/cli/agent/mcp.js.map +1 -0
  25. package/cli/agent/process.d.ts +18 -0
  26. package/cli/agent/process.js +118 -0
  27. package/cli/agent/process.js.map +1 -0
  28. package/cli/agent/protocol.d.ts +3 -0
  29. package/cli/agent/protocol.js +26 -0
  30. package/cli/agent/protocol.js.map +1 -0
  31. package/cli/agent/runner.d.ts +34 -0
  32. package/cli/agent/runner.js +152 -0
  33. package/cli/agent/runner.js.map +1 -0
  34. package/cli/agent/stdio.d.ts +1 -0
  35. package/cli/agent/stdio.js +62 -0
  36. package/cli/agent/stdio.js.map +1 -0
  37. package/cli/agent/tools.d.ts +7 -0
  38. package/cli/agent/tools.js +201 -0
  39. package/cli/agent/tools.js.map +1 -0
  40. package/cli/chat/app.d.ts +16 -0
  41. package/cli/chat/app.js +345 -0
  42. package/cli/chat/app.js.map +1 -0
  43. package/cli/chat/commands.d.ts +11 -0
  44. package/cli/chat/commands.js +120 -0
  45. package/cli/chat/commands.js.map +1 -0
  46. package/cli/chat/composer.d.ts +75 -0
  47. package/cli/chat/composer.js +467 -0
  48. package/cli/chat/composer.js.map +1 -0
  49. package/cli/chat/controller.d.ts +60 -0
  50. package/cli/chat/controller.js +393 -0
  51. package/cli/chat/controller.js.map +1 -0
  52. package/cli/chat/logo.d.ts +3 -0
  53. package/cli/chat/logo.js +14 -0
  54. package/cli/chat/logo.js.map +1 -0
  55. package/cli/chat/models.d.ts +18 -0
  56. package/cli/chat/models.js +88 -0
  57. package/cli/chat/models.js.map +1 -0
  58. package/cli/chat/profile.d.ts +5 -0
  59. package/cli/chat/profile.js +98 -0
  60. package/cli/chat/profile.js.map +1 -0
  61. package/cli/chat/render.d.ts +40 -0
  62. package/cli/chat/render.js +259 -0
  63. package/cli/chat/render.js.map +1 -0
  64. package/cli/chat/screen.d.ts +26 -0
  65. package/cli/chat/screen.js +117 -0
  66. package/cli/chat/screen.js.map +1 -0
  67. package/cli/chat/source.d.ts +29 -0
  68. package/cli/chat/source.js +116 -0
  69. package/cli/chat/source.js.map +1 -0
  70. package/cli/chat/store.d.ts +43 -0
  71. package/cli/chat/store.js +94 -0
  72. package/cli/chat/store.js.map +1 -0
  73. package/cli/chat/text.d.ts +4 -0
  74. package/cli/chat/text.js +27 -0
  75. package/cli/chat/text.js.map +1 -0
  76. package/cli/commands.d.ts +26 -0
  77. package/cli/commands.js +836 -811
  78. package/cli/commands.js.map +1 -0
  79. package/cli/explorer/advanced.d.ts +14 -0
  80. package/cli/explorer/advanced.js +321 -329
  81. package/cli/explorer/advanced.js.map +1 -0
  82. package/cli/explorer/app.d.ts +2 -0
  83. package/cli/explorer/app.js +404 -314
  84. package/cli/explorer/app.js.map +1 -0
  85. package/cli/explorer/assistant.d.ts +9 -0
  86. package/cli/explorer/assistant.js +58 -0
  87. package/cli/explorer/assistant.js.map +1 -0
  88. package/cli/explorer/commands.d.ts +17 -0
  89. package/cli/explorer/commands.js +373 -302
  90. package/cli/explorer/commands.js.map +1 -0
  91. package/cli/explorer/featureViews.d.ts +124 -0
  92. package/cli/explorer/featureViews.js +179 -0
  93. package/cli/explorer/featureViews.js.map +1 -0
  94. package/cli/explorer/github.d.ts +21 -0
  95. package/cli/explorer/github.js +42 -44
  96. package/cli/explorer/github.js.map +1 -0
  97. package/cli/explorer/graphs.d.ts +7 -0
  98. package/cli/explorer/graphs.js +90 -95
  99. package/cli/explorer/graphs.js.map +1 -0
  100. package/cli/explorer/picker.d.ts +22 -0
  101. package/cli/explorer/picker.js +150 -0
  102. package/cli/explorer/picker.js.map +1 -0
  103. package/cli/explorer/report.d.ts +85 -0
  104. package/cli/explorer/report.js +60 -0
  105. package/cli/explorer/report.js.map +1 -0
  106. package/cli/explorer/session.d.ts +449 -0
  107. package/cli/explorer/session.js +143 -144
  108. package/cli/explorer/session.js.map +1 -0
  109. package/cli/explorer/views.d.ts +19 -0
  110. package/cli/explorer/views.js +465 -482
  111. package/cli/explorer/views.js.map +1 -0
  112. package/cli/explorer/wrap.d.ts +1 -0
  113. package/cli/explorer/wrap.js +28 -44
  114. package/cli/explorer/wrap.js.map +1 -0
  115. package/cli/main.d.ts +1 -0
  116. package/cli/main.js +251 -164
  117. package/cli/main.js.map +1 -0
  118. package/cli/prompt.d.ts +5 -0
  119. package/cli/prompt.js +84 -80
  120. package/cli/prompt.js.map +1 -0
  121. package/cli/scanOptions.d.ts +2 -0
  122. package/cli/scanOptions.js +11 -0
  123. package/cli/scanOptions.js.map +1 -0
  124. package/cli/ui.d.ts +33 -0
  125. package/cli/ui.js +35 -44
  126. package/cli/ui.js.map +1 -0
  127. package/cli/wizard.d.ts +187 -0
  128. package/cli/wizard.js +304 -284
  129. package/cli/wizard.js.map +1 -0
  130. package/docs/HERMES_RESEARCH.md +51 -0
  131. package/package.json +16 -4
  132. package/public/app.d.ts +1 -0
  133. package/public/app.js +1133 -1011
  134. package/public/app.js.map +1 -0
  135. package/public/assets/onboarder-mark.svg +11 -0
  136. package/public/browser.d.ts +71 -0
  137. package/public/browser.js +2 -0
  138. package/public/browser.js.map +1 -0
  139. package/public/index.html +54 -20
  140. package/public/js/about.d.ts +6 -0
  141. package/public/js/about.js +152 -172
  142. package/public/js/about.js.map +1 -0
  143. package/public/js/aiDraft.d.ts +4 -0
  144. package/public/js/aiDraft.js +166 -125
  145. package/public/js/aiDraft.js.map +1 -0
  146. package/public/js/analysisPanel.d.ts +7 -0
  147. package/public/js/analysisPanel.js +166 -166
  148. package/public/js/analysisPanel.js.map +1 -0
  149. package/public/js/analysisReport.d.ts +38 -0
  150. package/public/js/analysisReport.js +105 -110
  151. package/public/js/analysisReport.js.map +1 -0
  152. package/public/js/api.d.ts +29 -0
  153. package/public/js/api.js +198 -166
  154. package/public/js/api.js.map +1 -0
  155. package/public/js/atlas.d.ts +6 -0
  156. package/public/js/atlas.js +50 -58
  157. package/public/js/atlas.js.map +1 -0
  158. package/public/js/blameView.d.ts +2 -0
  159. package/public/js/blameView.js +36 -37
  160. package/public/js/blameView.js.map +1 -0
  161. package/public/js/codeTab.d.ts +3 -0
  162. package/public/js/codeTab.js +175 -180
  163. package/public/js/codeTab.js.map +1 -0
  164. package/public/js/codeViewer.d.ts +5 -0
  165. package/public/js/codeViewer.js +162 -150
  166. package/public/js/codeViewer.js.map +1 -0
  167. package/public/js/components/FileChip.d.ts +9 -0
  168. package/public/js/components/FileChip.js +45 -49
  169. package/public/js/components/FileChip.js.map +1 -0
  170. package/public/js/components/MetricSparkline.d.ts +7 -0
  171. package/public/js/components/MetricSparkline.js +35 -44
  172. package/public/js/components/MetricSparkline.js.map +1 -0
  173. package/public/js/components/RiskBadge.d.ts +9 -0
  174. package/public/js/components/RiskBadge.js +55 -63
  175. package/public/js/components/RiskBadge.js.map +1 -0
  176. package/public/js/deepAnalysisView.d.ts +99 -0
  177. package/public/js/deepAnalysisView.js +282 -302
  178. package/public/js/deepAnalysisView.js.map +1 -0
  179. package/public/js/diagramPane.d.ts +9 -0
  180. package/public/js/diagramPane.js +138 -135
  181. package/public/js/diagramPane.js.map +1 -0
  182. package/public/js/diffView.d.ts +6 -0
  183. package/public/js/diffView.js +222 -209
  184. package/public/js/diffView.js.map +1 -0
  185. package/public/js/docsView.d.ts +2 -0
  186. package/public/js/docsView.js +441 -442
  187. package/public/js/docsView.js.map +1 -0
  188. package/public/js/dom.d.ts +197 -0
  189. package/public/js/dom.js +5 -0
  190. package/public/js/dom.js.map +1 -0
  191. package/public/js/fileSourceBrowser.d.ts +5 -0
  192. package/public/js/fileSourceBrowser.js +33 -41
  193. package/public/js/fileSourceBrowser.js.map +1 -0
  194. package/public/js/flameGraph.d.ts +5 -0
  195. package/public/js/flameGraph.js +62 -72
  196. package/public/js/flameGraph.js.map +1 -0
  197. package/public/js/forceGraph.d.ts +10 -0
  198. package/public/js/forceGraph.js +581 -556
  199. package/public/js/forceGraph.js.map +1 -0
  200. package/public/js/heatmap.d.ts +4 -0
  201. package/public/js/heatmap.js +142 -164
  202. package/public/js/heatmap.js.map +1 -0
  203. package/public/js/highlight.d.ts +2 -0
  204. package/public/js/highlight.js +116 -107
  205. package/public/js/highlight.js.map +1 -0
  206. package/public/js/html.d.ts +2 -0
  207. package/public/js/html.js +14 -44
  208. package/public/js/html.js.map +1 -0
  209. package/public/js/insightsView.d.ts +5 -0
  210. package/public/js/insightsView.js +93 -111
  211. package/public/js/insightsView.js.map +1 -0
  212. package/public/js/inspector.d.ts +37 -0
  213. package/public/js/inspector.js +416 -445
  214. package/public/js/inspector.js.map +1 -0
  215. package/public/js/llm.d.ts +115 -0
  216. package/public/js/llm.js +246 -278
  217. package/public/js/llm.js.map +1 -0
  218. package/public/js/mapView.d.ts +3 -0
  219. package/public/js/mapView.js +121 -120
  220. package/public/js/mapView.js.map +1 -0
  221. package/public/js/markdown.d.ts +3 -0
  222. package/public/js/markdown.js +84 -91
  223. package/public/js/markdown.js.map +1 -0
  224. package/public/js/mindmap.d.ts +32 -0
  225. package/public/js/mindmap.js +244 -259
  226. package/public/js/mindmap.js.map +1 -0
  227. package/public/js/mobilePanels.d.ts +5 -0
  228. package/public/js/mobilePanels.js +50 -0
  229. package/public/js/mobilePanels.js.map +1 -0
  230. package/public/js/repoFiles.d.ts +12 -0
  231. package/public/js/repoFiles.js +29 -28
  232. package/public/js/repoFiles.js.map +1 -0
  233. package/public/js/reviewView.d.ts +28 -0
  234. package/public/js/reviewView.js +256 -0
  235. package/public/js/reviewView.js.map +1 -0
  236. package/public/js/sbomView.d.ts +3 -0
  237. package/public/js/sbomView.js +59 -67
  238. package/public/js/sbomView.js.map +1 -0
  239. package/public/js/scanCache.d.ts +16 -0
  240. package/public/js/scanCache.js +67 -65
  241. package/public/js/scanCache.js.map +1 -0
  242. package/public/js/search.d.ts +7 -0
  243. package/public/js/search.js +868 -800
  244. package/public/js/search.js.map +1 -0
  245. package/public/js/searchLocal.d.ts +42 -0
  246. package/public/js/searchLocal.js +87 -0
  247. package/public/js/searchLocal.js.map +1 -0
  248. package/public/js/serverSettings.d.ts +5 -0
  249. package/public/js/serverSettings.js +153 -164
  250. package/public/js/serverSettings.js.map +1 -0
  251. package/public/js/state.d.ts +798 -0
  252. package/public/js/state.js +114 -122
  253. package/public/js/state.js.map +1 -0
  254. package/public/js/tour.d.ts +6 -0
  255. package/public/js/tour.js +5 -7
  256. package/public/js/tour.js.map +1 -0
  257. package/public/js/transitions.d.ts +2 -0
  258. package/public/js/transitions.js +9 -10
  259. package/public/js/transitions.js.map +1 -0
  260. package/public/js/tree.d.ts +12 -0
  261. package/public/js/tree.js +157 -154
  262. package/public/js/tree.js.map +1 -0
  263. package/public/js/workflowsView.d.ts +3 -0
  264. package/public/js/workflowsView.js +15 -22
  265. package/public/js/workflowsView.js.map +1 -0
  266. package/public/search.css +495 -0
  267. package/public/styles.css +188 -346
  268. package/public/workbench.css +166 -0
  269. package/server/apiAuth.d.ts +3 -0
  270. package/server/apiAuth.js +18 -20
  271. package/server/apiAuth.js.map +1 -0
  272. package/server/apiDiff.d.ts +2 -0
  273. package/server/apiDiff.js +20 -18
  274. package/server/apiDiff.js.map +1 -0
  275. package/server/apiDocs.d.ts +2 -0
  276. package/server/apiDocs.js +38 -40
  277. package/server/apiDocs.js.map +1 -0
  278. package/server/apiFile.d.ts +1 -0
  279. package/server/apiFile.js +14 -17
  280. package/server/apiFile.js.map +1 -0
  281. package/server/apiGitBlame.d.ts +2 -0
  282. package/server/apiGitBlame.js +50 -51
  283. package/server/apiGitBlame.js.map +1 -0
  284. package/server/apiMcp.d.ts +4 -0
  285. package/server/apiMcp.js +64 -66
  286. package/server/apiMcp.js.map +1 -0
  287. package/server/apiReview.d.ts +2 -0
  288. package/server/apiReview.js +45 -0
  289. package/server/apiReview.js.map +1 -0
  290. package/server/apiScan.d.ts +5 -0
  291. package/server/apiScan.js +90 -71
  292. package/server/apiScan.js.map +1 -0
  293. package/server/apiSearch.d.ts +33 -0
  294. package/server/apiSearch.js +184 -200
  295. package/server/apiSearch.js.map +1 -0
  296. package/server/apiSettings.d.ts +4 -0
  297. package/server/apiSettings.js +84 -85
  298. package/server/apiSettings.js.map +1 -0
  299. package/server/apiTools.d.ts +3 -0
  300. package/server/apiTools.js +55 -56
  301. package/server/apiTools.js.map +1 -0
  302. package/server/auth.d.ts +5 -0
  303. package/server/auth.js +54 -51
  304. package/server/auth.js.map +1 -0
  305. package/server/config.d.ts +42 -0
  306. package/server/config.js +189 -194
  307. package/server/config.js.map +1 -0
  308. package/server/daemon.d.ts +12 -0
  309. package/server/daemon.js +124 -114
  310. package/server/daemon.js.map +1 -0
  311. package/server/fileSourceNode.d.ts +2 -0
  312. package/server/fileSourceNode.js +34 -36
  313. package/server/fileSourceNode.js.map +1 -0
  314. package/server/gitClone.d.ts +9 -0
  315. package/server/gitClone.js +59 -61
  316. package/server/gitClone.js.map +1 -0
  317. package/server/gitDiff.d.ts +36 -0
  318. package/server/gitDiff.js +271 -169
  319. package/server/gitDiff.js.map +1 -0
  320. package/server/gitHistory.d.ts +12 -0
  321. package/server/gitHistory.js +80 -80
  322. package/server/gitHistory.js.map +1 -0
  323. package/server/gitRemote.d.ts +12 -0
  324. package/server/gitRemote.js +37 -38
  325. package/server/gitRemote.js.map +1 -0
  326. package/server/hermesChat.d.ts +13 -0
  327. package/server/hermesChat.js +145 -0
  328. package/server/hermesChat.js.map +1 -0
  329. package/server/htmlText.d.ts +4 -0
  330. package/server/htmlText.js +16 -23
  331. package/server/htmlText.js.map +1 -0
  332. package/server/http.d.ts +6 -0
  333. package/server/http.js +27 -34
  334. package/server/http.js.map +1 -0
  335. package/server/httpGuards.d.ts +2 -0
  336. package/server/httpGuards.js +47 -43
  337. package/server/httpGuards.js.map +1 -0
  338. package/server/https.d.ts +34 -0
  339. package/server/https.js +121 -111
  340. package/server/https.js.map +1 -0
  341. package/server/index.d.ts +40 -0
  342. package/server/index.js +139 -147
  343. package/server/index.js.map +1 -0
  344. package/server/layout.d.ts +26 -0
  345. package/server/layout.js +59 -64
  346. package/server/layout.js.map +1 -0
  347. package/server/llmProxy.d.ts +3 -0
  348. package/server/llmProxy.js +137 -135
  349. package/server/llmProxy.js.map +1 -0
  350. package/server/logger.d.ts +38 -0
  351. package/server/logger.js +198 -211
  352. package/server/logger.js.map +1 -0
  353. package/server/mcp/analysis.d.ts +29 -0
  354. package/server/mcp/analysis.js +99 -120
  355. package/server/mcp/analysis.js.map +1 -0
  356. package/server/mcp/http.d.ts +9 -0
  357. package/server/mcp/http.js +128 -137
  358. package/server/mcp/http.js.map +1 -0
  359. package/server/mcp/runner.d.ts +68 -0
  360. package/server/mcp/runner.js +208 -218
  361. package/server/mcp/runner.js.map +1 -0
  362. package/server/mcp/server.d.ts +29 -0
  363. package/server/mcp/server.js +167 -180
  364. package/server/mcp/server.js.map +1 -0
  365. package/server/mcp/standalone.d.ts +1 -0
  366. package/server/mcp/standalone.js +8 -10
  367. package/server/mcp/standalone.js.map +1 -0
  368. package/server/mcp/tools.d.ts +2020 -0
  369. package/server/mcp/tools.js +523 -574
  370. package/server/mcp/tools.js.map +1 -0
  371. package/server/paths.d.ts +3 -0
  372. package/server/paths.js +17 -15
  373. package/server/paths.js.map +1 -0
  374. package/server/pidfile.d.ts +9 -0
  375. package/server/pidfile.js +43 -45
  376. package/server/pidfile.js.map +1 -0
  377. package/server/review.d.ts +5 -0
  378. package/server/review.js +35 -0
  379. package/server/review.js.map +1 -0
  380. package/server/router.d.ts +33 -0
  381. package/server/router.js +195 -197
  382. package/server/router.js.map +1 -0
  383. package/server/scanRequest.d.ts +3 -0
  384. package/server/scanRequest.js +36 -0
  385. package/server/scanRequest.js.map +1 -0
  386. package/server/searchIndex.d.ts +17 -0
  387. package/server/searchIndex.js +83 -80
  388. package/server/searchIndex.js.map +1 -0
  389. package/server/sessions.d.ts +14 -0
  390. package/server/sessions.js +62 -70
  391. package/server/sessions.js.map +1 -0
  392. package/server/startup.d.ts +118 -0
  393. package/server/startup.js +143 -148
  394. package/server/startup.js.map +1 -0
  395. package/server/static.d.ts +6 -0
  396. package/server/static.js +28 -31
  397. package/server/static.js.map +1 -0
  398. package/server/tools/install.d.ts +4 -0
  399. package/server/tools/install.js +176 -185
  400. package/server/tools/install.js.map +1 -0
  401. package/server/tools/parse.d.ts +8 -0
  402. package/server/tools/parse.js +112 -114
  403. package/server/tools/parse.js.map +1 -0
  404. package/server/tools/platform.d.ts +9 -0
  405. package/server/tools/platform.js +49 -47
  406. package/server/tools/platform.js.map +1 -0
  407. package/server/tools/registry.d.ts +137 -0
  408. package/server/tools/registry.js +173 -172
  409. package/server/tools/registry.js.map +1 -0
  410. package/server/tools/scan.d.ts +34 -0
  411. package/server/tools/scan.js +89 -98
  412. package/server/tools/scan.js.map +1 -0
  413. package/server/tools.d.ts +34 -0
  414. package/server/tools.js +94 -107
  415. package/server/tools.js.map +1 -0
  416. package/server/tunnel.d.ts +29 -0
  417. package/server/tunnel.js +61 -66
  418. package/server/tunnel.js.map +1 -0
  419. package/shared/analyzer/docs.d.ts +16 -0
  420. package/shared/analyzer/docs.js +99 -93
  421. package/shared/analyzer/docs.js.map +1 -0
  422. package/shared/analyzer/explainLocal.d.ts +4 -0
  423. package/shared/analyzer/explainLocal.js +122 -142
  424. package/shared/analyzer/explainLocal.js.map +1 -0
  425. package/shared/analyzer/github.d.ts +37 -0
  426. package/shared/analyzer/github.js +41 -43
  427. package/shared/analyzer/github.js.map +1 -0
  428. package/shared/analyzer/graph.d.ts +41 -0
  429. package/shared/analyzer/graph.js +393 -400
  430. package/shared/analyzer/graph.js.map +1 -0
  431. package/shared/analyzer/health.d.ts +33 -0
  432. package/shared/analyzer/health.js +197 -193
  433. package/shared/analyzer/health.js.map +1 -0
  434. package/shared/analyzer/history.d.ts +29 -0
  435. package/shared/analyzer/history.js +110 -111
  436. package/shared/analyzer/history.js.map +1 -0
  437. package/shared/analyzer/jsonConfig.d.ts +2 -0
  438. package/shared/analyzer/jsonConfig.js +61 -0
  439. package/shared/analyzer/jsonConfig.js.map +1 -0
  440. package/shared/analyzer/languages/csharp.d.ts +26 -0
  441. package/shared/analyzer/languages/csharp.js +83 -88
  442. package/shared/analyzer/languages/csharp.js.map +1 -0
  443. package/shared/analyzer/languages/generic.d.ts +23 -0
  444. package/shared/analyzer/languages/generic.js +94 -105
  445. package/shared/analyzer/languages/generic.js.map +1 -0
  446. package/shared/analyzer/languages/go.d.ts +24 -0
  447. package/shared/analyzer/languages/go.js +45 -54
  448. package/shared/analyzer/languages/go.js.map +1 -0
  449. package/shared/analyzer/languages/index.d.ts +6 -0
  450. package/shared/analyzer/languages/index.js +19 -20
  451. package/shared/analyzer/languages/index.js.map +1 -0
  452. package/shared/analyzer/languages/java.d.ts +20 -0
  453. package/shared/analyzer/languages/java.js +73 -78
  454. package/shared/analyzer/languages/java.js.map +1 -0
  455. package/shared/analyzer/languages/javascript.d.ts +12 -0
  456. package/shared/analyzer/languages/javascript.js +258 -209
  457. package/shared/analyzer/languages/javascript.js.map +1 -0
  458. package/shared/analyzer/languages/python.d.ts +23 -0
  459. package/shared/analyzer/languages/python.js +92 -100
  460. package/shared/analyzer/languages/python.js.map +1 -0
  461. package/shared/analyzer/languages/rust.d.ts +17 -0
  462. package/shared/analyzer/languages/rust.js +96 -98
  463. package/shared/analyzer/languages/rust.js.map +1 -0
  464. package/shared/analyzer/languages/typescript.d.ts +11 -0
  465. package/shared/analyzer/languages/typescript.js +117 -116
  466. package/shared/analyzer/languages/typescript.js.map +1 -0
  467. package/shared/analyzer/licenses.d.ts +18 -0
  468. package/shared/analyzer/licenses.js +130 -133
  469. package/shared/analyzer/licenses.js.map +1 -0
  470. package/shared/analyzer/metrics.d.ts +20 -0
  471. package/shared/analyzer/metrics.js +112 -104
  472. package/shared/analyzer/metrics.js.map +1 -0
  473. package/shared/analyzer/pathUtil.d.ts +10 -0
  474. package/shared/analyzer/pathUtil.js +29 -35
  475. package/shared/analyzer/pathUtil.js.map +1 -0
  476. package/shared/analyzer/patterns.d.ts +11 -0
  477. package/shared/analyzer/patterns.js +231 -253
  478. package/shared/analyzer/patterns.js.map +1 -0
  479. package/shared/analyzer/scan.d.ts +62 -0
  480. package/shared/analyzer/scan.js +451 -442
  481. package/shared/analyzer/scan.js.map +1 -0
  482. package/shared/analyzer/scanControl.d.ts +11 -0
  483. package/shared/analyzer/scanControl.js +62 -0
  484. package/shared/analyzer/scanControl.js.map +1 -0
  485. package/shared/analyzer/security.d.ts +18 -0
  486. package/shared/analyzer/security.js +159 -159
  487. package/shared/analyzer/security.js.map +1 -0
  488. package/shared/analyzer/services.d.ts +5 -0
  489. package/shared/analyzer/services.js +141 -138
  490. package/shared/analyzer/services.js.map +1 -0
  491. package/shared/analyzer/stack.d.ts +6 -0
  492. package/shared/analyzer/stack.js +134 -141
  493. package/shared/analyzer/stack.js.map +1 -0
  494. package/shared/analyzer/tour.d.ts +2 -0
  495. package/shared/analyzer/tour.js +45 -53
  496. package/shared/analyzer/tour.js.map +1 -0
  497. package/shared/analyzer/util.d.ts +8 -0
  498. package/shared/analyzer/util.js +130 -76
  499. package/shared/analyzer/util.js.map +1 -0
  500. package/shared/analyzer/workflows.d.ts +8 -0
  501. package/shared/analyzer/workflows.js +139 -134
  502. package/shared/analyzer/workflows.js.map +1 -0
  503. package/shared/contracts.d.ts +250 -0
  504. package/shared/contracts.js +2 -0
  505. package/shared/contracts.js.map +1 -0
  506. package/shared/diagram/aiFacts.d.ts +35 -0
  507. package/shared/diagram/aiFacts.js +102 -105
  508. package/shared/diagram/aiFacts.js.map +1 -0
  509. package/shared/diagram/aiMermaid.d.ts +5 -0
  510. package/shared/diagram/aiMermaid.js +50 -46
  511. package/shared/diagram/aiMermaid.js.map +1 -0
  512. package/shared/diagram/atlas.d.ts +16 -0
  513. package/shared/diagram/atlas.js +51 -60
  514. package/shared/diagram/atlas.js.map +1 -0
  515. package/shared/diagram/mermaid.d.ts +43 -0
  516. package/shared/diagram/mermaid.js +348 -370
  517. package/shared/diagram/mermaid.js.map +1 -0
  518. package/shared/review/contracts.d.ts +95 -0
  519. package/shared/review/contracts.js +2 -0
  520. package/shared/review/contracts.js.map +1 -0
  521. package/shared/review/review.d.ts +10 -0
  522. package/shared/review/review.js +184 -0
  523. package/shared/review/review.js.map +1 -0
  524. package/shared/search/query.d.ts +32 -0
  525. package/shared/search/query.js +395 -388
  526. package/shared/search/query.js.map +1 -0
@@ -1,41 +1,40 @@
1
1
  export function initBlameView(container) {
2
- return function renderBlame(blameData, options = {}) {
3
- if (!blameData || !blameData.lines) {
4
- container.hidden = true;
5
- return;
6
- }
7
- container.hidden = false;
8
- container.innerHTML = '';
9
-
10
- // Hash author to color
11
- function getAuthorColor(author) {
12
- let hash = 0;
13
- for (let i = 0; i < author.length; i++) hash = author.charCodeAt(i) + ((hash << 5) - hash);
14
- return `hsl(${Math.abs(hash) % 360}, 60%, 50%)`;
15
- }
16
-
17
- blameData.lines.forEach(line => {
18
- const div = document.createElement('div');
19
- div.className = 'blame-line';
20
- div.style.backgroundColor = getAuthorColor(line.author || 'Unknown');
21
-
22
- const tooltip = document.createElement('div');
23
- tooltip.className = 'blame-tooltip';
24
- tooltip.textContent = `${line.author} - ${line.date || ''} (${(line.sha || '').substring(0, 7)})`;
25
-
26
- div.appendChild(tooltip);
27
- container.appendChild(div);
28
- });
29
- };
2
+ return function renderBlame(blameData, options = {}) {
3
+ if (!blameData || !blameData.lines) {
4
+ container.hidden = true;
5
+ return;
6
+ }
7
+ container.hidden = false;
8
+ container.innerHTML = '';
9
+ // Hash author to color
10
+ function getAuthorColor(author) {
11
+ let hash = 0;
12
+ for (let i = 0; i < author.length; i++)
13
+ hash = author.charCodeAt(i) + ((hash << 5) - hash);
14
+ return `hsl(${Math.abs(hash) % 360}, 60%, 50%)`;
15
+ }
16
+ blameData.lines.forEach(line => {
17
+ const div = document.createElement('div');
18
+ div.className = 'blame-line';
19
+ div.style.backgroundColor = getAuthorColor(line.author || 'Unknown');
20
+ const tooltip = document.createElement('div');
21
+ tooltip.className = 'blame-tooltip';
22
+ tooltip.textContent = `${line.author} - ${line.date || ''} (${(line.sha || '').substring(0, 7)})`;
23
+ div.appendChild(tooltip);
24
+ container.appendChild(div);
25
+ });
26
+ };
30
27
  }
31
-
32
28
  export async function fetchBlame(scanId, path) {
33
- try {
34
- const res = await fetch(`/api/blame?scan=${encodeURIComponent(scanId)}&path=${encodeURIComponent(path)}`);
35
- if (!res.ok) return null;
36
- return await res.json();
37
- } catch (err) {
38
- console.error('Failed to fetch blame:', err);
39
- return null;
40
- }
29
+ try {
30
+ const res = await fetch(`/api/blame?scan=${encodeURIComponent(scanId)}&path=${encodeURIComponent(path)}`);
31
+ if (!res.ok)
32
+ return null;
33
+ return await res.json();
34
+ }
35
+ catch (err) {
36
+ console.error('Failed to fetch blame:', err);
37
+ return null;
38
+ }
41
39
  }
40
+ //# sourceMappingURL=blameView.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blameView.js","sourceRoot":"","sources":["../../src/public/js/blameView.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,aAAa,CAAC,SAAS;IACrC,OAAO,SAAS,WAAW,CAAC,SAAS,EAAE,OAAO,GAAwB,EAAE;QACtE,IAAI,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;YACnC,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC;YACxB,OAAO;QACT,CAAC;QACD,SAAS,CAAC,MAAM,GAAG,KAAK,CAAC;QACzB,SAAS,CAAC,SAAS,GAAG,EAAE,CAAC;QAEzB,uBAAuB;QACvB,SAAS,cAAc,CAAC,MAAM;YAC5B,IAAI,IAAI,GAAG,CAAC,CAAC;YACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE;gBAAE,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;YAC3F,OAAO,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG,aAAa,CAAC;QAClD,CAAC;QAED,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;YAC7B,MAAM,GAAG,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;YAC1C,GAAG,CAAC,SAAS,GAAG,YAAY,CAAC;YAC7B,GAAG,CAAC,KAAK,CAAC,eAAe,GAAG,cAAc,CAAC,IAAI,CAAC,MAAM,IAAI,SAAS,CAAC,CAAC;YAErE,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;YAC9C,OAAO,CAAC,SAAS,GAAG,eAAe,CAAC;YACpC,OAAO,CAAC,WAAW,GAAG,GAAG,IAAI,CAAC,MAAM,MAAM,IAAI,CAAC,IAAI,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC;YAElG,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;YACzB,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,MAAM,EAAE,IAAI;IAC3C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,mBAAmB,kBAAkB,CAAC,MAAM,CAAC,SAAS,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC1G,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC;QACzB,OAAO,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;IAC1B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,wBAAwB,EAAE,GAAG,CAAC,CAAC;QAC7C,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC","sourcesContent":["export function initBlameView(container) {\n return function renderBlame(blameData, options: Record<string, any> = {}) {\n if (!blameData || !blameData.lines) {\n container.hidden = true;\n return;\n }\n container.hidden = false;\n container.innerHTML = '';\n \n // Hash author to color\n function getAuthorColor(author) {\n let hash = 0;\n for (let i = 0; i < author.length; i++) hash = author.charCodeAt(i) + ((hash << 5) - hash);\n return `hsl(${Math.abs(hash) % 360}, 60%, 50%)`;\n }\n\n blameData.lines.forEach(line => {\n const div = document.createElement('div');\n div.className = 'blame-line';\n div.style.backgroundColor = getAuthorColor(line.author || 'Unknown');\n \n const tooltip = document.createElement('div');\n tooltip.className = 'blame-tooltip';\n tooltip.textContent = `${line.author} - ${line.date || ''} (${(line.sha || '').substring(0, 7)})`;\n \n div.appendChild(tooltip);\n container.appendChild(div);\n });\n };\n}\n\nexport async function fetchBlame(scanId, path) {\n try {\n const res = await fetch(`/api/blame?scan=${encodeURIComponent(scanId)}&path=${encodeURIComponent(path)}`);\n if (!res.ok) return null;\n return await res.json();\n } catch (err) {\n console.error('Failed to fetch blame:', err);\n return null;\n }\n}\n"]}
@@ -0,0 +1,3 @@
1
+ export declare function revealLineInCode(line: any): void;
2
+ export declare function initCodeTab(options: any): void;
3
+ export declare function renderCode(): Promise<void>;
@@ -8,210 +8,205 @@
8
8
  //
9
9
  // The back/forward stack and the "which file should I show" decision live in
10
10
  // state.js, where they are pure and tested. What is left here is DOM.
11
-
12
11
  import { roleOf } from '/shared/analyzer/graph.js';
13
12
  import { escapeHtml } from './html.js';
14
13
  import { highlightCode, langOf } from './highlight.js';
15
14
  import { initViewer, showInViewer, monacoLangOf, revealLineInViewer } from './codeViewer.js';
16
15
  import { fetchBlame, initBlameView } from './blameView.js';
17
- import {
18
- state, focusFile, defaultCodePath, pushCodeHistory, codeHistoryTarget,
19
- } from './state.js';
16
+ import { state, focusFile, defaultCodePath, pushCodeHistory, codeHistoryTarget, } from './state.js';
20
17
  import { readRepoFile } from './repoFiles.js';
21
-
22
18
  const MAX_FALLBACK_LINES = 3000;
23
-
24
19
  let host = null;
25
20
  let renderBlameGutter = null;
26
21
  let hooks = {
27
- onSyncInspector: () => {},
28
- onRenderSidebar: () => {},
29
- onOpenFile: () => {},
30
- onToast: () => {},
31
- getTheme: () => 'light',
32
- blameGutter: null,
22
+ onDeepDive: (_path) => { },
23
+ onSyncInspector: (..._args) => { },
24
+ onRenderSidebar: (..._args) => { },
25
+ onOpenFile: (..._args) => { },
26
+ onToast: (..._args) => { },
27
+ getTheme: () => 'light',
28
+ blameGutter: null,
33
29
  };
34
-
35
- let codeSeq = 0; // render generations — a slow read never overwrites a newer one
30
+ let codeSeq = 0; // render generations — a slow read never overwrites a newer one
36
31
  let viewerFailed = false; // Monaco failed to load → hand-rolled fallback
37
32
  let pendingReveal = null; // a line a search result asked for, waiting for its file
38
-
39
33
  // A search result knows which line it matched. The reveal has to wait until the
40
34
  // text is on screen, and it must not leak onto the *next* file you open — which
41
35
  // is why it is taken once, at the top of `renderCode`, rather than living in
42
36
  // `state` where it would outlive the file it was meant for.
43
37
  export function revealLineInCode(line) {
44
- const target = Math.floor(Number(line));
45
- pendingReveal = Number.isFinite(target) && target > 0 ? target : null;
38
+ const target = Math.floor(Number(line));
39
+ pendingReveal = Number.isFinite(target) && target > 0 ? target : null;
46
40
  }
47
-
48
41
  // Monaco is the real answer; without it, the fallback is a single scrolling
49
42
  // `<pre>`, so the best we can do is put the line near the top. Approximate, and
50
43
  // honest about being approximate — the file is still the right file.
51
44
  function applyReveal(alt, line) {
52
- if (!line) return;
53
- if (!viewerFailed) {
54
- revealLineInViewer(line);
55
- return;
56
- }
57
- const shell = alt.querySelector('.code-shell');
58
- if (!shell) return;
59
- const gutter = shell.querySelector('.code-gutter');
60
- const total = gutter ? (gutter.textContent || '').split('\n').length : 0;
61
- if (!total) return;
62
- const perLine = shell.scrollHeight / total;
63
- shell.scrollTop = Math.max(0, (line - 2) * perLine);
45
+ if (!line)
46
+ return;
47
+ if (!viewerFailed) {
48
+ revealLineInViewer(line);
49
+ return;
50
+ }
51
+ const shell = alt.querySelector('.code-shell');
52
+ if (!shell)
53
+ return;
54
+ const gutter = shell.querySelector('.code-gutter');
55
+ const total = gutter ? (gutter.textContent || '').split('\n').length : 0;
56
+ if (!total)
57
+ return;
58
+ const perLine = shell.scrollHeight / total;
59
+ shell.scrollTop = Math.max(0, (line - 2) * perLine);
64
60
  }
65
-
66
61
  export function initCodeTab(options) {
67
- host = options.host;
68
- hooks = { ...hooks, ...options };
69
- if (options.blameGutter) {
70
- renderBlameGutter = initBlameView(options.blameGutter);
71
- }
72
-
73
- host.addEventListener('click', (event) => {
74
- const b = event.target.closest('button');
75
- if (!b) return;
76
- if (b.dataset.codeopen) return openCodeFile(b.dataset.codeopen);
77
- if (b.dataset.codenav) return codeNav(Number(b.dataset.codenav));
78
- if (b.dataset.codedive !== undefined) return (hooks.onDeepDive || hooks.onOpenFile)(state.code.path); // empty attribute is falsy — test undefined
79
- if (b.dataset.codeblame !== undefined) {
80
- if (!hooks.blameGutter) return;
81
- if (!hooks.blameGutter.hidden) {
82
- hooks.blameGutter.hidden = true;
83
- b.classList.remove('is-active');
84
- } else {
85
- hooks.onToast('Fetching git blame...');
86
- fetchBlame(state.scanId, state.code.path).then((data) => {
87
- if (data && data.lines && data.lines.length) {
88
- renderBlameGutter(data);
89
- hooks.blameGutter.hidden = false;
90
- b.classList.add('is-active');
91
- hooks.onToast(`Blame loaded for ${data.lines.length} lines`);
92
- } else {
93
- hooks.onToast(data?.reason || 'No blame available for this file.');
94
- }
95
- });
96
- }
97
- return;
98
- }
99
- if (b.dataset.codecopy !== undefined) {
100
- const text = state.code.cache[state.code.path];
101
- if (text !== undefined) {
102
- navigator.clipboard.writeText(text)
103
- .then(() => hooks.onToast('Copied to the clipboard.'))
104
- .catch(() => hooks.onToast('Could not copy to the clipboard.'));
105
- }
62
+ host = options.host;
63
+ hooks = { ...hooks, ...options };
64
+ if (options.blameGutter) {
65
+ renderBlameGutter = initBlameView(options.blameGutter);
106
66
  }
107
- });
67
+ host.addEventListener('click', (event) => {
68
+ const b = event.target.closest('button');
69
+ if (!b)
70
+ return;
71
+ if (b.dataset.codeopen)
72
+ return openCodeFile(b.dataset.codeopen);
73
+ if (b.dataset.codenav)
74
+ return codeNav(Number(b.dataset.codenav));
75
+ if (b.dataset.codedive !== undefined)
76
+ return (hooks.onDeepDive || hooks.onOpenFile)(state.code.path); // empty attribute is falsy — test undefined
77
+ if (b.dataset.codeblame !== undefined) {
78
+ if (!hooks.blameGutter)
79
+ return;
80
+ if (!hooks.blameGutter.hidden) {
81
+ hooks.blameGutter.hidden = true;
82
+ b.classList.remove('is-active');
83
+ }
84
+ else {
85
+ hooks.onToast('Fetching git blame...');
86
+ fetchBlame(state.scanId, state.code.path).then((data) => {
87
+ if (data && data.lines && data.lines.length) {
88
+ renderBlameGutter(data);
89
+ hooks.blameGutter.hidden = false;
90
+ b.classList.add('is-active');
91
+ hooks.onToast(`Blame loaded for ${data.lines.length} lines`);
92
+ }
93
+ else {
94
+ hooks.onToast(data?.reason || 'No blame available for this file.');
95
+ }
96
+ });
97
+ }
98
+ return;
99
+ }
100
+ if (b.dataset.codecopy !== undefined) {
101
+ const text = state.code.cache[state.code.path];
102
+ if (text !== undefined) {
103
+ navigator.clipboard.writeText(text)
104
+ .then(() => hooks.onToast('Copied to the clipboard.'))
105
+ .catch(() => hooks.onToast('Could not copy to the clipboard.'));
106
+ }
107
+ }
108
+ });
108
109
  }
109
-
110
110
  // In-tab navigation (the import chips) keeps the sidebar and inspector in step,
111
111
  // so the rest of the app follows along rather than pointing at the old file.
112
112
  function openCodeFile(path) {
113
- state.code.path = path;
114
- focusFile(path);
115
- hooks.onSyncInspector();
116
- hooks.onRenderSidebar();
117
- renderCode();
113
+ state.code.path = path;
114
+ focusFile(path);
115
+ hooks.onSyncInspector();
116
+ hooks.onRenderSidebar();
117
+ renderCode();
118
118
  }
119
-
120
119
  function codeNav(delta) {
121
- const path = codeHistoryTarget(delta);
122
- if (path) openCodeFile(path);
120
+ const path = codeHistoryTarget(delta);
121
+ if (path)
122
+ openCodeFile(path);
123
123
  }
124
-
125
124
  export async function renderCode() {
126
- const seq = ++codeSeq;
127
- const path = defaultCodePath();
128
- // Taken once and cleared, so a reveal belongs only to the render that followed
129
- // the request for it — never to the next file you happen to open.
130
- const revealLine = pendingReveal;
131
- pendingReveal = null;
132
- if (!path) {
133
- host.innerHTML = '<div class="code-empty">Nothing to preview — this repo has no readable files.</div>';
134
- return;
135
- }
136
- state.code.path = path;
137
- pushCodeHistory(path);
138
-
139
- // The shell is built once: the Monaco container must persist across file
140
- // switches, or the editor instance would be destroyed on every render.
141
- if (!host.querySelector('.code-page')) {
142
- host.innerHTML = `<div class="code-page">
125
+ const seq = ++codeSeq;
126
+ const path = defaultCodePath();
127
+ // Taken once and cleared, so a reveal belongs only to the render that followed
128
+ // the request for it — never to the next file you happen to open.
129
+ const revealLine = pendingReveal;
130
+ pendingReveal = null;
131
+ if (!path) {
132
+ host.innerHTML = '<div class="code-empty">Nothing to preview — this repo has no readable files.</div>';
133
+ return;
134
+ }
135
+ state.code.path = path;
136
+ pushCodeHistory(path);
137
+ // The shell is built once: the Monaco container must persist across file
138
+ // switches, or the editor instance would be destroyed on every render.
139
+ if (!host.querySelector('.code-page')) {
140
+ host.innerHTML = `<div class="code-page">
143
141
  <div class="code-head" id="codeHead"></div>
144
142
  <div id="codeLinks"></div>
145
143
  <div class="code-monaco" id="codeMonaco" hidden></div>
146
144
  <div id="codeAlt"></div>
147
145
  </div>`;
148
- }
149
- const headEl = host.querySelector('#codeHead');
150
- const linksEl = host.querySelector('#codeLinks');
151
- const monacoEl = host.querySelector('#codeMonaco');
152
- const alt = host.querySelector('#codeAlt');
153
-
154
- let text = state.code.cache[path];
155
- if (text === undefined) {
156
- monacoEl.hidden = true;
157
- alt.innerHTML = '<div class="code-empty">Reading ' + escapeHtml(path) + '…</div>';
158
- try {
159
- text = await readRepoFile(path);
160
- } catch (err) {
161
- if (seq !== codeSeq) return;
162
- alt.innerHTML = '<div class="code-empty">Could not read that file: ' + escapeHtml(err.message) + '</div>';
163
- return;
164
146
  }
165
- if (seq !== codeSeq) return;
166
- state.code.cache[path] = text;
167
- }
168
-
169
- const { facts } = state;
170
- const parsed = facts.fanIn[path] !== undefined;
171
- const name = path.split('/').pop();
172
- const ext = (name.match(/\.([A-Za-z0-9]+)$/) || [, ''])[1].toLowerCase();
173
- const isBinary = text.slice(0, 8000).includes('\0');
174
-
175
- renderHead(headEl, { path, name, ext, text, parsed, isBinary });
176
- linksEl.innerHTML = parsed ? importChips(path) : '';
177
-
178
- if (isBinary) {
179
- monacoEl.hidden = true;
180
- alt.innerHTML = '<div class="code-empty">Binary file — nothing to preview.</div>';
181
- return;
182
- }
183
-
184
- // Monaco first; the hand-rolled highlighter stands by if it can't load.
185
- if (!viewerFailed) {
186
- monacoEl.hidden = false;
187
- const ok = await initViewer(monacoEl, hooks.getTheme());
188
- if (seq !== codeSeq) return;
189
- if (ok) {
190
- alt.innerHTML = '';
191
- showInViewer(text, monacoLangOf(path), hooks.getTheme());
192
- applyReveal(alt, revealLine);
193
- return;
147
+ const headEl = host.querySelector('#codeHead');
148
+ const linksEl = host.querySelector('#codeLinks');
149
+ const monacoEl = host.querySelector('#codeMonaco');
150
+ const alt = host.querySelector('#codeAlt');
151
+ let text = state.code.cache[path];
152
+ if (text === undefined) {
153
+ monacoEl.hidden = true;
154
+ alt.innerHTML = '<div class="code-empty">Reading ' + escapeHtml(path) + '…</div>';
155
+ try {
156
+ text = await readRepoFile(path);
157
+ }
158
+ catch (err) {
159
+ if (seq !== codeSeq)
160
+ return;
161
+ alt.innerHTML = '<div class="code-empty">Could not read that file: ' + escapeHtml(err.message) + '</div>';
162
+ return;
163
+ }
164
+ if (seq !== codeSeq)
165
+ return;
166
+ state.code.cache[path] = text;
167
+ }
168
+ const { facts } = state;
169
+ const parsed = facts.fanIn[path] !== undefined;
170
+ const name = path.split('/').pop();
171
+ const ext = (name.match(/\.([A-Za-z0-9]+)$/) || [, ''])[1].toLowerCase();
172
+ const isBinary = text.slice(0, 8000).includes('\0');
173
+ renderHead(headEl, { path, name, ext, text, parsed, isBinary });
174
+ linksEl.innerHTML = parsed ? importChips(path) : '';
175
+ if (isBinary) {
176
+ monacoEl.hidden = true;
177
+ alt.innerHTML = '<div class="code-empty">Binary file — nothing to preview.</div>';
178
+ return;
179
+ }
180
+ // Monaco first; the hand-rolled highlighter stands by if it can't load.
181
+ if (!viewerFailed) {
182
+ monacoEl.hidden = false;
183
+ const ok = await initViewer(monacoEl, hooks.getTheme());
184
+ if (seq !== codeSeq)
185
+ return;
186
+ if (ok) {
187
+ alt.innerHTML = '';
188
+ showInViewer(text, monacoLangOf(path), hooks.getTheme());
189
+ applyReveal(alt, revealLine);
190
+ return;
191
+ }
192
+ viewerFailed = true;
193
+ monacoEl.hidden = true;
194
194
  }
195
- viewerFailed = true;
196
- monacoEl.hidden = true;
197
- }
198
- renderFallback(alt, text, path);
199
- applyReveal(alt, revealLine);
195
+ renderFallback(alt, text, path);
196
+ applyReveal(alt, revealLine);
200
197
  }
201
-
202
198
  // Navigation, identity, actions.
203
199
  function renderHead(headEl, { path, name, ext, text, parsed, isBinary }) {
204
- const { facts } = state;
205
- const canBack = state.code.idx > 0;
206
- const canFwd = state.code.idx < state.code.history.length - 1;
207
- const meta = [
208
- (ext || 'text').toUpperCase(),
209
- `${text.split('\n').length.toLocaleString()} lines`,
210
- `${(new Blob([text]).size / 1024).toFixed(1)} KB`,
211
- parsed ? `${roleOf(path, facts)} · ${facts.fanIn[path]} dependents · pulls in ${facts.fanOut[path]}` : 'not parsed',
212
- ].join(' · ');
213
-
214
- headEl.innerHTML = `
200
+ const { facts } = state;
201
+ const canBack = state.code.idx > 0;
202
+ const canFwd = state.code.idx < state.code.history.length - 1;
203
+ const meta = [
204
+ (ext || 'text').toUpperCase(),
205
+ `${text.split('\n').length.toLocaleString()} lines`,
206
+ `${(new Blob([text]).size / 1024).toFixed(1)} KB`,
207
+ parsed ? `${roleOf(path, facts)} · ${facts.fanIn[path]} dependents · pulls in ${facts.fanOut[path]}` : 'not parsed',
208
+ ].join(' · ');
209
+ headEl.innerHTML = `
215
210
  <div class="code-nav">
216
211
  <button class="code-navbtn" data-codenav="-1" ${canBack ? '' : 'disabled'} title="Previous file">←</button>
217
212
  <button class="code-navbtn" data-codenav="1" ${canFwd ? '' : 'disabled'} title="Next file">→</button>
@@ -227,30 +222,30 @@ function renderHead(headEl, { path, name, ext, text, parsed, isBinary }) {
227
222
  <button class="code-navbtn" data-codedive>Deep-dive →</button>
228
223
  </div>`;
229
224
  }
230
-
231
225
  // The file's neighbours, both directions, as one-click jumps.
232
226
  function importChips(path) {
233
- const { facts } = state;
234
- const chip = (p) => `<button class="code-chip" data-codeopen="${escapeHtml(p)}" title="${escapeHtml(p)}">${escapeHtml(p.split('/').pop())}</button>`;
235
- const pulls = (facts.importsOf[path] || []).map(chip).join('');
236
- const leans = (facts.importers[path] || []).map(chip).join('');
237
- if (!pulls && !leans) return '';
238
- return '<div class="code-links">'
239
- + (pulls ? `<span class="code-links-label">pulls in</span>${pulls}` : '')
240
- + (leans ? `<span class="code-links-label">leaned on by</span>${leans}` : '')
241
- + '</div>';
227
+ const { facts } = state;
228
+ const chip = (p) => `<button class="code-chip" data-codeopen="${escapeHtml(p)}" title="${escapeHtml(p)}">${escapeHtml(p.split('/').pop())}</button>`;
229
+ const pulls = (facts.importsOf[path] || []).map(chip).join('');
230
+ const leans = (facts.importers[path] || []).map(chip).join('');
231
+ if (!pulls && !leans)
232
+ return '';
233
+ return '<div class="code-links">'
234
+ + (pulls ? `<span class="code-links-label">pulls in</span>${pulls}` : '')
235
+ + (leans ? `<span class="code-links-label">leaned on by</span>${leans}` : '')
236
+ + '</div>';
242
237
  }
243
-
244
238
  // Without Monaco: a gutter, a highlighted body, and a cap, because pasting a
245
239
  // 40,000-line bundle into innerHTML locks the tab.
246
240
  function renderFallback(alt, text, path) {
247
- const all = text.split('\n');
248
- const capped = all.length > MAX_FALLBACK_LINES;
249
- const lines = capped ? all.slice(0, MAX_FALLBACK_LINES) : all;
250
- const gutter = lines.map((_, i) => i + 1).join('\n');
251
- const note = capped
252
- ? `<div class="code-note">Showing the first ${MAX_FALLBACK_LINES.toLocaleString()} of ${all.length.toLocaleString()} lines.</div>`
253
- : '';
254
- alt.innerHTML = `${note}<div class="code-shell"><pre class="code-gutter">${gutter}</pre>`
255
- + `<pre class="code-body"><code>${highlightCode(lines.join('\n'), langOf(path))}</code></pre></div>`;
241
+ const all = text.split('\n');
242
+ const capped = all.length > MAX_FALLBACK_LINES;
243
+ const lines = capped ? all.slice(0, MAX_FALLBACK_LINES) : all;
244
+ const gutter = lines.map((_, i) => i + 1).join('\n');
245
+ const note = capped
246
+ ? `<div class="code-note">Showing the first ${MAX_FALLBACK_LINES.toLocaleString()} of ${all.length.toLocaleString()} lines.</div>`
247
+ : '';
248
+ alt.innerHTML = `${note}<div class="code-shell"><pre class="code-gutter">${gutter}</pre>`
249
+ + `<pre class="code-body"><code>${highlightCode(lines.join('\n'), langOf(path))}</code></pre></div>`;
256
250
  }
251
+ //# sourceMappingURL=codeTab.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codeTab.js","sourceRoot":"","sources":["../../src/public/js/codeTab.ts"],"names":[],"mappings":"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","sourcesContent":["// The Code tab: one file at a time, with its imports as chips you can click.\n//\n// Two viewers, one behind the other. Monaco is loaded from the app's own\n// `vendor/` folder and used if it comes up; if it does not, a hand-rolled\n// highlighter takes over for the rest of the session. Neither is required for\n// the page to be useful — the header, the facts and the import chips are drawn\n// from the graph before any file text arrives.\n//\n// The back/forward stack and the \"which file should I show\" decision live in\n// state.js, where they are pure and tested. What is left here is DOM.\n\nimport { roleOf } from '/shared/analyzer/graph.js';\nimport { escapeHtml } from './html.js';\nimport { highlightCode, langOf } from './highlight.js';\nimport { initViewer, showInViewer, monacoLangOf, revealLineInViewer } from './codeViewer.js';\nimport { fetchBlame, initBlameView } from './blameView.js';\nimport {\n state, focusFile, defaultCodePath, pushCodeHistory, codeHistoryTarget,\n} from './state.js';\nimport { readRepoFile } from './repoFiles.js';\n\nconst MAX_FALLBACK_LINES = 3000;\n\nlet host = null;\nlet renderBlameGutter = null;\nlet hooks = {\n onDeepDive: (_path: string) => {},\n onSyncInspector: (..._args: unknown[]) => {},\n onRenderSidebar: (..._args: unknown[]) => {},\n onOpenFile: (..._args: unknown[]) => {},\n onToast: (..._args: unknown[]) => {},\n getTheme: () => 'light',\n blameGutter: null,\n};\n\nlet codeSeq = 0; // render generations — a slow read never overwrites a newer one\nlet viewerFailed = false; // Monaco failed to load → hand-rolled fallback\nlet pendingReveal = null; // a line a search result asked for, waiting for its file\n\n// A search result knows which line it matched. The reveal has to wait until the\n// text is on screen, and it must not leak onto the *next* file you open — which\n// is why it is taken once, at the top of `renderCode`, rather than living in\n// `state` where it would outlive the file it was meant for.\nexport function revealLineInCode(line) {\n const target = Math.floor(Number(line));\n pendingReveal = Number.isFinite(target) && target > 0 ? target : null;\n}\n\n// Monaco is the real answer; without it, the fallback is a single scrolling\n// `<pre>`, so the best we can do is put the line near the top. Approximate, and\n// honest about being approximate — the file is still the right file.\nfunction applyReveal(alt, line) {\n if (!line) return;\n if (!viewerFailed) {\n revealLineInViewer(line);\n return;\n }\n const shell = alt.querySelector('.code-shell');\n if (!shell) return;\n const gutter = shell.querySelector('.code-gutter');\n const total = gutter ? (gutter.textContent || '').split('\\n').length : 0;\n if (!total) return;\n const perLine = shell.scrollHeight / total;\n shell.scrollTop = Math.max(0, (line - 2) * perLine);\n}\n\nexport function initCodeTab(options) {\n host = options.host;\n hooks = { ...hooks, ...options };\n if (options.blameGutter) {\n renderBlameGutter = initBlameView(options.blameGutter);\n }\n\n host.addEventListener('click', (event) => {\n const b = event.target.closest('button');\n if (!b) return;\n if (b.dataset.codeopen) return openCodeFile(b.dataset.codeopen);\n if (b.dataset.codenav) return codeNav(Number(b.dataset.codenav));\n if (b.dataset.codedive !== undefined) return (hooks.onDeepDive || hooks.onOpenFile)(state.code.path); // empty attribute is falsy — test undefined\n if (b.dataset.codeblame !== undefined) {\n if (!hooks.blameGutter) return;\n if (!hooks.blameGutter.hidden) {\n hooks.blameGutter.hidden = true;\n b.classList.remove('is-active');\n } else {\n hooks.onToast('Fetching git blame...');\n fetchBlame(state.scanId, state.code.path).then((data) => {\n if (data && data.lines && data.lines.length) {\n renderBlameGutter(data);\n hooks.blameGutter.hidden = false;\n b.classList.add('is-active');\n hooks.onToast(`Blame loaded for ${data.lines.length} lines`);\n } else {\n hooks.onToast(data?.reason || 'No blame available for this file.');\n }\n });\n }\n return;\n }\n if (b.dataset.codecopy !== undefined) {\n const text = state.code.cache[state.code.path];\n if (text !== undefined) {\n navigator.clipboard.writeText(text)\n .then(() => hooks.onToast('Copied to the clipboard.'))\n .catch(() => hooks.onToast('Could not copy to the clipboard.'));\n }\n }\n });\n}\n\n// In-tab navigation (the import chips) keeps the sidebar and inspector in step,\n// so the rest of the app follows along rather than pointing at the old file.\nfunction openCodeFile(path) {\n state.code.path = path;\n focusFile(path);\n hooks.onSyncInspector();\n hooks.onRenderSidebar();\n renderCode();\n}\n\nfunction codeNav(delta) {\n const path = codeHistoryTarget(delta);\n if (path) openCodeFile(path);\n}\n\nexport async function renderCode() {\n const seq = ++codeSeq;\n const path = defaultCodePath();\n // Taken once and cleared, so a reveal belongs only to the render that followed\n // the request for it — never to the next file you happen to open.\n const revealLine = pendingReveal;\n pendingReveal = null;\n if (!path) {\n host.innerHTML = '<div class=\"code-empty\">Nothing to preview — this repo has no readable files.</div>';\n return;\n }\n state.code.path = path;\n pushCodeHistory(path);\n\n // The shell is built once: the Monaco container must persist across file\n // switches, or the editor instance would be destroyed on every render.\n if (!host.querySelector('.code-page')) {\n host.innerHTML = `<div class=\"code-page\">\n <div class=\"code-head\" id=\"codeHead\"></div>\n <div id=\"codeLinks\"></div>\n <div class=\"code-monaco\" id=\"codeMonaco\" hidden></div>\n <div id=\"codeAlt\"></div>\n </div>`;\n }\n const headEl = host.querySelector('#codeHead');\n const linksEl = host.querySelector('#codeLinks');\n const monacoEl = host.querySelector('#codeMonaco');\n const alt = host.querySelector('#codeAlt');\n\n let text = state.code.cache[path];\n if (text === undefined) {\n monacoEl.hidden = true;\n alt.innerHTML = '<div class=\"code-empty\">Reading ' + escapeHtml(path) + '…</div>';\n try {\n text = await readRepoFile(path);\n } catch (err) {\n if (seq !== codeSeq) return;\n alt.innerHTML = '<div class=\"code-empty\">Could not read that file: ' + escapeHtml(err.message) + '</div>';\n return;\n }\n if (seq !== codeSeq) return;\n state.code.cache[path] = text;\n }\n\n const { facts } = state;\n const parsed = facts.fanIn[path] !== undefined;\n const name = path.split('/').pop();\n const ext = (name.match(/\\.([A-Za-z0-9]+)$/) || [, ''])[1].toLowerCase();\n const isBinary = text.slice(0, 8000).includes('\\0');\n\n renderHead(headEl, { path, name, ext, text, parsed, isBinary });\n linksEl.innerHTML = parsed ? importChips(path) : '';\n\n if (isBinary) {\n monacoEl.hidden = true;\n alt.innerHTML = '<div class=\"code-empty\">Binary file — nothing to preview.</div>';\n return;\n }\n\n // Monaco first; the hand-rolled highlighter stands by if it can't load.\n if (!viewerFailed) {\n monacoEl.hidden = false;\n const ok = await initViewer(monacoEl, hooks.getTheme());\n if (seq !== codeSeq) return;\n if (ok) {\n alt.innerHTML = '';\n showInViewer(text, monacoLangOf(path), hooks.getTheme());\n applyReveal(alt, revealLine);\n return;\n }\n viewerFailed = true;\n monacoEl.hidden = true;\n }\n renderFallback(alt, text, path);\n applyReveal(alt, revealLine);\n}\n\n// Navigation, identity, actions.\nfunction renderHead(headEl, { path, name, ext, text, parsed, isBinary }) {\n const { facts } = state;\n const canBack = state.code.idx > 0;\n const canFwd = state.code.idx < state.code.history.length - 1;\n const meta = [\n (ext || 'text').toUpperCase(),\n `${text.split('\\n').length.toLocaleString()} lines`,\n `${(new Blob([text]).size / 1024).toFixed(1)} KB`,\n parsed ? `${roleOf(path, facts)} · ${facts.fanIn[path]} dependents · pulls in ${facts.fanOut[path]}` : 'not parsed',\n ].join(' · ');\n\n headEl.innerHTML = `\n <div class=\"code-nav\">\n <button class=\"code-navbtn\" data-codenav=\"-1\" ${canBack ? '' : 'disabled'} title=\"Previous file\">←</button>\n <button class=\"code-navbtn\" data-codenav=\"1\" ${canFwd ? '' : 'disabled'} title=\"Next file\">→</button>\n </div>\n <div class=\"code-title\">\n <h2>${escapeHtml(name)}</h2>\n <div class=\"code-path\">${escapeHtml(path)}</div>\n <div class=\"code-meta\">${escapeHtml(meta)}</div>\n </div>\n <div class=\"code-actions\">\n <button class=\"code-navbtn\" data-codeblame ${isBinary ? 'disabled' : ''} title=\"Toggle Git blame annotations\">Blame</button>\n <button class=\"code-navbtn\" data-codecopy ${isBinary ? 'disabled' : ''}>Copy</button>\n <button class=\"code-navbtn\" data-codedive>Deep-dive →</button>\n </div>`;\n}\n\n// The file's neighbours, both directions, as one-click jumps.\nfunction importChips(path) {\n const { facts } = state;\n const chip = (p) => `<button class=\"code-chip\" data-codeopen=\"${escapeHtml(p)}\" title=\"${escapeHtml(p)}\">${escapeHtml(p.split('/').pop())}</button>`;\n const pulls = (facts.importsOf[path] || []).map(chip).join('');\n const leans = (facts.importers[path] || []).map(chip).join('');\n if (!pulls && !leans) return '';\n return '<div class=\"code-links\">'\n + (pulls ? `<span class=\"code-links-label\">pulls in</span>${pulls}` : '')\n + (leans ? `<span class=\"code-links-label\">leaned on by</span>${leans}` : '')\n + '</div>';\n}\n\n// Without Monaco: a gutter, a highlighted body, and a cap, because pasting a\n// 40,000-line bundle into innerHTML locks the tab.\nfunction renderFallback(alt, text, path) {\n const all = text.split('\\n');\n const capped = all.length > MAX_FALLBACK_LINES;\n const lines = capped ? all.slice(0, MAX_FALLBACK_LINES) : all;\n const gutter = lines.map((_, i) => i + 1).join('\\n');\n const note = capped\n ? `<div class=\"code-note\">Showing the first ${MAX_FALLBACK_LINES.toLocaleString()} of ${all.length.toLocaleString()} lines.</div>`\n : '';\n alt.innerHTML = `${note}<div class=\"code-shell\"><pre class=\"code-gutter\">${gutter}</pre>`\n + `<pre class=\"code-body\"><code>${highlightCode(lines.join('\\n'), langOf(path))}</code></pre></div>`;\n}\n"]}
@@ -0,0 +1,5 @@
1
+ export declare function monacoLangOf(path: string): string;
2
+ export declare function initViewer(container: HTMLElement, theme: string): Promise<boolean>;
3
+ export declare function showInViewer(text: string, lang: string, theme: string): void;
4
+ export declare function setViewerTheme(theme: string): void;
5
+ export declare function revealLineInViewer(line: unknown): void;