kirograph 0.19.0 → 0.20.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 (658) hide show
  1. package/README.md +10 -8
  2. package/dist/architecture/layers/dart.d.ts +10 -0
  3. package/dist/architecture/layers/dart.d.ts.map +1 -0
  4. package/dist/architecture/layers/elixir.d.ts +6 -0
  5. package/dist/architecture/layers/elixir.d.ts.map +1 -0
  6. package/dist/architecture/layers/index.d.ts.map +1 -1
  7. package/dist/architecture/layers/ocaml.d.ts +6 -0
  8. package/dist/architecture/layers/ocaml.d.ts.map +1 -0
  9. package/dist/architecture/layers/scala.d.ts +6 -0
  10. package/dist/architecture/layers/scala.d.ts.map +1 -0
  11. package/dist/architecture/layers/solidity.d.ts +6 -0
  12. package/dist/architecture/layers/solidity.d.ts.map +1 -0
  13. package/dist/architecture/layers/vue.d.ts +6 -0
  14. package/dist/architecture/layers/vue.d.ts.map +1 -0
  15. package/dist/architecture/manifest/elm.d.ts +3 -0
  16. package/dist/architecture/manifest/elm.d.ts.map +1 -0
  17. package/dist/architecture/manifest/index.d.ts.map +1 -1
  18. package/dist/architecture/manifest/ocaml.d.ts +3 -0
  19. package/dist/architecture/manifest/ocaml.d.ts.map +1 -0
  20. package/dist/architecture/manifest/scala.d.ts +3 -0
  21. package/dist/architecture/manifest/scala.d.ts.map +1 -0
  22. package/dist/bin/banner.d.ts.map +1 -1
  23. package/dist/bin/commands/affected.d.ts.map +1 -1
  24. package/dist/bin/commands/attack-surface.d.ts +3 -0
  25. package/dist/bin/commands/attack-surface.d.ts.map +1 -0
  26. package/dist/bin/commands/attack-surface.js +7 -0
  27. package/dist/bin/commands/attack-surface.js.map +2 -2
  28. package/dist/bin/commands/benchmark.d.ts +9 -0
  29. package/dist/bin/commands/benchmark.d.ts.map +1 -0
  30. package/dist/bin/commands/budget.d.ts +6 -0
  31. package/dist/bin/commands/budget.d.ts.map +1 -0
  32. package/dist/bin/commands/caveman.d.ts +7 -0
  33. package/dist/bin/commands/caveman.d.ts.map +1 -0
  34. package/dist/bin/commands/communities.d.ts +3 -0
  35. package/dist/bin/commands/communities.d.ts.map +1 -0
  36. package/dist/bin/commands/compression.d.ts +7 -0
  37. package/dist/bin/commands/compression.d.ts.map +1 -0
  38. package/dist/bin/commands/context.d.ts.map +1 -1
  39. package/dist/bin/commands/data.d.ts +3 -0
  40. package/dist/bin/commands/data.d.ts.map +1 -0
  41. package/dist/bin/commands/dead-code.d.ts +3 -0
  42. package/dist/bin/commands/dead-code.d.ts.map +1 -0
  43. package/dist/bin/commands/dep-confusion.d.ts +3 -0
  44. package/dist/bin/commands/dep-confusion.d.ts.map +1 -0
  45. package/dist/bin/commands/docs.d.ts +3 -0
  46. package/dist/bin/commands/docs.d.ts.map +1 -0
  47. package/dist/bin/commands/exec.d.ts +11 -0
  48. package/dist/bin/commands/exec.d.ts.map +1 -0
  49. package/dist/bin/commands/export.d.ts +3 -0
  50. package/dist/bin/commands/export.d.ts.map +1 -0
  51. package/dist/bin/commands/flows.d.ts +3 -0
  52. package/dist/bin/commands/flows.d.ts.map +1 -0
  53. package/dist/bin/commands/gain.d.ts +6 -0
  54. package/dist/bin/commands/gain.d.ts.map +1 -0
  55. package/dist/bin/commands/help.d.ts +7 -0
  56. package/dist/bin/commands/help.d.ts.map +1 -1
  57. package/dist/bin/commands/help.js +20 -3
  58. package/dist/bin/commands/help.js.map +2 -2
  59. package/dist/bin/commands/hotspots.d.ts +3 -0
  60. package/dist/bin/commands/hotspots.d.ts.map +1 -0
  61. package/dist/bin/commands/hotspots.js +94 -1
  62. package/dist/bin/commands/hotspots.js.map +3 -3
  63. package/dist/bin/commands/install.d.ts.map +1 -1
  64. package/dist/bin/commands/install.js +3 -3
  65. package/dist/bin/commands/install.js.map +2 -2
  66. package/dist/bin/commands/licenses.d.ts +3 -0
  67. package/dist/bin/commands/licenses.d.ts.map +1 -0
  68. package/dist/bin/commands/memory.d.ts +16 -0
  69. package/dist/bin/commands/memory.d.ts.map +1 -0
  70. package/dist/bin/commands/memory.js +151 -4
  71. package/dist/bin/commands/memory.js.map +2 -2
  72. package/dist/bin/commands/path.d.ts +3 -0
  73. package/dist/bin/commands/path.d.ts.map +1 -0
  74. package/dist/bin/commands/pattern.d.ts +3 -0
  75. package/dist/bin/commands/pattern.d.ts.map +1 -0
  76. package/dist/bin/commands/pattern.js +592 -0
  77. package/dist/bin/commands/pattern.js.map +7 -0
  78. package/dist/bin/commands/query.d.ts.map +1 -1
  79. package/dist/bin/commands/reachability.d.ts +3 -0
  80. package/dist/bin/commands/reachability.d.ts.map +1 -0
  81. package/dist/bin/commands/read.d.ts +6 -0
  82. package/dist/bin/commands/read.d.ts.map +1 -0
  83. package/dist/bin/commands/refactor.d.ts +3 -0
  84. package/dist/bin/commands/refactor.d.ts.map +1 -0
  85. package/dist/bin/commands/remediation.d.ts +3 -0
  86. package/dist/bin/commands/remediation.d.ts.map +1 -0
  87. package/dist/bin/commands/sbom.d.ts +3 -0
  88. package/dist/bin/commands/sbom.d.ts.map +1 -0
  89. package/dist/bin/commands/security-ci-report.d.ts +9 -0
  90. package/dist/bin/commands/security-ci-report.d.ts.map +1 -0
  91. package/dist/bin/commands/security-export.d.ts +2 -0
  92. package/dist/bin/commands/security-export.d.ts.map +1 -0
  93. package/dist/bin/commands/security-flows.d.ts +3 -0
  94. package/dist/bin/commands/security-flows.d.ts.map +1 -0
  95. package/dist/bin/commands/security-secrets.d.ts +3 -0
  96. package/dist/bin/commands/security-secrets.d.ts.map +1 -0
  97. package/dist/bin/commands/security.d.ts +3 -0
  98. package/dist/bin/commands/security.d.ts.map +1 -0
  99. package/dist/bin/commands/security.js +15 -0
  100. package/dist/bin/commands/security.js.map +2 -2
  101. package/dist/bin/commands/snapshot.d.ts +3 -0
  102. package/dist/bin/commands/snapshot.d.ts.map +1 -0
  103. package/dist/bin/commands/staleness.d.ts +3 -0
  104. package/dist/bin/commands/staleness.d.ts.map +1 -0
  105. package/dist/bin/commands/status.d.ts.map +1 -1
  106. package/dist/bin/commands/status.js +27 -0
  107. package/dist/bin/commands/status.js.map +2 -2
  108. package/dist/bin/commands/supply-chain.d.ts +3 -0
  109. package/dist/bin/commands/supply-chain.d.ts.map +1 -0
  110. package/dist/bin/commands/surprising.d.ts +3 -0
  111. package/dist/bin/commands/surprising.d.ts.map +1 -0
  112. package/dist/bin/commands/sync.d.ts.map +1 -1
  113. package/dist/bin/commands/uninit.d.ts.map +1 -1
  114. package/dist/bin/commands/utils.d.ts +5 -0
  115. package/dist/bin/commands/utils.d.ts.map +1 -1
  116. package/dist/bin/commands/vex.d.ts +3 -0
  117. package/dist/bin/commands/vex.d.ts.map +1 -0
  118. package/dist/bin/commands/vuln-suppress.d.ts +3 -0
  119. package/dist/bin/commands/vuln-suppress.d.ts.map +1 -0
  120. package/dist/bin/commands/vulns.d.ts +3 -0
  121. package/dist/bin/commands/vulns.d.ts.map +1 -0
  122. package/dist/bin/installer/archive.d.ts +47 -0
  123. package/dist/bin/installer/archive.d.ts.map +1 -0
  124. package/dist/bin/installer/auto-detect.d.ts +16 -0
  125. package/dist/bin/installer/auto-detect.d.ts.map +1 -0
  126. package/dist/bin/installer/caveman.d.ts +12 -0
  127. package/dist/bin/installer/caveman.d.ts.map +1 -0
  128. package/dist/bin/installer/cli-agent.d.ts +7 -2
  129. package/dist/bin/installer/cli-agent.d.ts.map +1 -1
  130. package/dist/bin/installer/cli-agent.js +6 -2
  131. package/dist/bin/installer/cli-agent.js.map +2 -2
  132. package/dist/bin/installer/common.d.ts +36 -0
  133. package/dist/bin/installer/common.d.ts.map +1 -0
  134. package/dist/bin/installer/common.js +2 -1
  135. package/dist/bin/installer/common.js.map +2 -2
  136. package/dist/bin/installer/config-prompt.d.ts +1 -1
  137. package/dist/bin/installer/config-prompt.d.ts.map +1 -1
  138. package/dist/bin/installer/config-prompt.js +74 -2
  139. package/dist/bin/installer/config-prompt.js.map +2 -2
  140. package/dist/bin/installer/dashboard.d.ts.map +1 -1
  141. package/dist/bin/installer/detect.d.ts +30 -0
  142. package/dist/bin/installer/detect.d.ts.map +1 -0
  143. package/dist/bin/installer/hooks.d.ts +4 -1
  144. package/dist/bin/installer/hooks.d.ts.map +1 -1
  145. package/dist/bin/installer/hooks.js +34 -0
  146. package/dist/bin/installer/hooks.js.map +2 -2
  147. package/dist/bin/installer/index.d.ts +5 -4
  148. package/dist/bin/installer/index.d.ts.map +1 -1
  149. package/dist/bin/installer/index.js +38 -8
  150. package/dist/bin/installer/index.js.map +2 -2
  151. package/dist/bin/installer/instructions.d.ts +14 -0
  152. package/dist/bin/installer/instructions.d.ts.map +1 -0
  153. package/dist/bin/installer/instructions.js +15 -1
  154. package/dist/bin/installer/instructions.js.map +2 -2
  155. package/dist/bin/installer/mcp.d.ts.map +1 -1
  156. package/dist/bin/installer/prompts.d.ts +17 -0
  157. package/dist/bin/installer/prompts.d.ts.map +1 -1
  158. package/dist/bin/installer/qdrant-dashboard.d.ts.map +1 -1
  159. package/dist/bin/installer/steering.d.ts +14 -2
  160. package/dist/bin/installer/steering.d.ts.map +1 -1
  161. package/dist/bin/installer/steering.js +81 -0
  162. package/dist/bin/installer/steering.js.map +2 -2
  163. package/dist/bin/installer/targets/aider.d.ts +6 -0
  164. package/dist/bin/installer/targets/aider.d.ts.map +1 -0
  165. package/dist/bin/installer/targets/aider.js +3 -3
  166. package/dist/bin/installer/targets/aider.js.map +2 -2
  167. package/dist/bin/installer/targets/amp.d.ts +6 -0
  168. package/dist/bin/installer/targets/amp.d.ts.map +1 -0
  169. package/dist/bin/installer/targets/amp.js +3 -3
  170. package/dist/bin/installer/targets/amp.js.map +2 -2
  171. package/dist/bin/installer/targets/antigravity.d.ts +13 -0
  172. package/dist/bin/installer/targets/antigravity.d.ts.map +1 -0
  173. package/dist/bin/installer/targets/antigravity.js +2 -2
  174. package/dist/bin/installer/targets/antigravity.js.map +2 -2
  175. package/dist/bin/installer/targets/augment.d.ts +6 -0
  176. package/dist/bin/installer/targets/augment.d.ts.map +1 -0
  177. package/dist/bin/installer/targets/augment.js +3 -3
  178. package/dist/bin/installer/targets/augment.js.map +2 -2
  179. package/dist/bin/installer/targets/claude.d.ts +6 -0
  180. package/dist/bin/installer/targets/claude.d.ts.map +1 -0
  181. package/dist/bin/installer/targets/claude.js +2 -2
  182. package/dist/bin/installer/targets/claude.js.map +2 -2
  183. package/dist/bin/installer/targets/cline.d.ts +13 -0
  184. package/dist/bin/installer/targets/cline.d.ts.map +1 -0
  185. package/dist/bin/installer/targets/cline.js +2 -2
  186. package/dist/bin/installer/targets/cline.js.map +2 -2
  187. package/dist/bin/installer/targets/codex.d.ts +6 -0
  188. package/dist/bin/installer/targets/codex.d.ts.map +1 -0
  189. package/dist/bin/installer/targets/codex.js +2 -2
  190. package/dist/bin/installer/targets/codex.js.map +2 -2
  191. package/dist/bin/installer/targets/continue.d.ts +12 -0
  192. package/dist/bin/installer/targets/continue.d.ts.map +1 -0
  193. package/dist/bin/installer/targets/continue.js +2 -2
  194. package/dist/bin/installer/targets/continue.js.map +2 -2
  195. package/dist/bin/installer/targets/copilot-cli.d.ts +12 -0
  196. package/dist/bin/installer/targets/copilot-cli.d.ts.map +1 -0
  197. package/dist/bin/installer/targets/copilot-cli.js +2 -2
  198. package/dist/bin/installer/targets/copilot-cli.js.map +2 -2
  199. package/dist/bin/installer/targets/copilot.d.ts +6 -0
  200. package/dist/bin/installer/targets/copilot.d.ts.map +1 -0
  201. package/dist/bin/installer/targets/copilot.js +2 -2
  202. package/dist/bin/installer/targets/copilot.js.map +2 -2
  203. package/dist/bin/installer/targets/cursor.d.ts +6 -0
  204. package/dist/bin/installer/targets/cursor.d.ts.map +1 -0
  205. package/dist/bin/installer/targets/cursor.js +2 -2
  206. package/dist/bin/installer/targets/cursor.js.map +2 -2
  207. package/dist/bin/installer/targets/devin.d.ts +13 -0
  208. package/dist/bin/installer/targets/devin.d.ts.map +1 -0
  209. package/dist/bin/installer/targets/devin.js +2 -2
  210. package/dist/bin/installer/targets/devin.js.map +2 -2
  211. package/dist/bin/installer/targets/gemini-cli.d.ts +16 -0
  212. package/dist/bin/installer/targets/gemini-cli.d.ts.map +1 -0
  213. package/dist/bin/installer/targets/gemini-cli.js +2 -2
  214. package/dist/bin/installer/targets/gemini-cli.js.map +2 -2
  215. package/dist/bin/installer/targets/generic.d.ts +59 -0
  216. package/dist/bin/installer/targets/generic.d.ts.map +1 -0
  217. package/dist/bin/installer/targets/generic.js +2 -2
  218. package/dist/bin/installer/targets/generic.js.map +2 -2
  219. package/dist/bin/installer/targets/goose.d.ts +6 -0
  220. package/dist/bin/installer/targets/goose.d.ts.map +1 -0
  221. package/dist/bin/installer/targets/goose.js +3 -3
  222. package/dist/bin/installer/targets/goose.js.map +2 -2
  223. package/dist/bin/installer/targets/index.d.ts +11 -0
  224. package/dist/bin/installer/targets/index.d.ts.map +1 -0
  225. package/dist/bin/installer/targets/index.js.map +1 -1
  226. package/dist/bin/installer/targets/junie.d.ts +13 -0
  227. package/dist/bin/installer/targets/junie.d.ts.map +1 -0
  228. package/dist/bin/installer/targets/junie.js +2 -2
  229. package/dist/bin/installer/targets/junie.js.map +2 -2
  230. package/dist/bin/installer/targets/kilo.d.ts +12 -0
  231. package/dist/bin/installer/targets/kilo.d.ts.map +1 -0
  232. package/dist/bin/installer/targets/kilo.js +2 -2
  233. package/dist/bin/installer/targets/kilo.js.map +2 -2
  234. package/dist/bin/installer/targets/kiro.d.ts +5 -0
  235. package/dist/bin/installer/targets/kiro.d.ts.map +1 -0
  236. package/dist/bin/installer/targets/kiro.js +4 -4
  237. package/dist/bin/installer/targets/kiro.js.map +2 -2
  238. package/dist/bin/installer/targets/opencode.d.ts +13 -0
  239. package/dist/bin/installer/targets/opencode.d.ts.map +1 -0
  240. package/dist/bin/installer/targets/opencode.js +2 -2
  241. package/dist/bin/installer/targets/opencode.js.map +2 -2
  242. package/dist/bin/installer/targets/openhands.d.ts +6 -0
  243. package/dist/bin/installer/targets/openhands.d.ts.map +1 -0
  244. package/dist/bin/installer/targets/openhands.js +3 -3
  245. package/dist/bin/installer/targets/openhands.js.map +2 -2
  246. package/dist/bin/installer/targets/qoder.d.ts +12 -0
  247. package/dist/bin/installer/targets/qoder.d.ts.map +1 -0
  248. package/dist/bin/installer/targets/qoder.js +2 -2
  249. package/dist/bin/installer/targets/qoder.js.map +2 -2
  250. package/dist/bin/installer/targets/qwen.d.ts +12 -0
  251. package/dist/bin/installer/targets/qwen.d.ts.map +1 -0
  252. package/dist/bin/installer/targets/qwen.js +2 -2
  253. package/dist/bin/installer/targets/qwen.js.map +2 -2
  254. package/dist/bin/installer/targets/replit.d.ts +6 -0
  255. package/dist/bin/installer/targets/replit.d.ts.map +1 -0
  256. package/dist/bin/installer/targets/replit.js +3 -3
  257. package/dist/bin/installer/targets/replit.js.map +2 -2
  258. package/dist/bin/installer/targets/roo.d.ts +13 -0
  259. package/dist/bin/installer/targets/roo.d.ts.map +1 -0
  260. package/dist/bin/installer/targets/roo.js +2 -2
  261. package/dist/bin/installer/targets/roo.js.map +2 -2
  262. package/dist/bin/installer/targets/tabnine.d.ts +6 -0
  263. package/dist/bin/installer/targets/tabnine.d.ts.map +1 -0
  264. package/dist/bin/installer/targets/tabnine.js +3 -3
  265. package/dist/bin/installer/targets/tabnine.js.map +2 -2
  266. package/dist/bin/installer/targets/trae.d.ts +6 -0
  267. package/dist/bin/installer/targets/trae.d.ts.map +1 -0
  268. package/dist/bin/installer/targets/trae.js +3 -3
  269. package/dist/bin/installer/targets/trae.js.map +2 -2
  270. package/dist/bin/installer/targets/warp.d.ts +12 -0
  271. package/dist/bin/installer/targets/warp.d.ts.map +1 -0
  272. package/dist/bin/installer/targets/warp.js +2 -2
  273. package/dist/bin/installer/targets/warp.js.map +2 -2
  274. package/dist/bin/installer/targets/windsurf.d.ts +13 -0
  275. package/dist/bin/installer/targets/windsurf.d.ts.map +1 -0
  276. package/dist/bin/installer/targets/windsurf.js +2 -2
  277. package/dist/bin/installer/targets/windsurf.js.map +2 -2
  278. package/dist/bin/kirograph.js +3 -1
  279. package/dist/bin/kirograph.js.map +3 -3
  280. package/dist/bin/progress.d.ts +16 -1
  281. package/dist/bin/progress.d.ts.map +1 -1
  282. package/dist/compression/filters/aws.d.ts +9 -0
  283. package/dist/compression/filters/aws.d.ts.map +1 -0
  284. package/dist/compression/filters/docker.d.ts +6 -0
  285. package/dist/compression/filters/docker.d.ts.map +1 -0
  286. package/dist/compression/filters/files.d.ts +6 -0
  287. package/dist/compression/filters/files.d.ts.map +1 -0
  288. package/dist/compression/filters/generic.d.ts +7 -0
  289. package/dist/compression/filters/generic.d.ts.map +1 -0
  290. package/dist/compression/filters/git.d.ts +6 -0
  291. package/dist/compression/filters/git.d.ts.map +1 -0
  292. package/dist/compression/filters/github.d.ts +6 -0
  293. package/dist/compression/filters/github.d.ts.map +1 -0
  294. package/dist/compression/filters/lint.d.ts +6 -0
  295. package/dist/compression/filters/lint.d.ts.map +1 -0
  296. package/dist/compression/filters/misc.d.ts +6 -0
  297. package/dist/compression/filters/misc.d.ts.map +1 -0
  298. package/dist/compression/filters/package.d.ts +6 -0
  299. package/dist/compression/filters/package.d.ts.map +1 -0
  300. package/dist/compression/filters/test.d.ts +6 -0
  301. package/dist/compression/filters/test.d.ts.map +1 -0
  302. package/dist/compression/index.d.ts +29 -0
  303. package/dist/compression/index.d.ts.map +1 -0
  304. package/dist/compression/naive-cost.d.ts +26 -0
  305. package/dist/compression/naive-cost.d.ts.map +1 -0
  306. package/dist/compression/tracker.d.ts +155 -0
  307. package/dist/compression/tracker.d.ts.map +1 -0
  308. package/dist/compression/types.d.ts +49 -0
  309. package/dist/compression/types.d.ts.map +1 -0
  310. package/dist/config.d.ts +90 -0
  311. package/dist/config.d.ts.map +1 -1
  312. package/dist/config.js +55 -1
  313. package/dist/config.js.map +2 -2
  314. package/dist/core/lock-manager.d.ts +2 -0
  315. package/dist/core/lock-manager.d.ts.map +1 -1
  316. package/dist/core/pipeline.d.ts +4 -1
  317. package/dist/core/pipeline.d.ts.map +1 -1
  318. package/dist/core/pipeline.js +42 -0
  319. package/dist/core/pipeline.js.map +2 -2
  320. package/dist/core/snapshot.d.ts +58 -0
  321. package/dist/core/snapshot.d.ts.map +1 -0
  322. package/dist/data/filters.d.ts +23 -0
  323. package/dist/data/filters.d.ts.map +1 -0
  324. package/dist/data/indexer.d.ts +25 -0
  325. package/dist/data/indexer.d.ts.map +1 -0
  326. package/dist/data/linker.d.ts +37 -0
  327. package/dist/data/linker.d.ts.map +1 -0
  328. package/dist/data/lint.d.ts +27 -0
  329. package/dist/data/lint.d.ts.map +1 -0
  330. package/dist/data/parsers/csv.d.ts +11 -0
  331. package/dist/data/parsers/csv.d.ts.map +1 -0
  332. package/dist/data/parsers/excel.d.ts +10 -0
  333. package/dist/data/parsers/excel.d.ts.map +1 -0
  334. package/dist/data/parsers/index.d.ts +28 -0
  335. package/dist/data/parsers/index.d.ts.map +1 -0
  336. package/dist/data/parsers/json-array.d.ts +9 -0
  337. package/dist/data/parsers/json-array.d.ts.map +1 -0
  338. package/dist/data/parsers/jsonl.d.ts +9 -0
  339. package/dist/data/parsers/jsonl.d.ts.map +1 -0
  340. package/dist/data/parsers/parquet.d.ts +10 -0
  341. package/dist/data/parsers/parquet.d.ts.map +1 -0
  342. package/dist/data/profiler.d.ts +29 -0
  343. package/dist/data/profiler.d.ts.map +1 -0
  344. package/dist/data/queries.d.ts +95 -0
  345. package/dist/data/queries.d.ts.map +1 -0
  346. package/dist/data/types.d.ts +103 -0
  347. package/dist/data/types.d.ts.map +1 -0
  348. package/dist/db/database.d.ts +57 -0
  349. package/dist/db/database.d.ts.map +1 -1
  350. package/dist/db/database.js +19 -0
  351. package/dist/db/database.js.map +2 -2
  352. package/dist/db/patterns-schema.sql +23 -0
  353. package/dist/docs/formats/asciidoc.d.ts +9 -0
  354. package/dist/docs/formats/asciidoc.d.ts.map +1 -0
  355. package/dist/docs/formats/html.d.ts +10 -0
  356. package/dist/docs/formats/html.d.ts.map +1 -0
  357. package/dist/docs/formats/index.d.ts +31 -0
  358. package/dist/docs/formats/index.d.ts.map +1 -0
  359. package/dist/docs/formats/markdown.d.ts +11 -0
  360. package/dist/docs/formats/markdown.d.ts.map +1 -0
  361. package/dist/docs/formats/openapi.d.ts +17 -0
  362. package/dist/docs/formats/openapi.d.ts.map +1 -0
  363. package/dist/docs/formats/org.d.ts +9 -0
  364. package/dist/docs/formats/org.d.ts.map +1 -0
  365. package/dist/docs/formats/plaintext.d.ts +11 -0
  366. package/dist/docs/formats/plaintext.d.ts.map +1 -0
  367. package/dist/docs/formats/rdoc.d.ts +10 -0
  368. package/dist/docs/formats/rdoc.d.ts.map +1 -0
  369. package/dist/docs/formats/rst.d.ts +11 -0
  370. package/dist/docs/formats/rst.d.ts.map +1 -0
  371. package/dist/docs/indexer.d.ts +49 -0
  372. package/dist/docs/indexer.d.ts.map +1 -0
  373. package/dist/docs/linker.d.ts +30 -0
  374. package/dist/docs/linker.d.ts.map +1 -0
  375. package/dist/docs/lint.d.ts +27 -0
  376. package/dist/docs/lint.d.ts.map +1 -0
  377. package/dist/docs/queries.d.ts +78 -0
  378. package/dist/docs/queries.d.ts.map +1 -0
  379. package/dist/docs/section-id.d.ts +48 -0
  380. package/dist/docs/section-id.d.ts.map +1 -0
  381. package/dist/docs/summarizer.d.ts +13 -0
  382. package/dist/docs/summarizer.d.ts.map +1 -0
  383. package/dist/docs/types.d.ts +71 -0
  384. package/dist/docs/types.d.ts.map +1 -0
  385. package/dist/docs/vectors.d.ts +54 -0
  386. package/dist/docs/vectors.d.ts.map +1 -0
  387. package/dist/extraction/extractor.d.ts +1 -1
  388. package/dist/extraction/extractor.d.ts.map +1 -1
  389. package/dist/extraction/grammars.d.ts +6 -0
  390. package/dist/extraction/grammars.d.ts.map +1 -1
  391. package/dist/extraction/languages.d.ts.map +1 -1
  392. package/dist/extraction/notebook.d.ts +14 -0
  393. package/dist/extraction/notebook.d.ts.map +1 -0
  394. package/dist/frameworks/amplify.d.ts +9 -0
  395. package/dist/frameworks/amplify.d.ts.map +1 -0
  396. package/dist/frameworks/angular.d.ts +9 -0
  397. package/dist/frameworks/angular.d.ts.map +1 -0
  398. package/dist/frameworks/ansible.d.ts +8 -0
  399. package/dist/frameworks/ansible.d.ts.map +1 -0
  400. package/dist/frameworks/cloudformation.d.ts +9 -0
  401. package/dist/frameworks/cloudformation.d.ts.map +1 -0
  402. package/dist/frameworks/docker.d.ts +9 -0
  403. package/dist/frameworks/docker.d.ts.map +1 -0
  404. package/dist/frameworks/elixir.d.ts +6 -0
  405. package/dist/frameworks/elixir.d.ts.map +1 -0
  406. package/dist/frameworks/flutter.d.ts +12 -0
  407. package/dist/frameworks/flutter.d.ts.map +1 -0
  408. package/dist/frameworks/iac.d.ts +10 -0
  409. package/dist/frameworks/iac.d.ts.map +1 -0
  410. package/dist/frameworks/index.d.ts +14 -0
  411. package/dist/frameworks/index.d.ts.map +1 -1
  412. package/dist/frameworks/kubernetes.d.ts +9 -0
  413. package/dist/frameworks/kubernetes.d.ts.map +1 -0
  414. package/dist/frameworks/pulumi.d.ts +9 -0
  415. package/dist/frameworks/pulumi.d.ts.map +1 -0
  416. package/dist/frameworks/scala.d.ts +6 -0
  417. package/dist/frameworks/scala.d.ts.map +1 -0
  418. package/dist/frameworks/solidity.d.ts +6 -0
  419. package/dist/frameworks/solidity.d.ts.map +1 -0
  420. package/dist/frameworks/terraform.d.ts +14 -0
  421. package/dist/frameworks/terraform.d.ts.map +1 -0
  422. package/dist/frameworks/vue.d.ts +7 -0
  423. package/dist/frameworks/vue.d.ts.map +1 -0
  424. package/dist/graph/communities.d.ts +43 -0
  425. package/dist/graph/communities.d.ts.map +1 -0
  426. package/dist/graph/flows.d.ts +55 -0
  427. package/dist/graph/flows.d.ts.map +1 -0
  428. package/dist/graph/refactor.d.ts +43 -0
  429. package/dist/graph/refactor.d.ts.map +1 -0
  430. package/dist/index.d.ts +36 -4
  431. package/dist/index.d.ts.map +1 -1
  432. package/dist/mcp/cache.d.ts +69 -0
  433. package/dist/mcp/cache.d.ts.map +1 -0
  434. package/dist/mcp/read-modes.d.ts +31 -0
  435. package/dist/mcp/read-modes.d.ts.map +1 -0
  436. package/dist/mcp/server.d.ts +1 -0
  437. package/dist/mcp/server.d.ts.map +1 -1
  438. package/dist/mcp/server.js +15 -2
  439. package/dist/mcp/server.js.map +2 -2
  440. package/dist/mcp/tool-names.d.ts +2 -0
  441. package/dist/mcp/tool-names.d.ts.map +1 -0
  442. package/dist/mcp/tool-names.js +4 -1
  443. package/dist/mcp/tool-names.js.map +2 -2
  444. package/dist/mcp/tools.d.ts +12 -0
  445. package/dist/mcp/tools.d.ts.map +1 -1
  446. package/dist/mcp/tools.js +397 -0
  447. package/dist/mcp/tools.js.map +2 -2
  448. package/dist/memory/compress.d.ts +19 -0
  449. package/dist/memory/compress.d.ts.map +1 -0
  450. package/dist/memory/database.d.ts +92 -0
  451. package/dist/memory/database.d.ts.map +1 -0
  452. package/dist/memory/database.js +38 -0
  453. package/dist/memory/database.js.map +2 -2
  454. package/dist/memory/index.d.ts +71 -0
  455. package/dist/memory/index.d.ts.map +1 -0
  456. package/dist/memory/index.js +12 -2
  457. package/dist/memory/index.js.map +2 -2
  458. package/dist/memory/symbols.d.ts +21 -0
  459. package/dist/memory/symbols.d.ts.map +1 -0
  460. package/dist/memory/types.d.ts +78 -0
  461. package/dist/memory/types.d.ts.map +1 -0
  462. package/dist/memory/types.js.map +1 -1
  463. package/dist/memory/vectors.d.ts +43 -0
  464. package/dist/memory/vectors.d.ts.map +1 -0
  465. package/dist/patterns/graph.d.ts +16 -0
  466. package/dist/patterns/graph.d.ts.map +1 -0
  467. package/dist/patterns/graph.js +45 -0
  468. package/dist/patterns/graph.js.map +7 -0
  469. package/dist/patterns/index.d.ts +4 -0
  470. package/dist/patterns/index.d.ts.map +1 -0
  471. package/dist/patterns/index.js +39 -0
  472. package/dist/patterns/index.js.map +7 -0
  473. package/dist/patterns/indexer.d.ts +15 -0
  474. package/dist/patterns/indexer.d.ts.map +1 -0
  475. package/dist/patterns/indexer.js +97 -0
  476. package/dist/patterns/indexer.js.map +7 -0
  477. package/dist/patterns/library/command-injection-go.yaml +11 -0
  478. package/dist/patterns/library/dangerous-eval-js.yaml +14 -0
  479. package/dist/patterns/library/dangerous-exec-py.yaml +13 -0
  480. package/dist/patterns/library/dangerous-reflection-java.yaml +8 -0
  481. package/dist/patterns/library/path-traversal-go.yaml +11 -0
  482. package/dist/patterns/library/path-traversal-py.yaml +12 -0
  483. package/dist/patterns/library/path-traversal-readfile-js.yaml +14 -0
  484. package/dist/patterns/library/prototype-pollution-js.yaml +12 -0
  485. package/dist/patterns/library/sql-injection-concat-js.yaml +12 -0
  486. package/dist/patterns/library/sql-injection-java.yaml +13 -0
  487. package/dist/patterns/library/sql-injection-py.yaml +12 -0
  488. package/dist/patterns/library/sql-injection-template-js.yaml +13 -0
  489. package/dist/patterns/library/weak-crypto-md5-js.yaml +13 -0
  490. package/dist/patterns/library/weak-crypto-py.yaml +13 -0
  491. package/dist/patterns/loader.d.ts +18 -0
  492. package/dist/patterns/loader.d.ts.map +1 -0
  493. package/dist/patterns/loader.js +277 -0
  494. package/dist/patterns/loader.js.map +7 -0
  495. package/dist/patterns/runner.d.ts +42 -0
  496. package/dist/patterns/runner.d.ts.map +1 -0
  497. package/dist/patterns/runner.js +277 -0
  498. package/dist/patterns/runner.js.map +7 -0
  499. package/dist/patterns/types.d.ts +27 -0
  500. package/dist/patterns/types.d.ts.map +1 -0
  501. package/dist/patterns/types.js +34 -0
  502. package/dist/patterns/types.js.map +7 -0
  503. package/dist/resolution/bridges/android-rn.d.ts +13 -0
  504. package/dist/resolution/bridges/android-rn.d.ts.map +1 -0
  505. package/dist/resolution/bridges/expo-modules.d.ts +10 -0
  506. package/dist/resolution/bridges/expo-modules.d.ts.map +1 -0
  507. package/dist/resolution/bridges/flutter-channel.d.ts +14 -0
  508. package/dist/resolution/bridges/flutter-channel.d.ts.map +1 -0
  509. package/dist/resolution/bridges/index.d.ts +40 -0
  510. package/dist/resolution/bridges/index.d.ts.map +1 -0
  511. package/dist/resolution/bridges/native-events.d.ts +10 -0
  512. package/dist/resolution/bridges/native-events.d.ts.map +1 -0
  513. package/dist/resolution/bridges/native-views.d.ts +13 -0
  514. package/dist/resolution/bridges/native-views.d.ts.map +1 -0
  515. package/dist/resolution/bridges/react-native.d.ts +9 -0
  516. package/dist/resolution/bridges/react-native.d.ts.map +1 -0
  517. package/dist/resolution/bridges/swift-objc.d.ts +14 -0
  518. package/dist/resolution/bridges/swift-objc.d.ts.map +1 -0
  519. package/dist/resolution/bridges/turbomodules.d.ts +10 -0
  520. package/dist/resolution/bridges/turbomodules.d.ts.map +1 -0
  521. package/dist/resolution/index.d.ts +28 -3
  522. package/dist/resolution/index.d.ts.map +1 -1
  523. package/dist/security/attack-surface.d.ts +46 -0
  524. package/dist/security/attack-surface.d.ts.map +1 -0
  525. package/dist/security/attack-surface.js +43 -1
  526. package/dist/security/attack-surface.js.map +2 -2
  527. package/dist/security/context-warnings.d.ts +40 -0
  528. package/dist/security/context-warnings.d.ts.map +1 -0
  529. package/dist/security/data-flows.d.ts +33 -0
  530. package/dist/security/data-flows.d.ts.map +1 -0
  531. package/dist/security/data-flows.js +65 -7
  532. package/dist/security/data-flows.js.map +2 -2
  533. package/dist/security/dep-confusion.d.ts +23 -0
  534. package/dist/security/dep-confusion.d.ts.map +1 -0
  535. package/dist/security/errors.d.ts +16 -0
  536. package/dist/security/errors.d.ts.map +1 -0
  537. package/dist/security/export/fix-suggestions.d.ts +21 -0
  538. package/dist/security/export/fix-suggestions.d.ts.map +1 -0
  539. package/dist/security/export/sbom.d.ts +33 -0
  540. package/dist/security/export/sbom.d.ts.map +1 -0
  541. package/dist/security/export/serialization.d.ts +62 -0
  542. package/dist/security/export/serialization.d.ts.map +1 -0
  543. package/dist/security/export/vex.d.ts +58 -0
  544. package/dist/security/export/vex.d.ts.map +1 -0
  545. package/dist/security/index.d.ts +21 -0
  546. package/dist/security/index.d.ts.map +1 -0
  547. package/dist/security/integrator.d.ts +63 -0
  548. package/dist/security/integrator.d.ts.map +1 -0
  549. package/dist/security/license.d.ts +33 -0
  550. package/dist/security/license.d.ts.map +1 -0
  551. package/dist/security/manifest/adapter.d.ts +92 -0
  552. package/dist/security/manifest/adapter.d.ts.map +1 -0
  553. package/dist/security/manifest/parser.d.ts +73 -0
  554. package/dist/security/manifest/parser.d.ts.map +1 -0
  555. package/dist/security/manifest/plugins/cargo.d.ts +11 -0
  556. package/dist/security/manifest/plugins/cargo.d.ts.map +1 -0
  557. package/dist/security/manifest/plugins/composer.d.ts +11 -0
  558. package/dist/security/manifest/plugins/composer.d.ts.map +1 -0
  559. package/dist/security/manifest/plugins/go.d.ts +12 -0
  560. package/dist/security/manifest/plugins/go.d.ts.map +1 -0
  561. package/dist/security/manifest/plugins/gradle.d.ts +12 -0
  562. package/dist/security/manifest/plugins/gradle.d.ts.map +1 -0
  563. package/dist/security/manifest/plugins/hex.d.ts +11 -0
  564. package/dist/security/manifest/plugins/hex.d.ts.map +1 -0
  565. package/dist/security/manifest/plugins/maven.d.ts +11 -0
  566. package/dist/security/manifest/plugins/maven.d.ts.map +1 -0
  567. package/dist/security/manifest/plugins/npm.d.ts +11 -0
  568. package/dist/security/manifest/plugins/npm.d.ts.map +1 -0
  569. package/dist/security/manifest/plugins/nuget.d.ts +12 -0
  570. package/dist/security/manifest/plugins/nuget.d.ts.map +1 -0
  571. package/dist/security/manifest/plugins/pip.d.ts +11 -0
  572. package/dist/security/manifest/plugins/pip.d.ts.map +1 -0
  573. package/dist/security/manifest/plugins/pubspec.d.ts +11 -0
  574. package/dist/security/manifest/plugins/pubspec.d.ts.map +1 -0
  575. package/dist/security/manifest/plugins/pyproject.d.ts +3 -0
  576. package/dist/security/manifest/plugins/pyproject.d.ts.map +1 -0
  577. package/dist/security/manifest/plugins/rubygems.d.ts +11 -0
  578. package/dist/security/manifest/plugins/rubygems.d.ts.map +1 -0
  579. package/dist/security/manifest/plugins/swift.d.ts +11 -0
  580. package/dist/security/manifest/plugins/swift.d.ts.map +1 -0
  581. package/dist/security/owasp.d.ts +16 -0
  582. package/dist/security/owasp.d.ts.map +1 -0
  583. package/dist/security/pipeline.d.ts +37 -0
  584. package/dist/security/pipeline.d.ts.map +1 -0
  585. package/dist/security/reachability.d.ts +67 -0
  586. package/dist/security/reachability.d.ts.map +1 -0
  587. package/dist/security/remediation.d.ts +51 -0
  588. package/dist/security/remediation.d.ts.map +1 -0
  589. package/dist/security/secrets.d.ts +38 -0
  590. package/dist/security/secrets.d.ts.map +1 -0
  591. package/dist/security/staleness.d.ts +43 -0
  592. package/dist/security/staleness.d.ts.map +1 -0
  593. package/dist/security/supply-chain.d.ts +34 -0
  594. package/dist/security/supply-chain.d.ts.map +1 -0
  595. package/dist/security/suppressions.d.ts +18 -0
  596. package/dist/security/suppressions.d.ts.map +1 -0
  597. package/dist/security/types.d.ts +144 -0
  598. package/dist/security/types.d.ts.map +1 -0
  599. package/dist/security/vuln/client.d.ts +90 -0
  600. package/dist/security/vuln/client.d.ts.map +1 -0
  601. package/dist/security/vuln/client.js.map +2 -2
  602. package/dist/security/vuln/epss-client.d.ts +26 -0
  603. package/dist/security/vuln/epss-client.d.ts.map +1 -0
  604. package/dist/security/vuln/index.d.ts +6 -0
  605. package/dist/security/vuln/index.d.ts.map +1 -0
  606. package/dist/security/vuln/osv-adapter.d.ts +58 -0
  607. package/dist/security/vuln/osv-adapter.d.ts.map +1 -0
  608. package/dist/security/vuln/types.d.ts +29 -0
  609. package/dist/security/vuln/types.d.ts.map +1 -0
  610. package/dist/sync/index.d.ts +4 -2
  611. package/dist/sync/index.d.ts.map +1 -1
  612. package/dist/types.d.ts +10 -4
  613. package/dist/types.d.ts.map +1 -1
  614. package/dist/types.js.map +1 -1
  615. package/dist/vectors/index.d.ts +11 -3
  616. package/dist/vectors/index.d.ts.map +1 -1
  617. package/dist/vectors/qdrant-index.d.ts +10 -3
  618. package/dist/vectors/qdrant-index.d.ts.map +1 -1
  619. package/dist/vectors/typesense-index.d.ts.map +1 -1
  620. package/dist/watchmen/index.js +83 -0
  621. package/dist/watchmen/index.js.map +7 -0
  622. package/dist/watchmen/synthesize.js +475 -0
  623. package/dist/watchmen/synthesize.js.map +7 -0
  624. package/package.json +5 -2
  625. package/dist/security/context-warnings.test.js +0 -300
  626. package/dist/security/context-warnings.test.js.map +0 -7
  627. package/dist/security/export/fix-suggestions.test.js +0 -74
  628. package/dist/security/export/fix-suggestions.test.js.map +0 -7
  629. package/dist/security/export/sbom.test.js +0 -288
  630. package/dist/security/export/sbom.test.js.map +0 -7
  631. package/dist/security/export/serialization.test.js +0 -310
  632. package/dist/security/export/serialization.test.js.map +0 -7
  633. package/dist/security/export/vex.test.js +0 -278
  634. package/dist/security/export/vex.test.js.map +0 -7
  635. package/dist/security/integrator-transitives.test.js +0 -359
  636. package/dist/security/integrator-transitives.test.js.map +0 -7
  637. package/dist/security/integrator.test.js +0 -237
  638. package/dist/security/integrator.test.js.map +0 -7
  639. package/dist/security/manifest/adapter.test.js +0 -272
  640. package/dist/security/manifest/adapter.test.js.map +0 -7
  641. package/dist/security/manifest/parser.test.js +0 -110
  642. package/dist/security/manifest/parser.test.js.map +0 -7
  643. package/dist/security/manifest/plugins/cargo.test.js +0 -304
  644. package/dist/security/manifest/plugins/cargo.test.js.map +0 -7
  645. package/dist/security/manifest/plugins/go.test.js +0 -341
  646. package/dist/security/manifest/plugins/go.test.js.map +0 -7
  647. package/dist/security/manifest/plugins/maven.test.js +0 -389
  648. package/dist/security/manifest/plugins/maven.test.js.map +0 -7
  649. package/dist/security/manifest/plugins/npm.test.js +0 -298
  650. package/dist/security/manifest/plugins/npm.test.js.map +0 -7
  651. package/dist/security/manifest/plugins/pip.test.js +0 -208
  652. package/dist/security/manifest/plugins/pip.test.js.map +0 -7
  653. package/dist/security/reachability.test.js +0 -394
  654. package/dist/security/reachability.test.js.map +0 -7
  655. package/dist/security/vuln/client.test.js +0 -288
  656. package/dist/security/vuln/client.test.js.map +0 -7
  657. package/dist/security/vuln/osv-adapter.test.js +0 -391
  658. package/dist/security/vuln/osv-adapter.test.js.map +0 -7
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Dependency Staleness Checker
3
+ *
4
+ * Queries public package registries (npm, PyPI, crates.io, RubyGems, Packagist)
5
+ * to determine the latest published version and compute a staleness score for
6
+ * each dependency tracked in sec_dependencies.
7
+ *
8
+ * Score formula:
9
+ * score = min(majorVersionsBehind * 0.2, 0.6) // up to 0.6 for version lag
10
+ * + min(monthsSinceLatest / 36, 0.4) // up to 0.4 for time lag
11
+ * score = min(score, 1.0)
12
+ */
13
+ import type { GraphDatabase } from '../db/database';
14
+ export interface StalenessResult {
15
+ packageName: string;
16
+ ecosystem: string;
17
+ resolvedVersion: string;
18
+ latestVersion: string;
19
+ latestPublished: number;
20
+ stalenessScore: number;
21
+ majorVersionsBehind: number;
22
+ monthsSinceLatest: number;
23
+ }
24
+ export declare class StalenessChecker {
25
+ private readonly db;
26
+ constructor(db: GraphDatabase);
27
+ /**
28
+ * Check all dependencies in sec_dependencies that have a supported ecosystem.
29
+ * Returns a summary of checked/stale counts and any errors encountered.
30
+ */
31
+ checkAll(): Promise<{
32
+ checked: number;
33
+ stale: number;
34
+ errors: string[];
35
+ }>;
36
+ /**
37
+ * Check a single dependency by node_id. Returns null if the ecosystem is
38
+ * not supported or the dependency is not found.
39
+ */
40
+ checkOne(nodeId: string): Promise<StalenessResult | null>;
41
+ private _checkRow;
42
+ }
43
+ //# sourceMappingURL=staleness.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"staleness.d.ts","sourceRoot":"","sources":["../../src/security/staleness.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAIpD,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAqJD,qBAAa,gBAAgB;IACf,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAAF,EAAE,EAAE,aAAa;IAE9C;;;OAGG;IACG,QAAQ,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IA+B/E;;;OAGG;IACG,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;YAqBjD,SAAS;CAkDxB"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Supply Chain Health Checker
3
+ *
4
+ * Queries OpenSSF Scorecard and registry APIs to assess the health of
5
+ * dependencies: maintenance activity, maintainer count, package age, and
6
+ * overall supply-chain risk level.
7
+ */
8
+ import type { GraphDatabase } from '../db/database';
9
+ export interface SupplyChainRisk {
10
+ packageName: string;
11
+ ecosystem: string;
12
+ nodeId: string;
13
+ scorecardScore: number | null;
14
+ scorecardChecks: Record<string, number> | null;
15
+ daysSinceLastCommit: number | null;
16
+ isAbandoned: boolean;
17
+ maintainerCount: number | null;
18
+ isSingleMaintainer: boolean;
19
+ publishedAt: string | null;
20
+ isVeryNew: boolean;
21
+ riskLevel: 'critical' | 'high' | 'medium' | 'low' | 'unknown';
22
+ riskReasons: string[];
23
+ }
24
+ export declare class SupplyChainChecker {
25
+ private readonly db;
26
+ constructor(db: GraphDatabase);
27
+ checkAll(): Promise<{
28
+ results: SupplyChainRisk[];
29
+ errors: string[];
30
+ }>;
31
+ checkOne(packageName: string, ecosystem: string): Promise<SupplyChainRisk | null>;
32
+ private _check;
33
+ }
34
+ //# sourceMappingURL=supply-chain.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"supply-chain.d.ts","sourceRoot":"","sources":["../../src/security/supply-chain.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAIpD,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IAEf,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IAE/C,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,WAAW,EAAE,OAAO,CAAC;IACrB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,kBAAkB,EAAE,OAAO,CAAC;IAE5B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,OAAO,CAAC;IAEnB,SAAS,EAAE,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,GAAG,SAAS,CAAC;IAC9D,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAuQD,qBAAa,kBAAkB;IACjB,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAAF,EAAE,EAAE,aAAa;IAExC,QAAQ,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,eAAe,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IA2BrE,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;YAUzE,MAAM;CAgErB"}
@@ -0,0 +1,18 @@
1
+ export interface Suppression {
2
+ cveId: string;
3
+ reason?: string;
4
+ suppressedAt: string;
5
+ expiresAt?: string;
6
+ }
7
+ export declare class SuppressionManager {
8
+ private readonly projectRoot;
9
+ constructor(projectRoot: string);
10
+ private get filePath();
11
+ load(): Suppression[];
12
+ save(suppressions: Suppression[]): void;
13
+ add(cveId: string, reason?: string, expiresAt?: string): void;
14
+ remove(cveId: string): boolean;
15
+ isSuppressed(cveId: string): boolean;
16
+ getActive(): Suppression[];
17
+ }
18
+ //# sourceMappingURL=suppressions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"suppressions.d.ts","sourceRoot":"","sources":["../../src/security/suppressions.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,kBAAkB;IACjB,OAAO,CAAC,QAAQ,CAAC,WAAW;gBAAX,WAAW,EAAE,MAAM;IAEhD,OAAO,KAAK,QAAQ,GAEnB;IAED,IAAI,IAAI,WAAW,EAAE;IA2BrB,IAAI,CAAC,YAAY,EAAE,WAAW,EAAE,GAAG,IAAI;IAQvC,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI;IAoB7D,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAS9B,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAIpC,SAAS,IAAI,WAAW,EAAE;CAG3B"}
@@ -0,0 +1,144 @@
1
+ /**
2
+ * KiroGraph-Sec Type Definitions
3
+ *
4
+ * Interfaces for the security analysis module including manifest parsing,
5
+ * vulnerability detection, reachability analysis, and CycloneDX export.
6
+ */
7
+ export interface ParsedDependency {
8
+ name: string;
9
+ declaredConstraint: string;
10
+ resolvedVersion?: string;
11
+ scope: 'production' | 'development' | 'optional';
12
+ ecosystem: string;
13
+ sourceManifest: string;
14
+ license?: string;
15
+ }
16
+ export interface ManifestParseResult {
17
+ dependenciesCreated: number;
18
+ manifestsParsed: number;
19
+ warnings: Array<{
20
+ file: string;
21
+ line?: number;
22
+ message: string;
23
+ }>;
24
+ errors: Array<{
25
+ file: string;
26
+ message: string;
27
+ }>;
28
+ }
29
+ export interface IntegrationResult {
30
+ importsEdgesCreated: number;
31
+ referencesEdgesCreated: number;
32
+ }
33
+ export interface TransitiveResult {
34
+ dependsOnEdgesCreated: number;
35
+ incompleteNodes: string[];
36
+ }
37
+ export interface CleanupResult {
38
+ nodesRemoved: number;
39
+ edgesRemoved: number;
40
+ }
41
+ export interface CVERecord {
42
+ id: string;
43
+ severity: number;
44
+ affectedVersionRanges: VersionRange[];
45
+ fixedVersion?: string;
46
+ summary: string;
47
+ }
48
+ export interface VersionRange {
49
+ introduced?: string;
50
+ fixed?: string;
51
+ lastAffected?: string;
52
+ }
53
+ export interface EnrichmentResult {
54
+ vulnerabilitiesFound: number;
55
+ dependenciesChecked: number;
56
+ errors: Array<{
57
+ dependency: string;
58
+ database: string;
59
+ error: string;
60
+ }>;
61
+ staleNodes: string[];
62
+ }
63
+ export type ReachabilityVerdict = 'affected' | 'not_affected' | 'under_investigation';
64
+ export interface ReachabilityPath {
65
+ entryPoint: string;
66
+ path: string[];
67
+ }
68
+ export interface ReachabilityResult {
69
+ verdict: ReachabilityVerdict;
70
+ paths: ReachabilityPath[];
71
+ unresolvedSymbols: string[];
72
+ reachingEntryPointCount: number;
73
+ }
74
+ export interface ImpactSummary {
75
+ affectedLayers: string[];
76
+ affectedEntryPoints: string[];
77
+ distinctPathCount: number;
78
+ }
79
+ export interface SecurityResult {
80
+ manifestsDiscovered: number;
81
+ dependenciesCreated: number;
82
+ vulnerabilitiesFound: number;
83
+ affectedCount: number;
84
+ notAffectedCount: number;
85
+ underInvestigationCount: number;
86
+ duration: number;
87
+ }
88
+ export interface SBOMMetadata {
89
+ toolName: string;
90
+ toolVersion: string;
91
+ timestamp: string;
92
+ projectName: string;
93
+ }
94
+ export interface CycloneDXSBOM {
95
+ bomFormat: 'CycloneDX';
96
+ specVersion: '1.5';
97
+ version: number;
98
+ metadata: Record<string, unknown>;
99
+ components: CycloneDXComponent[];
100
+ dependencies: CycloneDXDependencyEntry[];
101
+ }
102
+ export interface CycloneDXComponent {
103
+ type: 'library';
104
+ name: string;
105
+ version: string;
106
+ purl: string;
107
+ scope?: 'required' | 'optional';
108
+ properties?: Array<{
109
+ name: string;
110
+ value: string;
111
+ }>;
112
+ }
113
+ export interface CycloneDXDependencyEntry {
114
+ ref: string;
115
+ dependsOn?: string[];
116
+ }
117
+ export interface CycloneDXVEX {
118
+ bomFormat: 'CycloneDX';
119
+ specVersion: '1.5';
120
+ version: number;
121
+ metadata: Record<string, unknown>;
122
+ vulnerabilities: CycloneDXVulnerability[];
123
+ }
124
+ export interface CycloneDXVulnerability {
125
+ id: string;
126
+ source?: {
127
+ name: string;
128
+ url?: string;
129
+ };
130
+ ratings?: Array<{
131
+ score: number;
132
+ severity?: string;
133
+ method?: string;
134
+ }>;
135
+ analysis?: {
136
+ state: 'affected' | 'not_affected' | 'under_investigation';
137
+ justification?: string;
138
+ detail?: string;
139
+ };
140
+ affects?: Array<{
141
+ ref: string;
142
+ }>;
143
+ }
144
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/security/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * VulnerabilityDatabaseClient
3
+ *
4
+ * Orchestrates vulnerability enrichment by querying configured databases,
5
+ * merging and deduplicating results by CVE identifier, creating Vulnerability_Nodes
6
+ * linked to affected Dependency_Nodes, and handling unreachable databases gracefully.
7
+ *
8
+ * Requirements: 3.1, 3.2, 3.3, 3.4, 3.5, 3.7
9
+ */
10
+ import type { GraphDatabase } from '../../db/database';
11
+ import type { CVERecord, EnrichmentResult } from '../types';
12
+ import type { VulnDatabaseAdapter } from './types';
13
+ /**
14
+ * Compute a combined risk score (0.0–10.0) for a vulnerability.
15
+ *
16
+ * Formula:
17
+ * risk = reachability_factor × (0.4 × cvss_normalized + 0.6 × epss) × staleness_bonus
18
+ * scaled to 0–10: min(risk × 10, 10.0)
19
+ *
20
+ * @param cvss - CVSS base score (0.0–10.0), null treated as 5.0
21
+ * @param epss - EPSS exploitation probability (0.0–1.0), null treated as 0.0
22
+ * @param verdict - Reachability verdict or null/undefined
23
+ * @param staleness - Dependency staleness score (0.0–1.0), null treated as 0.0
24
+ */
25
+ export declare function computeRiskScore(cvss: number | null | undefined, epss: number | null | undefined, verdict: string | null | undefined, staleness: number | null | undefined): number;
26
+ export declare class VulnerabilityDatabaseClient {
27
+ private readonly adapters;
28
+ private readonly db;
29
+ private readonly timeoutMs;
30
+ constructor(adapters: VulnDatabaseAdapter[], db: GraphDatabase, timeoutMs?: number);
31
+ /**
32
+ * Enrich all Dependency_Nodes with vulnerability data.
33
+ *
34
+ * Uses batch queries (up to 1000 per HTTP request) when the adapter supports
35
+ * `queryBatch`. Falls back to sequential single queries per dependency if batch
36
+ * is unavailable or fails. Results are deduplicated by CVE ID across adapters.
37
+ */
38
+ enrichAll(): Promise<EnrichmentResult>;
39
+ /**
40
+ * Fetch EPSS scores for all stored vulnerabilities and update the database.
41
+ */
42
+ private enrichEpss;
43
+ /**
44
+ * Compute and persist combined risk scores for all stored vulnerabilities.
45
+ * Called after EPSS enrichment so epss_score values are up to date.
46
+ */
47
+ private computeRiskScores;
48
+ /**
49
+ * Batch enrichment path: groups deps into chunks of BATCH_CHUNK_SIZE and sends
50
+ * one HTTP request per chunk. Falls back to sequential on batch failure.
51
+ */
52
+ private enrichAllBatch;
53
+ /**
54
+ * Sequential enrichment path: queries one dependency at a time.
55
+ * Used when the adapter does not support queryBatch, or as a fallback.
56
+ */
57
+ private enrichAllSequential;
58
+ /**
59
+ * Enrich a single Dependency_Node with vulnerability data.
60
+ *
61
+ * @param dependencyNodeId - The node ID of the dependency to enrich
62
+ * @returns Array of CVE records found for this dependency
63
+ */
64
+ enrichOne(dependencyNodeId: string): Promise<CVERecord[]>;
65
+ /**
66
+ * Query a set of adapters for a single dependency.
67
+ * Handles timeouts and unreachable databases gracefully.
68
+ * Defaults to all configured adapters when adapterList is omitted.
69
+ */
70
+ private queryAdaptersForDependency;
71
+ /**
72
+ * Mark a dependency node as having stale vulnerability data.
73
+ * Retains cached data but sets the stale flag with timestamp.
74
+ */
75
+ private markDependencyStale;
76
+ /**
77
+ * Deduplicate CVE records by their ID.
78
+ * When the same CVE is reported by multiple databases, keep the first occurrence.
79
+ */
80
+ private deduplicateByCveId;
81
+ /**
82
+ * Create or update a Vulnerability_Node and link it to the affected dependency.
83
+ *
84
+ * - Creates a node in `nodes` table with kind='vulnerability', ID format `vuln:<cve_id>`
85
+ * - Inserts a row in `sec_vulnerabilities` with CVE metadata
86
+ * - Creates a `has_vulnerability` edge from the Dependency_Node to the Vulnerability_Node
87
+ */
88
+ private upsertVulnerabilityNode;
89
+ }
90
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/security/vuln/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5D,OAAO,KAAK,EAAE,mBAAmB,EAAc,MAAM,SAAS,CAAC;AAM/D;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAC/B,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAC/B,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAClC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GACnC,MAAM,CAoBR;AAaD,qBAAa,2BAA2B;IACtC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAwB;IACjD,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAgB;IACnC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAGjC,QAAQ,EAAE,mBAAmB,EAAE,EAC/B,EAAE,EAAE,aAAa,EACjB,SAAS,GAAE,MAAc;IAO3B;;;;;;OAMG;IACG,SAAS,IAAI,OAAO,CAAC,gBAAgB,CAAC;IA4C5C;;OAEG;YACW,UAAU;IA+BxB;;;OAGG;YACW,iBAAiB;IAsB/B;;;OAGG;YACW,cAAc;IA4C5B;;;OAGG;YACW,mBAAmB;IAkBjC;;;;;OAKG;IACG,SAAS,CAAC,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAiD/D;;;;OAIG;YACW,0BAA0B;IA6CxC;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAoB3B;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAU1B;;;;;;OAMG;IACH,OAAO,CAAC,uBAAuB;CAuDhC"}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/security/vuln/client.ts"],
4
- "sourcesContent": ["/**\n * VulnerabilityDatabaseClient\n *\n * Orchestrates vulnerability enrichment by querying configured databases,\n * merging and deduplicating results by CVE identifier, creating Vulnerability_Nodes\n * linked to affected Dependency_Nodes, and handling unreachable databases gracefully.\n *\n * Requirements: 3.1, 3.2, 3.3, 3.4, 3.5, 3.7\n */\n\nimport type { GraphDatabase } from '../../db/database';\nimport type { Edge } from '../../types';\nimport type { CVERecord, EnrichmentResult } from '../types';\nimport type { VulnDatabaseAdapter, BatchQuery } from './types';\nimport { logError, logWarn } from '../../errors';\nimport { EpssClient } from './epss-client';\n\nconst BATCH_CHUNK_SIZE = 1000;\n\n/**\n * Compute a combined risk score (0.0\u201310.0) for a vulnerability.\n *\n * Formula:\n * risk = reachability_factor \u00D7 (0.4 \u00D7 cvss_normalized + 0.6 \u00D7 epss) \u00D7 staleness_bonus\n * scaled to 0\u201310: min(risk \u00D7 10, 10.0)\n *\n * @param cvss - CVSS base score (0.0\u201310.0), null treated as 5.0\n * @param epss - EPSS exploitation probability (0.0\u20131.0), null treated as 0.0\n * @param verdict - Reachability verdict or null/undefined\n * @param staleness - Dependency staleness score (0.0\u20131.0), null treated as 0.0\n */\nexport function computeRiskScore(\n cvss: number | null | undefined,\n epss: number | null | undefined,\n verdict: string | null | undefined,\n staleness: number | null | undefined,\n): number {\n const cvssNormalized = (cvss ?? 5.0) / 10.0;\n const epssValue = epss ?? 0.0;\n\n let reachabilityFactor: number;\n if (verdict === 'affected') {\n reachabilityFactor = 1.0;\n } else if (verdict === 'under_investigation') {\n reachabilityFactor = 0.5;\n } else if (verdict === 'not_affected') {\n reachabilityFactor = 0.1;\n } else {\n // no verdict\n reachabilityFactor = 0.3;\n }\n\n const stalenessBonus = 1.0 + ((staleness ?? 0) * 0.2);\n\n const raw = reachabilityFactor * (0.4 * cvssNormalized + 0.6 * epssValue) * stalenessBonus;\n return Math.min(raw * 10, 10.0);\n}\n\n/**\n * Dependency row from sec_dependencies table.\n */\ninterface DependencyRow {\n node_id: string;\n ecosystem: string;\n package_name: string;\n resolved_version: string | null;\n declared_constraint: string;\n}\n\nexport class VulnerabilityDatabaseClient {\n private readonly adapters: VulnDatabaseAdapter[];\n private readonly db: GraphDatabase;\n private readonly timeoutMs: number;\n\n constructor(\n adapters: VulnDatabaseAdapter[],\n db: GraphDatabase,\n timeoutMs: number = 30000,\n ) {\n this.adapters = adapters;\n this.db = db;\n this.timeoutMs = timeoutMs;\n }\n\n /**\n * Enrich all Dependency_Nodes with vulnerability data.\n *\n * Uses batch queries (up to 1000 per HTTP request) when the adapter supports\n * `queryBatch`. Falls back to sequential single queries per dependency if batch\n * is unavailable or fails. Results are deduplicated by CVE ID across adapters.\n */\n async enrichAll(): Promise<EnrichmentResult> {\n const rawDb = this.db.getRawDb();\n const result: EnrichmentResult = {\n vulnerabilitiesFound: 0,\n dependenciesChecked: 0,\n errors: [],\n staleNodes: [],\n };\n\n const depRows: DependencyRow[] = rawDb.all(\n `SELECT node_id, ecosystem, package_name, resolved_version, declared_constraint\n FROM sec_dependencies`,\n );\n\n // Filter out deps with no usable version\n const queryableDeps = depRows.filter(d => d.resolved_version || d.declared_constraint);\n\n for (const adapter of this.adapters) {\n if (adapter.queryBatch) {\n await this.enrichAllBatch(adapter, queryableDeps, result);\n } else {\n await this.enrichAllSequential(adapter, queryableDeps, result);\n }\n }\n\n // Record lastVulnCheck for all queried deps (do once, after all adapters)\n const now = Date.now();\n for (const dep of queryableDeps) {\n rawDb.run(\n `UPDATE sec_dependencies SET last_vuln_check = ? WHERE node_id = ?`,\n [now, dep.node_id],\n );\n }\n result.dependenciesChecked = queryableDeps.length;\n\n // Enrich stored vulnerabilities with EPSS scores\n await this.enrichEpss(rawDb);\n\n // Compute combined risk scores after all enrichment is done\n await this.computeRiskScores(rawDb);\n\n return result;\n }\n\n /**\n * Fetch EPSS scores for all stored vulnerabilities and update the database.\n */\n private async enrichEpss(rawDb: any): Promise<void> {\n try {\n const cveRows: Array<{ cve_id: string }> = rawDb.all(\n `SELECT cve_id FROM sec_vulnerabilities`,\n );\n\n if (cveRows.length === 0) {\n return;\n }\n\n const cveIds = cveRows.map(r => r.cve_id);\n const epssClient = new EpssClient();\n const scores = await epssClient.fetchScores(cveIds);\n\n if (scores.size === 0) {\n return;\n }\n\n const fetchedAt = Date.now();\n for (const [cveId, { score, percentile }] of scores) {\n rawDb.run(\n `UPDATE sec_vulnerabilities SET epss_score = ?, epss_percentile = ?, epss_fetched_at = ? WHERE cve_id = ?`,\n [score, percentile, fetchedAt, cveId],\n );\n }\n } catch (error: unknown) {\n const msg = error instanceof Error ? error.message : String(error);\n logWarn(`[sec:epss] EPSS enrichment failed (non-critical): ${msg}`);\n }\n }\n\n /**\n * Compute and persist combined risk scores for all stored vulnerabilities.\n * Called after EPSS enrichment so epss_score values are up to date.\n */\n private async computeRiskScores(rawDb: any): Promise<void> {\n const rows: Array<{\n node_id: string;\n severity_score: number | null;\n epss_score: number | null;\n verdict: string | null;\n staleness_score: number | null;\n }> = rawDb.all(`\n SELECT v.node_id, v.severity_score, v.epss_score,\n r.verdict,\n d.staleness_score\n FROM sec_vulnerabilities v\n LEFT JOIN edges e ON e.target = v.node_id AND e.kind = 'has_vulnerability'\n LEFT JOIN sec_dependencies d ON d.node_id = e.source\n LEFT JOIN sec_reachability r ON r.vulnerability_node_id = v.node_id\n `);\n for (const row of rows) {\n const score = computeRiskScore(row.severity_score, row.epss_score, row.verdict, row.staleness_score);\n rawDb.run(`UPDATE sec_vulnerabilities SET risk_score = ? WHERE node_id = ?`, [score, row.node_id]);\n }\n }\n\n /**\n * Batch enrichment path: groups deps into chunks of BATCH_CHUNK_SIZE and sends\n * one HTTP request per chunk. Falls back to sequential on batch failure.\n */\n private async enrichAllBatch(\n adapter: VulnDatabaseAdapter & Required<Pick<VulnDatabaseAdapter, 'queryBatch'>>,\n deps: DependencyRow[],\n result: EnrichmentResult,\n ): Promise<void> {\n const rawDb = this.db.getRawDb();\n\n for (let i = 0; i < deps.length; i += BATCH_CHUNK_SIZE) {\n const chunk = deps.slice(i, i + BATCH_CHUNK_SIZE);\n const queries: BatchQuery[] = chunk.map(dep => ({\n ecosystem: dep.ecosystem,\n packageName: dep.package_name,\n version: dep.resolved_version || dep.declared_constraint,\n }));\n\n let batchResults: Array<CVERecord[]>;\n try {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), this.timeoutMs);\n try {\n batchResults = await adapter.queryBatch(queries, controller.signal);\n } finally {\n clearTimeout(timeout);\n }\n } catch (error: unknown) {\n // Batch failed \u2014 fall back to sequential for this chunk\n const msg = error instanceof Error ? error.message : String(error);\n logWarn(`[sec:vuln] ${adapter.name} batch query failed (${msg}), falling back to sequential for chunk of ${chunk.length}`);\n await this.enrichAllSequential(adapter, chunk, result);\n continue;\n }\n\n for (let j = 0; j < chunk.length; j++) {\n const dep = chunk[j]!;\n const cveRecords = batchResults[j] ?? [];\n const uniqueCves = this.deduplicateByCveId(cveRecords);\n for (const cve of uniqueCves) {\n this.upsertVulnerabilityNode(rawDb, cve, dep.node_id);\n result.vulnerabilitiesFound++;\n }\n }\n }\n }\n\n /**\n * Sequential enrichment path: queries one dependency at a time.\n * Used when the adapter does not support queryBatch, or as a fallback.\n */\n private async enrichAllSequential(\n adapter: VulnDatabaseAdapter,\n deps: DependencyRow[],\n result: EnrichmentResult,\n ): Promise<void> {\n const rawDb = this.db.getRawDb();\n\n for (const dep of deps) {\n const version = dep.resolved_version || dep.declared_constraint;\n const cveRecords = await this.queryAdaptersForDependency(dep, version, result, [adapter]);\n const uniqueCves = this.deduplicateByCveId(cveRecords);\n for (const cve of uniqueCves) {\n this.upsertVulnerabilityNode(rawDb, cve, dep.node_id);\n result.vulnerabilitiesFound++;\n }\n }\n }\n\n /**\n * Enrich a single Dependency_Node with vulnerability data.\n *\n * @param dependencyNodeId - The node ID of the dependency to enrich\n * @returns Array of CVE records found for this dependency\n */\n async enrichOne(dependencyNodeId: string): Promise<CVERecord[]> {\n const rawDb = this.db.getRawDb();\n\n const dep: DependencyRow | undefined = rawDb.get(\n `SELECT node_id, ecosystem, package_name, resolved_version, declared_constraint\n FROM sec_dependencies WHERE node_id = ?`,\n [dependencyNodeId],\n );\n\n if (!dep) {\n return [];\n }\n\n const version = dep.resolved_version || dep.declared_constraint;\n if (!version) {\n return [];\n }\n\n const enrichResult: EnrichmentResult = {\n vulnerabilitiesFound: 0,\n dependenciesChecked: 0,\n errors: [],\n staleNodes: [],\n };\n\n const cveRecords = await this.queryAdaptersForDependency(\n dep,\n version,\n enrichResult,\n );\n\n // Deduplicate by CVE ID\n const uniqueCves = this.deduplicateByCveId(cveRecords);\n\n // Create Vulnerability_Nodes and edges\n for (const cve of uniqueCves) {\n this.upsertVulnerabilityNode(rawDb, cve, dep.node_id);\n }\n\n // Record lastVulnCheck timestamp\n const now = Date.now();\n rawDb.run(\n `UPDATE sec_dependencies SET last_vuln_check = ? WHERE node_id = ?`,\n [now, dep.node_id],\n );\n\n return uniqueCves;\n }\n\n /**\n * Query a set of adapters for a single dependency.\n * Handles timeouts and unreachable databases gracefully.\n * Defaults to all configured adapters when adapterList is omitted.\n */\n private async queryAdaptersForDependency(\n dep: DependencyRow,\n version: string,\n result: EnrichmentResult,\n adapterList: VulnDatabaseAdapter[] = this.adapters,\n ): Promise<CVERecord[]> {\n const allRecords: CVERecord[] = [];\n\n for (const adapter of adapterList) {\n try {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), this.timeoutMs);\n\n try {\n const records = await adapter.query(\n dep.ecosystem,\n dep.package_name,\n version,\n controller.signal,\n );\n allRecords.push(...records);\n } finally {\n clearTimeout(timeout);\n }\n } catch (error: unknown) {\n // Handle unreachable database (Requirement 3.5)\n const errorMessage = error instanceof Error ? error.message : String(error);\n logError(\n `[sec:vuln] Failed to query ${adapter.name} for ${dep.package_name}@${version}: ${errorMessage}`,\n );\n\n result.errors.push({\n dependency: dep.package_name,\n database: adapter.name,\n error: errorMessage,\n });\n\n // Set vulnDataStale flag on the dependency node\n this.markDependencyStale(dep.node_id, result);\n }\n }\n\n return allRecords;\n }\n\n /**\n * Mark a dependency node as having stale vulnerability data.\n * Retains cached data but sets the stale flag with timestamp.\n */\n private markDependencyStale(nodeId: string, result: EnrichmentResult): void {\n const rawDb = this.db.getRawDb();\n const now = Date.now();\n\n rawDb.run(\n `UPDATE sec_dependencies\n SET vuln_data_stale = 1, vuln_data_stale_since = ?\n WHERE node_id = ?`,\n [now, nodeId],\n );\n\n if (!result.staleNodes.includes(nodeId)) {\n result.staleNodes.push(nodeId);\n }\n\n logWarn(\n `[sec:vuln] Vulnerability data marked stale for dependency node ${nodeId}`,\n );\n }\n\n /**\n * Deduplicate CVE records by their ID.\n * When the same CVE is reported by multiple databases, keep the first occurrence.\n */\n private deduplicateByCveId(records: CVERecord[]): CVERecord[] {\n const seen = new Map<string, CVERecord>();\n for (const record of records) {\n if (!seen.has(record.id)) {\n seen.set(record.id, record);\n }\n }\n return [...seen.values()];\n }\n\n /**\n * Create or update a Vulnerability_Node and link it to the affected dependency.\n *\n * - Creates a node in `nodes` table with kind='vulnerability', ID format `vuln:<cve_id>`\n * - Inserts a row in `sec_vulnerabilities` with CVE metadata\n * - Creates a `has_vulnerability` edge from the Dependency_Node to the Vulnerability_Node\n */\n private upsertVulnerabilityNode(\n rawDb: any,\n cve: CVERecord,\n dependencyNodeId: string,\n ): void {\n const vulnNodeId = `vuln:${cve.id}`;\n const now = Date.now();\n\n // Truncate summary to 500 characters (Requirement 3.3)\n const summary = cve.summary.length > 500\n ? cve.summary.slice(0, 500)\n : cve.summary;\n\n // Determine source database from the first adapter that returned this CVE\n // (in practice, the adapter name is not stored on CVERecord, so we use\n // the first configured adapter's name as the source)\n const sourceDatabase = this.adapters.length > 0 ? this.adapters[0].name : 'unknown';\n\n // Upsert into nodes table\n rawDb.run(\n `INSERT OR REPLACE INTO nodes\n (id, kind, name, qualified_name, file_path, language,\n start_line, end_line, start_column, end_column,\n is_exported, is_async, is_static, is_abstract, updated_at)\n VALUES (?, 'vulnerability', ?, ?, '', 'unknown', 0, 0, 0, 0, 0, 0, 0, 0, ?)`,\n [vulnNodeId, cve.id, cve.id, now],\n );\n\n // Upsert into sec_vulnerabilities table\n const affectedRangesJson = JSON.stringify(cve.affectedVersionRanges);\n rawDb.run(\n `INSERT OR REPLACE INTO sec_vulnerabilities\n (node_id, cve_id, severity_score, affected_ranges, fixed_version, summary, source_database)\n VALUES (?, ?, ?, ?, ?, ?, ?)`,\n [\n vulnNodeId,\n cve.id,\n cve.severity,\n affectedRangesJson,\n cve.fixedVersion ?? null,\n summary,\n sourceDatabase,\n ],\n );\n\n // Create has_vulnerability edge from Dependency_Node to Vulnerability_Node\n const edge: Edge = {\n source: dependencyNodeId,\n target: vulnNodeId,\n kind: 'has_vulnerability',\n confidence: 'extracted',\n confidenceScore: 1.0,\n };\n this.db.insertEdge(edge);\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * VulnerabilityDatabaseClient\n *\n * Orchestrates vulnerability enrichment by querying configured databases,\n * merging and deduplicating results by CVE identifier, creating Vulnerability_Nodes\n * linked to affected Dependency_Nodes, and handling unreachable databases gracefully.\n *\n * Requirements: 3.1, 3.2, 3.3, 3.4, 3.5, 3.7\n */\n\nimport type { GraphDatabase } from '../../db/database';\nimport type { Edge } from '../../types';\nimport type { CVERecord, EnrichmentResult } from '../types';\nimport type { VulnDatabaseAdapter, BatchQuery } from './types';\nimport { logError, logWarn } from '../../errors';\nimport { EpssClient } from './epss-client';\n\nconst BATCH_CHUNK_SIZE = 1000;\n\n/**\n * Compute a combined risk score (0.0\u201310.0) for a vulnerability.\n *\n * Formula:\n * risk = reachability_factor \u00D7 (0.4 \u00D7 cvss_normalized + 0.6 \u00D7 epss) \u00D7 staleness_bonus\n * scaled to 0\u201310: min(risk \u00D7 10, 10.0)\n *\n * @param cvss - CVSS base score (0.0\u201310.0), null treated as 5.0\n * @param epss - EPSS exploitation probability (0.0\u20131.0), null treated as 0.0\n * @param verdict - Reachability verdict or null/undefined\n * @param staleness - Dependency staleness score (0.0\u20131.0), null treated as 0.0\n */\nexport function computeRiskScore(\n cvss: number | null | undefined,\n epss: number | null | undefined,\n verdict: string | null | undefined,\n staleness: number | null | undefined,\n): number {\n const cvssNormalized = (cvss ?? 5.0) / 10.0;\n const epssValue = epss ?? 0.0;\n\n let reachabilityFactor: number;\n if (verdict === 'affected') {\n reachabilityFactor = 1.0;\n } else if (verdict === 'under_investigation') {\n reachabilityFactor = 0.5;\n } else if (verdict === 'not_affected') {\n reachabilityFactor = 0.1;\n } else {\n // no verdict\n reachabilityFactor = 0.3;\n }\n\n const stalenessBonus = 1.0 + ((staleness ?? 0) * 0.2);\n\n const raw = reachabilityFactor * (0.4 * cvssNormalized + 0.6 * epssValue) * stalenessBonus;\n return Math.min(raw * 10, 10.0);\n}\n\n/**\n * Dependency row from sec_dependencies table.\n */\ninterface DependencyRow {\n node_id: string;\n ecosystem: string;\n package_name: string;\n resolved_version: string | null;\n declared_constraint: string;\n}\n\nexport class VulnerabilityDatabaseClient {\n private readonly adapters: VulnDatabaseAdapter[];\n private readonly db: GraphDatabase;\n private readonly timeoutMs: number;\n\n constructor(\n adapters: VulnDatabaseAdapter[],\n db: GraphDatabase,\n timeoutMs: number = 30000,\n ) {\n this.adapters = adapters;\n this.db = db;\n this.timeoutMs = timeoutMs;\n }\n\n /**\n * Enrich all Dependency_Nodes with vulnerability data.\n *\n * Uses batch queries (up to 1000 per HTTP request) when the adapter supports\n * `queryBatch`. Falls back to sequential single queries per dependency if batch\n * is unavailable or fails. Results are deduplicated by CVE ID across adapters.\n */\n async enrichAll(): Promise<EnrichmentResult> {\n const rawDb = this.db.getRawDb();\n const result: EnrichmentResult = {\n vulnerabilitiesFound: 0,\n dependenciesChecked: 0,\n errors: [],\n staleNodes: [],\n };\n\n const depRows: DependencyRow[] = rawDb.all(\n `SELECT node_id, ecosystem, package_name, resolved_version, declared_constraint\n FROM sec_dependencies`,\n );\n\n // Filter out deps with no usable version\n const queryableDeps = depRows.filter(d => d.resolved_version || d.declared_constraint);\n\n for (const adapter of this.adapters) {\n if (adapter.queryBatch) {\n await this.enrichAllBatch(adapter as typeof adapter & Required<Pick<typeof adapter, 'queryBatch'>>, queryableDeps, result);\n } else {\n await this.enrichAllSequential(adapter, queryableDeps, result);\n }\n }\n\n // Record lastVulnCheck for all queried deps (do once, after all adapters)\n const now = Date.now();\n for (const dep of queryableDeps) {\n rawDb.run(\n `UPDATE sec_dependencies SET last_vuln_check = ? WHERE node_id = ?`,\n [now, dep.node_id],\n );\n }\n result.dependenciesChecked = queryableDeps.length;\n\n // Enrich stored vulnerabilities with EPSS scores\n await this.enrichEpss(rawDb);\n\n // Compute combined risk scores after all enrichment is done\n await this.computeRiskScores(rawDb);\n\n return result;\n }\n\n /**\n * Fetch EPSS scores for all stored vulnerabilities and update the database.\n */\n private async enrichEpss(rawDb: any): Promise<void> {\n try {\n const cveRows: Array<{ cve_id: string }> = rawDb.all(\n `SELECT cve_id FROM sec_vulnerabilities`,\n );\n\n if (cveRows.length === 0) {\n return;\n }\n\n const cveIds = cveRows.map(r => r.cve_id);\n const epssClient = new EpssClient();\n const scores = await epssClient.fetchScores(cveIds);\n\n if (scores.size === 0) {\n return;\n }\n\n const fetchedAt = Date.now();\n for (const [cveId, { score, percentile }] of scores) {\n rawDb.run(\n `UPDATE sec_vulnerabilities SET epss_score = ?, epss_percentile = ?, epss_fetched_at = ? WHERE cve_id = ?`,\n [score, percentile, fetchedAt, cveId],\n );\n }\n } catch (error: unknown) {\n const msg = error instanceof Error ? error.message : String(error);\n logWarn(`[sec:epss] EPSS enrichment failed (non-critical): ${msg}`);\n }\n }\n\n /**\n * Compute and persist combined risk scores for all stored vulnerabilities.\n * Called after EPSS enrichment so epss_score values are up to date.\n */\n private async computeRiskScores(rawDb: any): Promise<void> {\n const rows: Array<{\n node_id: string;\n severity_score: number | null;\n epss_score: number | null;\n verdict: string | null;\n staleness_score: number | null;\n }> = rawDb.all(`\n SELECT v.node_id, v.severity_score, v.epss_score,\n r.verdict,\n d.staleness_score\n FROM sec_vulnerabilities v\n LEFT JOIN edges e ON e.target = v.node_id AND e.kind = 'has_vulnerability'\n LEFT JOIN sec_dependencies d ON d.node_id = e.source\n LEFT JOIN sec_reachability r ON r.vulnerability_node_id = v.node_id\n `);\n for (const row of rows) {\n const score = computeRiskScore(row.severity_score, row.epss_score, row.verdict, row.staleness_score);\n rawDb.run(`UPDATE sec_vulnerabilities SET risk_score = ? WHERE node_id = ?`, [score, row.node_id]);\n }\n }\n\n /**\n * Batch enrichment path: groups deps into chunks of BATCH_CHUNK_SIZE and sends\n * one HTTP request per chunk. Falls back to sequential on batch failure.\n */\n private async enrichAllBatch(\n adapter: VulnDatabaseAdapter & Required<Pick<VulnDatabaseAdapter, 'queryBatch'>>,\n deps: DependencyRow[],\n result: EnrichmentResult,\n ): Promise<void> {\n const rawDb = this.db.getRawDb();\n\n for (let i = 0; i < deps.length; i += BATCH_CHUNK_SIZE) {\n const chunk = deps.slice(i, i + BATCH_CHUNK_SIZE);\n const queries: BatchQuery[] = chunk.map(dep => ({\n ecosystem: dep.ecosystem,\n packageName: dep.package_name,\n version: dep.resolved_version || dep.declared_constraint,\n }));\n\n let batchResults: Array<CVERecord[]>;\n try {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), this.timeoutMs);\n try {\n batchResults = await adapter.queryBatch(queries, controller.signal);\n } finally {\n clearTimeout(timeout);\n }\n } catch (error: unknown) {\n // Batch failed \u2014 fall back to sequential for this chunk\n const msg = error instanceof Error ? error.message : String(error);\n logWarn(`[sec:vuln] ${adapter.name} batch query failed (${msg}), falling back to sequential for chunk of ${chunk.length}`);\n await this.enrichAllSequential(adapter, chunk, result);\n continue;\n }\n\n for (let j = 0; j < chunk.length; j++) {\n const dep = chunk[j]!;\n const cveRecords = batchResults[j] ?? [];\n const uniqueCves = this.deduplicateByCveId(cveRecords);\n for (const cve of uniqueCves) {\n this.upsertVulnerabilityNode(rawDb, cve, dep.node_id);\n result.vulnerabilitiesFound++;\n }\n }\n }\n }\n\n /**\n * Sequential enrichment path: queries one dependency at a time.\n * Used when the adapter does not support queryBatch, or as a fallback.\n */\n private async enrichAllSequential(\n adapter: VulnDatabaseAdapter,\n deps: DependencyRow[],\n result: EnrichmentResult,\n ): Promise<void> {\n const rawDb = this.db.getRawDb();\n\n for (const dep of deps) {\n const version = dep.resolved_version || dep.declared_constraint;\n const cveRecords = await this.queryAdaptersForDependency(dep, version, result, [adapter]);\n const uniqueCves = this.deduplicateByCveId(cveRecords);\n for (const cve of uniqueCves) {\n this.upsertVulnerabilityNode(rawDb, cve, dep.node_id);\n result.vulnerabilitiesFound++;\n }\n }\n }\n\n /**\n * Enrich a single Dependency_Node with vulnerability data.\n *\n * @param dependencyNodeId - The node ID of the dependency to enrich\n * @returns Array of CVE records found for this dependency\n */\n async enrichOne(dependencyNodeId: string): Promise<CVERecord[]> {\n const rawDb = this.db.getRawDb();\n\n const dep: DependencyRow | undefined = rawDb.get(\n `SELECT node_id, ecosystem, package_name, resolved_version, declared_constraint\n FROM sec_dependencies WHERE node_id = ?`,\n [dependencyNodeId],\n );\n\n if (!dep) {\n return [];\n }\n\n const version = dep.resolved_version || dep.declared_constraint;\n if (!version) {\n return [];\n }\n\n const enrichResult: EnrichmentResult = {\n vulnerabilitiesFound: 0,\n dependenciesChecked: 0,\n errors: [],\n staleNodes: [],\n };\n\n const cveRecords = await this.queryAdaptersForDependency(\n dep,\n version,\n enrichResult,\n );\n\n // Deduplicate by CVE ID\n const uniqueCves = this.deduplicateByCveId(cveRecords);\n\n // Create Vulnerability_Nodes and edges\n for (const cve of uniqueCves) {\n this.upsertVulnerabilityNode(rawDb, cve, dep.node_id);\n }\n\n // Record lastVulnCheck timestamp\n const now = Date.now();\n rawDb.run(\n `UPDATE sec_dependencies SET last_vuln_check = ? WHERE node_id = ?`,\n [now, dep.node_id],\n );\n\n return uniqueCves;\n }\n\n /**\n * Query a set of adapters for a single dependency.\n * Handles timeouts and unreachable databases gracefully.\n * Defaults to all configured adapters when adapterList is omitted.\n */\n private async queryAdaptersForDependency(\n dep: DependencyRow,\n version: string,\n result: EnrichmentResult,\n adapterList: VulnDatabaseAdapter[] = this.adapters,\n ): Promise<CVERecord[]> {\n const allRecords: CVERecord[] = [];\n\n for (const adapter of adapterList) {\n try {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), this.timeoutMs);\n\n try {\n const records = await adapter.query(\n dep.ecosystem,\n dep.package_name,\n version,\n controller.signal,\n );\n allRecords.push(...records);\n } finally {\n clearTimeout(timeout);\n }\n } catch (error: unknown) {\n // Handle unreachable database (Requirement 3.5)\n const errorMessage = error instanceof Error ? error.message : String(error);\n logError(\n `[sec:vuln] Failed to query ${adapter.name} for ${dep.package_name}@${version}: ${errorMessage}`,\n );\n\n result.errors.push({\n dependency: dep.package_name,\n database: adapter.name,\n error: errorMessage,\n });\n\n // Set vulnDataStale flag on the dependency node\n this.markDependencyStale(dep.node_id, result);\n }\n }\n\n return allRecords;\n }\n\n /**\n * Mark a dependency node as having stale vulnerability data.\n * Retains cached data but sets the stale flag with timestamp.\n */\n private markDependencyStale(nodeId: string, result: EnrichmentResult): void {\n const rawDb = this.db.getRawDb();\n const now = Date.now();\n\n rawDb.run(\n `UPDATE sec_dependencies\n SET vuln_data_stale = 1, vuln_data_stale_since = ?\n WHERE node_id = ?`,\n [now, nodeId],\n );\n\n if (!result.staleNodes.includes(nodeId)) {\n result.staleNodes.push(nodeId);\n }\n\n logWarn(\n `[sec:vuln] Vulnerability data marked stale for dependency node ${nodeId}`,\n );\n }\n\n /**\n * Deduplicate CVE records by their ID.\n * When the same CVE is reported by multiple databases, keep the first occurrence.\n */\n private deduplicateByCveId(records: CVERecord[]): CVERecord[] {\n const seen = new Map<string, CVERecord>();\n for (const record of records) {\n if (!seen.has(record.id)) {\n seen.set(record.id, record);\n }\n }\n return [...seen.values()];\n }\n\n /**\n * Create or update a Vulnerability_Node and link it to the affected dependency.\n *\n * - Creates a node in `nodes` table with kind='vulnerability', ID format `vuln:<cve_id>`\n * - Inserts a row in `sec_vulnerabilities` with CVE metadata\n * - Creates a `has_vulnerability` edge from the Dependency_Node to the Vulnerability_Node\n */\n private upsertVulnerabilityNode(\n rawDb: any,\n cve: CVERecord,\n dependencyNodeId: string,\n ): void {\n const vulnNodeId = `vuln:${cve.id}`;\n const now = Date.now();\n\n // Truncate summary to 500 characters (Requirement 3.3)\n const summary = cve.summary.length > 500\n ? cve.summary.slice(0, 500)\n : cve.summary;\n\n // Determine source database from the first adapter that returned this CVE\n // (in practice, the adapter name is not stored on CVERecord, so we use\n // the first configured adapter's name as the source)\n const sourceDatabase = this.adapters.length > 0 ? this.adapters[0].name : 'unknown';\n\n // Upsert into nodes table\n rawDb.run(\n `INSERT OR REPLACE INTO nodes\n (id, kind, name, qualified_name, file_path, language,\n start_line, end_line, start_column, end_column,\n is_exported, is_async, is_static, is_abstract, updated_at)\n VALUES (?, 'vulnerability', ?, ?, '', 'unknown', 0, 0, 0, 0, 0, 0, 0, 0, ?)`,\n [vulnNodeId, cve.id, cve.id, now],\n );\n\n // Upsert into sec_vulnerabilities table\n const affectedRangesJson = JSON.stringify(cve.affectedVersionRanges);\n rawDb.run(\n `INSERT OR REPLACE INTO sec_vulnerabilities\n (node_id, cve_id, severity_score, affected_ranges, fixed_version, summary, source_database)\n VALUES (?, ?, ?, ?, ?, ?, ?)`,\n [\n vulnNodeId,\n cve.id,\n cve.severity,\n affectedRangesJson,\n cve.fixedVersion ?? null,\n summary,\n sourceDatabase,\n ],\n );\n\n // Create has_vulnerability edge from Dependency_Node to Vulnerability_Node\n const edge: Edge = {\n source: dependencyNodeId,\n target: vulnNodeId,\n kind: 'has_vulnerability',\n confidence: 'extracted',\n confidenceScore: 1.0,\n };\n this.db.insertEdge(edge);\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * EPSS (Exploit Prediction Scoring System) Client
3
+ *
4
+ * Fetches exploit prediction scores from the FIRST.org EPSS API for CVE IDs.
5
+ * EPSS is non-critical: on error, an empty map is returned so the caller can
6
+ * continue without scores.
7
+ *
8
+ * API: https://api.first.org/data/v1/epss
9
+ */
10
+ export declare class EpssClient {
11
+ /**
12
+ * Fetch EPSS scores for a list of CVE IDs.
13
+ *
14
+ * CVEs are batched into chunks of 500 per request. Missing CVEs simply do
15
+ * not appear in the response and are omitted from the returned map.
16
+ *
17
+ * @param cveIds - List of CVE identifiers (e.g. ["CVE-2021-44228", ...])
18
+ * @returns Map from CVE ID to { score, percentile } (floats in [0, 1])
19
+ */
20
+ fetchScores(cveIds: string[]): Promise<Map<string, {
21
+ score: number;
22
+ percentile: number;
23
+ }>>;
24
+ private fetchChunk;
25
+ }
26
+ //# sourceMappingURL=epss-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"epss-client.d.ts","sourceRoot":"","sources":["../../../src/security/vuln/epss-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAmBH,qBAAa,UAAU;IACrB;;;;;;;;OAQG;IACG,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;YAwBlF,UAAU;CA2CzB"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Vulnerability database subsystem exports.
3
+ */
4
+ export { VulnerabilityDatabaseClient } from './client';
5
+ export type { VulnDatabaseAdapter } from './types';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/security/vuln/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,2BAA2B,EAAE,MAAM,UAAU,CAAC;AACvD,YAAY,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * OSV API Adapter
3
+ *
4
+ * Queries the OSV (Open Source Vulnerabilities) database for known CVEs
5
+ * affecting project dependencies. Implements the VulnDatabaseAdapter interface.
6
+ */
7
+ import { CVERecord } from '../types';
8
+ import type { VulnDatabaseAdapter, BatchQuery } from './types';
9
+ export type { VulnDatabaseAdapter, BatchQuery };
10
+ export declare class OsvAdapter implements VulnDatabaseAdapter {
11
+ readonly name = "OSV";
12
+ private readonly apiUrl;
13
+ private readonly batchApiUrl;
14
+ private readonly timeoutMs;
15
+ constructor(options?: {
16
+ apiUrl?: string;
17
+ batchApiUrl?: string;
18
+ timeoutMs?: number;
19
+ });
20
+ /**
21
+ * Batch query up to OSV_BATCH_MAX_QUERIES packages in a single HTTP request.
22
+ * Results are returned in the same order as the input queries.
23
+ * Queries for unsupported ecosystems produce empty results without an HTTP call.
24
+ */
25
+ queryBatch(queries: BatchQuery[], signal?: AbortSignal): Promise<Array<CVERecord[]>>;
26
+ query(ecosystem: string, packageName: string, version: string, signal?: AbortSignal): Promise<CVERecord[]>;
27
+ /**
28
+ * Parse the OSV API response into CVERecord objects.
29
+ */
30
+ private parseResponse;
31
+ /**
32
+ * Extract CVE ID from the vulnerability's aliases or use the OSV ID.
33
+ * Prefers CVE-* identifiers from the aliases array.
34
+ */
35
+ private extractCveId;
36
+ /**
37
+ * Extract CVSS v3.1 base score from the severity array.
38
+ * Returns 0 if no CVSS score is available.
39
+ */
40
+ private extractSeverity;
41
+ /**
42
+ * Parse a CVSS vector string or numeric score.
43
+ * CVSS vectors look like: "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"
44
+ * The base score is not directly in the vector — we extract it if it's a plain number,
45
+ * or return null if we can't parse it.
46
+ */
47
+ private parseCvssScore;
48
+ /**
49
+ * Extract affected version ranges and the first fixed version from the vulnerability.
50
+ */
51
+ private extractAffectedRanges;
52
+ /**
53
+ * Extract and truncate the summary from the vulnerability.
54
+ * Prefers the summary field, falls back to details.
55
+ */
56
+ private extractSummary;
57
+ }
58
+ //# sourceMappingURL=osv-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"osv-adapter.d.ts","sourceRoot":"","sources":["../../../src/security/vuln/osv-adapter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAgB,MAAM,UAAU,CAAC;AACnD,OAAO,KAAK,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAI/D,YAAY,EAAE,mBAAmB,EAAE,UAAU,EAAE,CAAC;AAsEhD,qBAAa,UAAW,YAAW,mBAAmB;IACpD,SAAgB,IAAI,SAAS;IAE7B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAEvB,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE;IAMnF;;;;OAIG;IACG,UAAU,CACd,OAAO,EAAE,UAAU,EAAE,EACrB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC;IA6ExB,KAAK,CACT,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,SAAS,EAAE,CAAC;IAkEvB;;OAEG;IACH,OAAO,CAAC,aAAa;IA8BrB;;;OAGG;IACH,OAAO,CAAC,YAAY;IAapB;;;OAGG;IACH,OAAO,CAAC,eAAe;IAyBvB;;;;;OAKG;IACH,OAAO,CAAC,cAAc;IAYtB;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAiD7B;;;OAGG;IACH,OAAO,CAAC,cAAc;CAOvB"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Shared types for the vulnerability database subsystem.
3
+ */
4
+ import type { CVERecord } from '../types';
5
+ /** A single entry in a batch vulnerability query. */
6
+ export interface BatchQuery {
7
+ ecosystem: string;
8
+ packageName: string;
9
+ version: string;
10
+ }
11
+ /**
12
+ * Adapter interface for querying a vulnerability database.
13
+ * Each supported database (OSV, NVD, etc.) implements this interface.
14
+ */
15
+ export interface VulnDatabaseAdapter {
16
+ /** Human-readable name of the database (e.g. "OSV") */
17
+ name: string;
18
+ /**
19
+ * Query for vulnerabilities affecting a specific package version.
20
+ */
21
+ query(ecosystem: string, packageName: string, version: string, signal?: AbortSignal): Promise<CVERecord[]>;
22
+ /**
23
+ * Batch query — results[i] corresponds to queries[i].
24
+ * Implementing this is optional but strongly recommended for performance:
25
+ * a single HTTP request replaces N sequential requests.
26
+ */
27
+ queryBatch?(queries: BatchQuery[], signal?: AbortSignal): Promise<Array<CVERecord[]>>;
28
+ }
29
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/security/vuln/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAE1C,qDAAqD;AACrD,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,KAAK,CACH,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IAExB;;;;OAIG;IACH,UAAU,CAAC,CACT,OAAO,EAAE,UAAU,EAAE,EACrB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;CAChC"}
@@ -16,12 +16,14 @@ export declare function shouldIncludeFile(relPath: string, config: KiroGraphConf
16
16
  export declare function hashContent(content: Buffer | string): string;
17
17
  /**
18
18
  * Returns absolute paths of all indexable files under root.
19
- * Uses git ls-files fast-path when available; falls back to filesystem walk.
19
+ * Handles monorepos with multiple nested git roots by running git ls-files
20
+ * from each sub-repo root independently, then merging results.
21
+ * Falls back to filesystem walk if no git roots found.
20
22
  * Respects AbortSignal.
21
23
  */
22
24
  export declare function scanDirectory(root: string, config: KiroGraphConfig, signal?: AbortSignal): Promise<string[]>;
23
25
  /**
24
- * Classifies git-changed files into added / modified / removed.
26
+ * Classifies git-changed files into added / modified / removed across all nested git roots.
25
27
  * Returns absolute paths. Returns empty arrays if git is unavailable.
26
28
  * Excludes paths whose detected language is 'unknown'.
27
29
  */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sync/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAsFjD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,GAAG,OAAO,CAUnF;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAE5D;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,eAAe,EACvB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,MAAM,EAAE,CAAC,CAwBnB;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,eAAe,GACtB,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAoCrE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sync/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AA+GjD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,GAAG,OAAO,CAUnF;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAE5D;AAED;;;;;;GAMG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,eAAe,EACvB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,MAAM,EAAE,CAAC,CA8BnB;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,eAAe,GACtB,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAmCrE"}