kirograph 0.16.1 → 0.19.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 (365) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +103 -1605
  3. package/dist/architecture/layers/dart.js +112 -0
  4. package/dist/architecture/layers/dart.js.map +7 -0
  5. package/dist/architecture/layers/index.js +3 -1
  6. package/dist/architecture/layers/index.js.map +2 -2
  7. package/dist/bin/banner.js +74 -6
  8. package/dist/bin/banner.js.map +2 -2
  9. package/dist/bin/commands/affected.js +40 -5
  10. package/dist/bin/commands/affected.js.map +2 -2
  11. package/dist/bin/commands/attack-surface.js +157 -0
  12. package/dist/bin/commands/attack-surface.js.map +7 -0
  13. package/dist/bin/commands/benchmark.js +206 -0
  14. package/dist/bin/commands/benchmark.js.map +7 -0
  15. package/dist/bin/commands/budget.js +70 -0
  16. package/dist/bin/commands/budget.js.map +7 -0
  17. package/dist/bin/commands/communities.js +77 -0
  18. package/dist/bin/commands/communities.js.map +7 -0
  19. package/dist/bin/commands/data.js +665 -0
  20. package/dist/bin/commands/data.js.map +7 -0
  21. package/dist/bin/commands/dep-confusion.js +119 -0
  22. package/dist/bin/commands/dep-confusion.js.map +7 -0
  23. package/dist/bin/commands/export.js +304 -10
  24. package/dist/bin/commands/export.js.map +2 -2
  25. package/dist/bin/commands/flows.js +97 -0
  26. package/dist/bin/commands/flows.js.map +7 -0
  27. package/dist/bin/commands/help.js +386 -100
  28. package/dist/bin/commands/help.js.map +2 -2
  29. package/dist/bin/commands/install.js +90 -8
  30. package/dist/bin/commands/install.js.map +2 -2
  31. package/dist/bin/commands/licenses.js +201 -0
  32. package/dist/bin/commands/licenses.js.map +7 -0
  33. package/dist/bin/commands/reachability.js +160 -0
  34. package/dist/bin/commands/reachability.js.map +7 -0
  35. package/dist/bin/commands/read.js +100 -0
  36. package/dist/bin/commands/read.js.map +7 -0
  37. package/dist/bin/commands/refactor.js +116 -0
  38. package/dist/bin/commands/refactor.js.map +7 -0
  39. package/dist/bin/commands/remediation.js +133 -0
  40. package/dist/bin/commands/remediation.js.map +7 -0
  41. package/dist/bin/commands/sbom.js +76 -0
  42. package/dist/bin/commands/sbom.js.map +7 -0
  43. package/dist/bin/commands/security-ci-report.js +267 -0
  44. package/dist/bin/commands/security-ci-report.js.map +7 -0
  45. package/dist/bin/commands/security-export.js +1349 -0
  46. package/dist/bin/commands/security-export.js.map +7 -0
  47. package/dist/bin/commands/security-flows.js +126 -0
  48. package/dist/bin/commands/security-flows.js.map +7 -0
  49. package/dist/bin/commands/security-secrets.js +170 -0
  50. package/dist/bin/commands/security-secrets.js.map +7 -0
  51. package/dist/bin/commands/security.js +193 -0
  52. package/dist/bin/commands/security.js.map +7 -0
  53. package/dist/bin/commands/staleness.js +144 -0
  54. package/dist/bin/commands/staleness.js.map +7 -0
  55. package/dist/bin/commands/status.js +102 -2
  56. package/dist/bin/commands/status.js.map +2 -2
  57. package/dist/bin/commands/supply-chain.js +138 -0
  58. package/dist/bin/commands/supply-chain.js.map +7 -0
  59. package/dist/bin/commands/uninit.js +109 -60
  60. package/dist/bin/commands/uninit.js.map +2 -2
  61. package/dist/bin/commands/vex.js +76 -0
  62. package/dist/bin/commands/vex.js.map +7 -0
  63. package/dist/bin/commands/vuln-suppress.js +95 -0
  64. package/dist/bin/commands/vuln-suppress.js.map +7 -0
  65. package/dist/bin/commands/vulns.js +382 -0
  66. package/dist/bin/commands/vulns.js.map +7 -0
  67. package/dist/bin/installer/auto-detect.js +125 -0
  68. package/dist/bin/installer/auto-detect.js.map +7 -0
  69. package/dist/bin/installer/cli-agent.js +28 -5
  70. package/dist/bin/installer/cli-agent.js.map +2 -2
  71. package/dist/bin/installer/common.js +47 -0
  72. package/dist/bin/installer/common.js.map +2 -2
  73. package/dist/bin/installer/config-prompt.js +39 -1
  74. package/dist/bin/installer/config-prompt.js.map +2 -2
  75. package/dist/bin/installer/detect.js +309 -0
  76. package/dist/bin/installer/detect.js.map +7 -0
  77. package/dist/bin/installer/index.js +36 -1
  78. package/dist/bin/installer/index.js.map +2 -2
  79. package/dist/bin/installer/instructions.js +195 -3
  80. package/dist/bin/installer/instructions.js.map +2 -2
  81. package/dist/bin/installer/steering.js +440 -0
  82. package/dist/bin/installer/steering.js.map +2 -2
  83. package/dist/bin/installer/targets/aider.js +3 -3
  84. package/dist/bin/installer/targets/aider.js.map +2 -2
  85. package/dist/bin/installer/targets/amp.js +3 -3
  86. package/dist/bin/installer/targets/amp.js.map +2 -2
  87. package/dist/bin/installer/targets/antigravity.js +35 -6
  88. package/dist/bin/installer/targets/antigravity.js.map +2 -2
  89. package/dist/bin/installer/targets/augment.js +3 -3
  90. package/dist/bin/installer/targets/augment.js.map +2 -2
  91. package/dist/bin/installer/targets/claude.js +49 -5
  92. package/dist/bin/installer/targets/claude.js.map +2 -2
  93. package/dist/bin/installer/targets/cline.js +32 -6
  94. package/dist/bin/installer/targets/cline.js.map +2 -2
  95. package/dist/bin/installer/targets/codex.js +64 -12
  96. package/dist/bin/installer/targets/codex.js.map +2 -2
  97. package/dist/bin/installer/targets/continue.js +2 -2
  98. package/dist/bin/installer/targets/continue.js.map +2 -2
  99. package/dist/bin/installer/targets/copilot-cli.js +101 -0
  100. package/dist/bin/installer/targets/copilot-cli.js.map +7 -0
  101. package/dist/bin/installer/targets/copilot.js +31 -5
  102. package/dist/bin/installer/targets/copilot.js.map +2 -2
  103. package/dist/bin/installer/targets/cursor.js +4 -4
  104. package/dist/bin/installer/targets/cursor.js.map +2 -2
  105. package/dist/bin/installer/targets/devin.js +2 -2
  106. package/dist/bin/installer/targets/devin.js.map +2 -2
  107. package/dist/bin/installer/targets/gemini-cli.js +2 -2
  108. package/dist/bin/installer/targets/gemini-cli.js.map +2 -2
  109. package/dist/bin/installer/targets/generic.js +2 -14
  110. package/dist/bin/installer/targets/generic.js.map +2 -2
  111. package/dist/bin/installer/targets/goose.js +3 -3
  112. package/dist/bin/installer/targets/goose.js.map +2 -2
  113. package/dist/bin/installer/targets/index.js +250 -0
  114. package/dist/bin/installer/targets/index.js.map +2 -2
  115. package/dist/bin/installer/targets/junie.js +2 -2
  116. package/dist/bin/installer/targets/junie.js.map +2 -2
  117. package/dist/bin/installer/targets/kilo.js +2 -2
  118. package/dist/bin/installer/targets/kilo.js.map +2 -2
  119. package/dist/bin/installer/targets/kiro.js +3 -3
  120. package/dist/bin/installer/targets/kiro.js.map +2 -2
  121. package/dist/bin/installer/targets/opencode.js +2 -2
  122. package/dist/bin/installer/targets/opencode.js.map +2 -2
  123. package/dist/bin/installer/targets/openhands.js +3 -3
  124. package/dist/bin/installer/targets/openhands.js.map +2 -2
  125. package/dist/bin/installer/targets/qoder.js +91 -0
  126. package/dist/bin/installer/targets/qoder.js.map +7 -0
  127. package/dist/bin/installer/targets/qwen.js +96 -0
  128. package/dist/bin/installer/targets/qwen.js.map +7 -0
  129. package/dist/bin/installer/targets/replit.js +3 -3
  130. package/dist/bin/installer/targets/replit.js.map +2 -2
  131. package/dist/bin/installer/targets/roo.js +2 -2
  132. package/dist/bin/installer/targets/roo.js.map +2 -2
  133. package/dist/bin/installer/targets/tabnine.js +3 -3
  134. package/dist/bin/installer/targets/tabnine.js.map +2 -2
  135. package/dist/bin/installer/targets/trae.js +5 -5
  136. package/dist/bin/installer/targets/trae.js.map +2 -2
  137. package/dist/bin/installer/targets/warp.js +2 -2
  138. package/dist/bin/installer/targets/warp.js.map +2 -2
  139. package/dist/bin/installer/targets/windsurf.js +35 -6
  140. package/dist/bin/installer/targets/windsurf.js.map +2 -2
  141. package/dist/bin/kirograph.js +74 -6
  142. package/dist/bin/kirograph.js.map +3 -3
  143. package/dist/bin/progress.js +30 -0
  144. package/dist/bin/progress.js.map +2 -2
  145. package/dist/compression/naive-cost.js +25 -0
  146. package/dist/compression/naive-cost.js.map +2 -2
  147. package/dist/compression/tracker.js +91 -2
  148. package/dist/compression/tracker.js.map +2 -2
  149. package/dist/compression/types.js.map +1 -1
  150. package/dist/config.js +126 -3
  151. package/dist/config.js.map +2 -2
  152. package/dist/core/pipeline.js +92 -4
  153. package/dist/core/pipeline.js.map +2 -2
  154. package/dist/data/filters.js +105 -0
  155. package/dist/data/filters.js.map +7 -0
  156. package/dist/data/indexer.js +225 -0
  157. package/dist/data/indexer.js.map +7 -0
  158. package/dist/data/linker.js +150 -0
  159. package/dist/data/linker.js.map +7 -0
  160. package/dist/data/lint.js +109 -0
  161. package/dist/data/lint.js.map +7 -0
  162. package/dist/data/parsers/csv.js +132 -0
  163. package/dist/data/parsers/csv.js.map +7 -0
  164. package/dist/data/parsers/excel.js +88 -0
  165. package/dist/data/parsers/excel.js.map +7 -0
  166. package/dist/data/parsers/index.js +79 -0
  167. package/dist/data/parsers/index.js.map +7 -0
  168. package/dist/data/parsers/json-array.js +89 -0
  169. package/dist/data/parsers/json-array.js.map +7 -0
  170. package/dist/data/parsers/jsonl.js +84 -0
  171. package/dist/data/parsers/jsonl.js.map +7 -0
  172. package/dist/data/parsers/parquet.js +95 -0
  173. package/dist/data/parsers/parquet.js.map +7 -0
  174. package/dist/data/profiler.js +182 -0
  175. package/dist/data/profiler.js.map +7 -0
  176. package/dist/data/queries.js +512 -0
  177. package/dist/data/queries.js.map +7 -0
  178. package/dist/data/types.js +17 -0
  179. package/dist/data/types.js.map +7 -0
  180. package/dist/db/data-schema.sql +61 -0
  181. package/dist/db/database.js +67 -5
  182. package/dist/db/database.js.map +2 -2
  183. package/dist/db/memory-schema.sql +5 -1
  184. package/dist/db/schema.sql +3 -1
  185. package/dist/db/security-schema.sql +72 -0
  186. package/dist/extraction/extractor.js +81 -0
  187. package/dist/extraction/extractor.js.map +2 -2
  188. package/dist/extraction/grammars.js +32 -8
  189. package/dist/extraction/grammars.js.map +2 -2
  190. package/dist/extraction/languages.js +43 -1
  191. package/dist/extraction/languages.js.map +2 -2
  192. package/dist/extraction/notebook.js +300 -0
  193. package/dist/extraction/notebook.js.map +7 -0
  194. package/dist/extraction/wasm/tree-sitter-astro.wasm +0 -0
  195. package/dist/extraction/wasm/tree-sitter-gdscript.wasm +0 -0
  196. package/dist/extraction/wasm/tree-sitter-julia.wasm +0 -0
  197. package/dist/extraction/wasm/tree-sitter-nix.wasm +0 -0
  198. package/dist/extraction/wasm/tree-sitter-perl.wasm +0 -0
  199. package/dist/extraction/wasm/tree-sitter-powershell.wasm +0 -0
  200. package/dist/extraction/wasm/tree-sitter-r.wasm +0 -0
  201. package/dist/extraction/wasm/tree-sitter-sql.wasm +0 -0
  202. package/dist/extraction/wasm/tree-sitter-verilog.wasm +0 -0
  203. package/dist/frameworks/flutter.js +130 -0
  204. package/dist/frameworks/flutter.js.map +7 -0
  205. package/dist/frameworks/index.js +7 -1
  206. package/dist/frameworks/index.js.map +3 -3
  207. package/dist/graph/communities.js +317 -0
  208. package/dist/graph/communities.js.map +7 -0
  209. package/dist/graph/flows.js +138 -0
  210. package/dist/graph/flows.js.map +7 -0
  211. package/dist/graph/refactor.js +155 -0
  212. package/dist/graph/refactor.js.map +7 -0
  213. package/dist/index.js +1 -1
  214. package/dist/index.js.map +2 -2
  215. package/dist/mcp/cache.js +172 -0
  216. package/dist/mcp/cache.js.map +7 -0
  217. package/dist/mcp/read-modes.js +295 -0
  218. package/dist/mcp/read-modes.js.map +7 -0
  219. package/dist/mcp/server.js +2 -1
  220. package/dist/mcp/server.js.map +2 -2
  221. package/dist/mcp/tool-names.js +29 -1
  222. package/dist/mcp/tool-names.js.map +2 -2
  223. package/dist/mcp/tools.js +1588 -6
  224. package/dist/mcp/tools.js.map +3 -3
  225. package/dist/memory/database.js +32 -2
  226. package/dist/memory/database.js.map +2 -2
  227. package/dist/memory/types.js.map +1 -1
  228. package/dist/resolution/bridges/android-rn.js +298 -0
  229. package/dist/resolution/bridges/android-rn.js.map +7 -0
  230. package/dist/resolution/bridges/expo-modules.js +155 -0
  231. package/dist/resolution/bridges/expo-modules.js.map +7 -0
  232. package/dist/resolution/bridges/flutter-channel.js +385 -0
  233. package/dist/resolution/bridges/flutter-channel.js.map +7 -0
  234. package/dist/resolution/bridges/index.js +80 -0
  235. package/dist/resolution/bridges/index.js.map +7 -0
  236. package/dist/resolution/bridges/native-events.js +188 -0
  237. package/dist/resolution/bridges/native-events.js.map +7 -0
  238. package/dist/resolution/bridges/native-views.js +244 -0
  239. package/dist/resolution/bridges/native-views.js.map +7 -0
  240. package/dist/resolution/bridges/react-native.js +161 -0
  241. package/dist/resolution/bridges/react-native.js.map +7 -0
  242. package/dist/resolution/bridges/swift-objc.js +227 -0
  243. package/dist/resolution/bridges/swift-objc.js.map +7 -0
  244. package/dist/resolution/bridges/turbomodules.js +216 -0
  245. package/dist/resolution/bridges/turbomodules.js.map +7 -0
  246. package/dist/resolution/index.js +61 -2
  247. package/dist/resolution/index.js.map +2 -2
  248. package/dist/security/attack-surface.js +164 -0
  249. package/dist/security/attack-surface.js.map +7 -0
  250. package/dist/security/context-warnings.js +123 -0
  251. package/dist/security/context-warnings.js.map +7 -0
  252. package/dist/security/context-warnings.test.js +300 -0
  253. package/dist/security/context-warnings.test.js.map +7 -0
  254. package/dist/security/data-flows.js +228 -0
  255. package/dist/security/data-flows.js.map +7 -0
  256. package/dist/security/dep-confusion.js +255 -0
  257. package/dist/security/dep-confusion.js.map +7 -0
  258. package/dist/security/errors.js +51 -0
  259. package/dist/security/errors.js.map +7 -0
  260. package/dist/security/export/fix-suggestions.js +58 -0
  261. package/dist/security/export/fix-suggestions.js.map +7 -0
  262. package/dist/security/export/fix-suggestions.test.js +74 -0
  263. package/dist/security/export/fix-suggestions.test.js.map +7 -0
  264. package/dist/security/export/sbom.js +230 -0
  265. package/dist/security/export/sbom.js.map +7 -0
  266. package/dist/security/export/sbom.test.js +288 -0
  267. package/dist/security/export/sbom.test.js.map +7 -0
  268. package/dist/security/export/serialization.js +142 -0
  269. package/dist/security/export/serialization.js.map +7 -0
  270. package/dist/security/export/serialization.test.js +310 -0
  271. package/dist/security/export/serialization.test.js.map +7 -0
  272. package/dist/security/export/vex.js +220 -0
  273. package/dist/security/export/vex.js.map +7 -0
  274. package/dist/security/export/vex.test.js +278 -0
  275. package/dist/security/export/vex.test.js.map +7 -0
  276. package/dist/security/index.js +67 -0
  277. package/dist/security/index.js.map +7 -0
  278. package/dist/security/integrator-transitives.test.js +359 -0
  279. package/dist/security/integrator-transitives.test.js.map +7 -0
  280. package/dist/security/integrator.js +491 -0
  281. package/dist/security/integrator.js.map +7 -0
  282. package/dist/security/integrator.test.js +237 -0
  283. package/dist/security/integrator.test.js.map +7 -0
  284. package/dist/security/license.js +70 -0
  285. package/dist/security/license.js.map +7 -0
  286. package/dist/security/manifest/adapter.js +243 -0
  287. package/dist/security/manifest/adapter.js.map +7 -0
  288. package/dist/security/manifest/adapter.test.js +272 -0
  289. package/dist/security/manifest/adapter.test.js.map +7 -0
  290. package/dist/security/manifest/parser.js +376 -0
  291. package/dist/security/manifest/parser.js.map +7 -0
  292. package/dist/security/manifest/parser.test.js +110 -0
  293. package/dist/security/manifest/parser.test.js.map +7 -0
  294. package/dist/security/manifest/plugins/cargo.js +233 -0
  295. package/dist/security/manifest/plugins/cargo.js.map +7 -0
  296. package/dist/security/manifest/plugins/cargo.test.js +304 -0
  297. package/dist/security/manifest/plugins/cargo.test.js.map +7 -0
  298. package/dist/security/manifest/plugins/composer.js +152 -0
  299. package/dist/security/manifest/plugins/composer.js.map +7 -0
  300. package/dist/security/manifest/plugins/go.js +146 -0
  301. package/dist/security/manifest/plugins/go.js.map +7 -0
  302. package/dist/security/manifest/plugins/go.test.js +341 -0
  303. package/dist/security/manifest/plugins/go.test.js.map +7 -0
  304. package/dist/security/manifest/plugins/gradle.js +159 -0
  305. package/dist/security/manifest/plugins/gradle.js.map +7 -0
  306. package/dist/security/manifest/plugins/hex.js +159 -0
  307. package/dist/security/manifest/plugins/hex.js.map +7 -0
  308. package/dist/security/manifest/plugins/maven.js +128 -0
  309. package/dist/security/manifest/plugins/maven.js.map +7 -0
  310. package/dist/security/manifest/plugins/maven.test.js +389 -0
  311. package/dist/security/manifest/plugins/maven.test.js.map +7 -0
  312. package/dist/security/manifest/plugins/npm.js +284 -0
  313. package/dist/security/manifest/plugins/npm.js.map +7 -0
  314. package/dist/security/manifest/plugins/npm.test.js +298 -0
  315. package/dist/security/manifest/plugins/npm.test.js.map +7 -0
  316. package/dist/security/manifest/plugins/nuget.js +186 -0
  317. package/dist/security/manifest/plugins/nuget.js.map +7 -0
  318. package/dist/security/manifest/plugins/pip.js +123 -0
  319. package/dist/security/manifest/plugins/pip.js.map +7 -0
  320. package/dist/security/manifest/plugins/pip.test.js +208 -0
  321. package/dist/security/manifest/plugins/pip.test.js.map +7 -0
  322. package/dist/security/manifest/plugins/pubspec.js +212 -0
  323. package/dist/security/manifest/plugins/pubspec.js.map +7 -0
  324. package/dist/security/manifest/plugins/pyproject.js +261 -0
  325. package/dist/security/manifest/plugins/pyproject.js.map +7 -0
  326. package/dist/security/manifest/plugins/rubygems.js +185 -0
  327. package/dist/security/manifest/plugins/rubygems.js.map +7 -0
  328. package/dist/security/manifest/plugins/swift.js +200 -0
  329. package/dist/security/manifest/plugins/swift.js.map +7 -0
  330. package/dist/security/owasp.js +104 -0
  331. package/dist/security/owasp.js.map +7 -0
  332. package/dist/security/pipeline.js +125 -0
  333. package/dist/security/pipeline.js.map +7 -0
  334. package/dist/security/reachability.js +276 -0
  335. package/dist/security/reachability.js.map +7 -0
  336. package/dist/security/reachability.test.js +394 -0
  337. package/dist/security/reachability.test.js.map +7 -0
  338. package/dist/security/remediation.js +126 -0
  339. package/dist/security/remediation.js.map +7 -0
  340. package/dist/security/secrets.js +176 -0
  341. package/dist/security/secrets.js.map +7 -0
  342. package/dist/security/staleness.js +231 -0
  343. package/dist/security/staleness.js.map +7 -0
  344. package/dist/security/supply-chain.js +301 -0
  345. package/dist/security/supply-chain.js.map +7 -0
  346. package/dist/security/suppressions.js +106 -0
  347. package/dist/security/suppressions.js.map +7 -0
  348. package/dist/security/types.js +17 -0
  349. package/dist/security/types.js.map +7 -0
  350. package/dist/security/vuln/client.js +355 -0
  351. package/dist/security/vuln/client.js.map +7 -0
  352. package/dist/security/vuln/client.test.js +288 -0
  353. package/dist/security/vuln/client.test.js.map +7 -0
  354. package/dist/security/vuln/epss-client.js +95 -0
  355. package/dist/security/vuln/epss-client.js.map +7 -0
  356. package/dist/security/vuln/index.js +29 -0
  357. package/dist/security/vuln/index.js.map +7 -0
  358. package/dist/security/vuln/osv-adapter.js +321 -0
  359. package/dist/security/vuln/osv-adapter.js.map +7 -0
  360. package/dist/security/vuln/osv-adapter.test.js +391 -0
  361. package/dist/security/vuln/osv-adapter.test.js.map +7 -0
  362. package/dist/security/vuln/types.js +17 -0
  363. package/dist/security/vuln/types.js.map +7 -0
  364. package/dist/types.js.map +2 -2
  365. package/package.json +5 -2
@@ -0,0 +1,185 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var rubygems_exports = {};
30
+ __export(rubygems_exports, {
31
+ parseRubygemsManifest: () => parseRubygemsManifest
32
+ });
33
+ module.exports = __toCommonJS(rubygems_exports);
34
+ var fs = __toESM(require("fs"));
35
+ var path = __toESM(require("path"));
36
+ var import_errors = require("../../../errors");
37
+ async function parseRubygemsManifest(manifestPath, projectRoot) {
38
+ const manifestDir = path.dirname(manifestPath);
39
+ const relativeManifest = path.relative(projectRoot, manifestPath).replace(/\\/g, "/");
40
+ let content;
41
+ try {
42
+ content = fs.readFileSync(manifestPath, "utf8");
43
+ } catch (err) {
44
+ (0, import_errors.logWarn)(`[sec:rubygems] Failed to read ${relativeManifest}: ${err instanceof Error ? err.message : String(err)}`);
45
+ return [];
46
+ }
47
+ const resolvedVersions = loadResolvedVersions(manifestDir);
48
+ const license = loadGemspecLicense(manifestDir);
49
+ const dependencies = [];
50
+ const lines = content.split("\n");
51
+ let currentScope = "production";
52
+ let groupDepth = 0;
53
+ for (const line of lines) {
54
+ const trimmed = line.trim();
55
+ if (trimmed === "" || trimmed.startsWith("#")) continue;
56
+ const groupMatch = trimmed.match(/^group\s+(.+?)\s+do\s*(?:#.*)?$/);
57
+ if (groupMatch) {
58
+ groupDepth++;
59
+ if (groupDepth === 1) {
60
+ currentScope = resolveGroupScope(groupMatch[1]);
61
+ }
62
+ continue;
63
+ }
64
+ if (trimmed === "end" || trimmed.startsWith("end ") || trimmed.startsWith("end#")) {
65
+ if (groupDepth > 0) {
66
+ groupDepth--;
67
+ if (groupDepth === 0) {
68
+ currentScope = "production";
69
+ }
70
+ }
71
+ continue;
72
+ }
73
+ const dep = parseGemLine(trimmed, relativeManifest);
74
+ if (dep) {
75
+ const resolvedVersion = resolvedVersions.get(dep.name);
76
+ dependencies.push({
77
+ name: dep.name,
78
+ declaredConstraint: dep.constraint,
79
+ resolvedVersion,
80
+ scope: currentScope,
81
+ ecosystem: "rubygems",
82
+ sourceManifest: relativeManifest,
83
+ ...license !== void 0 ? { license } : {}
84
+ });
85
+ }
86
+ }
87
+ return dependencies;
88
+ }
89
+ function parseGemLine(line, relativeManifest) {
90
+ const withoutComment = line.replace(/\s*#.*$/, "");
91
+ const gemMatch = withoutComment.match(/^gem\s+(['"])([^'"]+)\1(.*)?$/);
92
+ if (!gemMatch) return null;
93
+ const name = gemMatch[2].trim();
94
+ const rest = (gemMatch[3] || "").trim();
95
+ if (!isValidGemName(name)) {
96
+ (0, import_errors.logWarn)(`[sec:rubygems] Invalid gem name "${name}" in ${relativeManifest} \u2014 skipping`);
97
+ return null;
98
+ }
99
+ if (rest === "" || rest.startsWith(":") || rest.startsWith(",s*:")) {
100
+ return { name, constraint: "*" };
101
+ }
102
+ const versionConstraints = [];
103
+ const versionPattern = /['"]([^'"]*)['"]/g;
104
+ let versionMatch;
105
+ while ((versionMatch = versionPattern.exec(rest)) !== null) {
106
+ const candidate = versionMatch[1].trim();
107
+ if (/^(~>|>=|<=|!=|>|<|=|\d)/.test(candidate)) {
108
+ versionConstraints.push(candidate);
109
+ }
110
+ }
111
+ if (versionConstraints.length === 0) {
112
+ return { name, constraint: "*" };
113
+ }
114
+ return { name, constraint: versionConstraints.join(", ") };
115
+ }
116
+ function resolveGroupScope(groupSpec) {
117
+ if (/:test\b/.test(groupSpec) || /:development\b/.test(groupSpec)) {
118
+ return "development";
119
+ }
120
+ return "production";
121
+ }
122
+ function isValidGemName(name) {
123
+ if (!name || typeof name !== "string") return false;
124
+ if (name.length > 128) return false;
125
+ return /^[a-zA-Z0-9][a-zA-Z0-9_.-]*$/.test(name);
126
+ }
127
+ function loadResolvedVersions(manifestDir) {
128
+ const map = /* @__PURE__ */ new Map();
129
+ const lockPath = path.join(manifestDir, "Gemfile.lock");
130
+ if (!fs.existsSync(lockPath)) {
131
+ return map;
132
+ }
133
+ try {
134
+ const lockContent = fs.readFileSync(lockPath, "utf8");
135
+ extractFromGemfileLock(lockContent, map);
136
+ } catch (err) {
137
+ (0, import_errors.logWarn)(`[sec:rubygems] Failed to parse Gemfile.lock: ${err instanceof Error ? err.message : String(err)}`);
138
+ }
139
+ return map;
140
+ }
141
+ function extractFromGemfileLock(content, map) {
142
+ const lines = content.split("\n");
143
+ let inGemSection = false;
144
+ let inSpecsSection = false;
145
+ for (const line of lines) {
146
+ if (/^\S/.test(line)) {
147
+ inGemSection = line.trimEnd() === "GEM";
148
+ inSpecsSection = false;
149
+ continue;
150
+ }
151
+ if (!inGemSection) continue;
152
+ if (/^ specs:\s*$/.test(line)) {
153
+ inSpecsSection = true;
154
+ continue;
155
+ }
156
+ if (!inSpecsSection) continue;
157
+ const specMatch = line.match(/^ ([a-zA-Z0-9][a-zA-Z0-9_.-]*)\s+\(([^)]+)\)\s*$/);
158
+ if (specMatch) {
159
+ const name = specMatch[1];
160
+ const version = specMatch[2].trim();
161
+ if (!map.has(name)) {
162
+ map.set(name, version);
163
+ }
164
+ }
165
+ }
166
+ }
167
+ function loadGemspecLicense(dir) {
168
+ try {
169
+ const entries = fs.readdirSync(dir);
170
+ const gemspecFile = entries.find((f) => f.endsWith(".gemspec"));
171
+ if (!gemspecFile) return void 0;
172
+ const content = fs.readFileSync(path.join(dir, gemspecFile), "utf8");
173
+ const match = content.match(/\.license\s*=\s*['"]([^'"]+)['"]/);
174
+ if (match && match[1].trim() !== "") {
175
+ return match[1].trim();
176
+ }
177
+ } catch {
178
+ }
179
+ return void 0;
180
+ }
181
+ // Annotate the CommonJS export names for ESM import in node:
182
+ 0 && (module.exports = {
183
+ parseRubygemsManifest
184
+ });
185
+ //# sourceMappingURL=rubygems.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/security/manifest/plugins/rubygems.ts"],
4
+ "sourcesContent": ["/**\n * RubyGems Version Extraction Plugin for KiroGraph-Sec\n *\n * Parses Gemfile manifests to extract gem declarations with version constraints,\n * scopes (derived from `group` blocks), and resolved versions from Gemfile.lock.\n *\n * Handles:\n * - `gem 'name', '~> 1.0'` \u2014 single version constraint\n * - `gem 'name', '>= 1.0', '< 2.0'` \u2014 multiple constraints (joined with ', ')\n * - `gem 'name'` \u2014 no version constraint\n * - `group :development, :test do ... end` blocks \u2192 'development' scope\n */\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport type { ParsedDependency } from '../../types';\nimport { logWarn } from '../../../errors';\n\n/**\n * Resolved version map: gem name \u2192 resolved version string.\n * Built from Gemfile.lock.\n */\ntype ResolvedVersionMap = Map<string, string>;\n\n/**\n * Parse a Gemfile manifest and extract gem declarations with version constraints,\n * scopes, and resolved versions from Gemfile.lock.\n *\n * @param manifestPath - Absolute path to the Gemfile\n * @param projectRoot - Absolute path to the project root directory\n * @returns Array of parsed dependencies with version and scope information\n */\nexport async function parseRubygemsManifest(\n manifestPath: string,\n projectRoot: string,\n): Promise<ParsedDependency[]> {\n const manifestDir = path.dirname(manifestPath);\n const relativeManifest = path.relative(projectRoot, manifestPath).replace(/\\\\/g, '/');\n\n // Read the Gemfile content\n let content: string;\n try {\n content = fs.readFileSync(manifestPath, 'utf8');\n } catch (err) {\n logWarn(`[sec:rubygems] Failed to read ${relativeManifest}: ${err instanceof Error ? err.message : String(err)}`);\n return [];\n }\n\n // Attempt to load resolved versions from Gemfile.lock\n const resolvedVersions = loadResolvedVersions(manifestDir);\n\n // Attempt to extract license from a gemspec in the same directory\n const license = loadGemspecLicense(manifestDir);\n\n // Extract dependencies from the Gemfile\n const dependencies: ParsedDependency[] = [];\n const lines = content.split('\\n');\n\n // Track current group scope \u2014 null means top-level (production)\n let currentScope: ParsedDependency['scope'] = 'production';\n let groupDepth = 0; // tracks nesting depth inside a group block\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (trimmed === '' || trimmed.startsWith('#')) continue;\n\n // Detect start of a group block: `group :test, :development do`\n const groupMatch = trimmed.match(/^group\\s+(.+?)\\s+do\\s*(?:#.*)?$/);\n if (groupMatch) {\n groupDepth++;\n if (groupDepth === 1) {\n currentScope = resolveGroupScope(groupMatch[1]);\n }\n continue;\n }\n\n // Detect `end` \u2014 only reset scope when we exit the outermost group block\n if (trimmed === 'end' || trimmed.startsWith('end ') || trimmed.startsWith('end#')) {\n if (groupDepth > 0) {\n groupDepth--;\n if (groupDepth === 0) {\n currentScope = 'production';\n }\n }\n continue;\n }\n\n // Match gem declarations\n const dep = parseGemLine(trimmed, relativeManifest);\n if (dep) {\n const resolvedVersion = resolvedVersions.get(dep.name);\n dependencies.push({\n name: dep.name,\n declaredConstraint: dep.constraint,\n resolvedVersion,\n scope: currentScope,\n ecosystem: 'rubygems',\n sourceManifest: relativeManifest,\n ...(license !== undefined ? { license } : {}),\n });\n }\n }\n\n return dependencies;\n}\n\n/**\n * A raw dependency entry extracted from a Gemfile line.\n */\ninterface RawDependency {\n name: string;\n constraint: string;\n}\n\n/**\n * Parse a single `gem` declaration line from a Gemfile.\n *\n * Handles:\n * - `gem 'name'`\n * - `gem 'name', '~> 1.0'`\n * - `gem \"name\", \"~> 1.0\"`\n * - `gem 'name', '>= 1.0', '< 2.0'` (multiple constraints joined with ', ')\n */\nfunction parseGemLine(line: string, relativeManifest: string): RawDependency | null {\n // Strip inline comments\n const withoutComment = line.replace(/\\s*#.*$/, '');\n\n // Match: gem 'name' or gem \"name\" followed by optional version strings\n const gemMatch = withoutComment.match(/^gem\\s+(['\"])([^'\"]+)\\1(.*)?$/);\n if (!gemMatch) return null;\n\n const name = gemMatch[2].trim();\n const rest = (gemMatch[3] || '').trim();\n\n if (!isValidGemName(name)) {\n logWarn(`[sec:rubygems] Invalid gem name \"${name}\" in ${relativeManifest} \u2014 skipping`);\n return null;\n }\n\n // No version constraint\n if (rest === '' || rest.startsWith(':') || rest.startsWith(',\\s*:')) {\n return { name, constraint: '*' };\n }\n\n // Extract all string literals from the rest of the line that look like version constraints\n const versionConstraints: string[] = [];\n const versionPattern = /['\"]([^'\"]*)['\"]/g;\n let versionMatch: RegExpExecArray | null;\n while ((versionMatch = versionPattern.exec(rest)) !== null) {\n const candidate = versionMatch[1].trim();\n // Only capture strings that look like version constraints (start with ~>, >=, <=, !=, >, <, =, or a digit)\n if (/^(~>|>=|<=|!=|>|<|=|\\d)/.test(candidate)) {\n versionConstraints.push(candidate);\n }\n }\n\n if (versionConstraints.length === 0) {\n return { name, constraint: '*' };\n }\n\n return { name, constraint: versionConstraints.join(', ') };\n}\n\n/**\n * Determine the dependency scope from a group specifier string.\n * Any group containing :test or :development maps to 'development'.\n *\n * @param groupSpec - The group specifier string, e.g., `:development, :test`\n */\nfunction resolveGroupScope(groupSpec: string): ParsedDependency['scope'] {\n if (/:test\\b/.test(groupSpec) || /:development\\b/.test(groupSpec)) {\n return 'development';\n }\n return 'production';\n}\n\n/**\n * Validate that a gem name follows RubyGems naming conventions.\n */\nfunction isValidGemName(name: string): boolean {\n if (!name || typeof name !== 'string') return false;\n if (name.length > 128) return false;\n return /^[a-zA-Z0-9][a-zA-Z0-9_.-]*$/.test(name);\n}\n\n/**\n * Attempt to load resolved versions from Gemfile.lock in the given directory.\n * Returns an empty map if Gemfile.lock is not available.\n *\n * Gemfile.lock GEM section format:\n * ```\n * GEM\n * remote: https://rubygems.org/\n * specs:\n * rails (7.0.4)\n * rake (13.0.6)\n * ```\n */\nfunction loadResolvedVersions(manifestDir: string): ResolvedVersionMap {\n const map: ResolvedVersionMap = new Map();\n\n const lockPath = path.join(manifestDir, 'Gemfile.lock');\n if (!fs.existsSync(lockPath)) {\n return map;\n }\n\n try {\n const lockContent = fs.readFileSync(lockPath, 'utf8');\n extractFromGemfileLock(lockContent, map);\n } catch (err) {\n logWarn(`[sec:rubygems] Failed to parse Gemfile.lock: ${err instanceof Error ? err.message : String(err)}`);\n }\n\n return map;\n}\n\n/**\n * Extract resolved versions from Gemfile.lock content.\n *\n * The GEM section contains a `specs:` subsection with lines of the form:\n * ` gemname (1.2.3)` (4-space indent for direct deps, 6-space for sub-deps).\n * We capture all entries under `specs:`.\n */\nfunction extractFromGemfileLock(content: string, map: ResolvedVersionMap): void {\n const lines = content.split('\\n');\n let inGemSection = false;\n let inSpecsSection = false;\n\n for (const line of lines) {\n // Detect top-level section headers (no indent)\n if (/^\\S/.test(line)) {\n inGemSection = line.trimEnd() === 'GEM';\n inSpecsSection = false;\n continue;\n }\n\n if (!inGemSection) continue;\n\n // Detect ` specs:` subsection (2-space indent)\n if (/^ specs:\\s*$/.test(line)) {\n inSpecsSection = true;\n continue;\n }\n\n if (!inSpecsSection) continue;\n\n // Parse gem entries: ` gemname (1.2.3)` \u2014 4+ spaces indent\n const specMatch = line.match(/^ ([a-zA-Z0-9][a-zA-Z0-9_.-]*)\\s+\\(([^)]+)\\)\\s*$/);\n if (specMatch) {\n const name = specMatch[1];\n const version = specMatch[2].trim();\n if (!map.has(name)) {\n map.set(name, version);\n }\n }\n }\n}\n\n/**\n * Attempt to load the license from a .gemspec file in the given directory.\n * Looks for: s.license = 'MIT' or spec.license = \"MIT\"\n */\nfunction loadGemspecLicense(dir: string): string | undefined {\n try {\n const entries = fs.readdirSync(dir);\n const gemspecFile = entries.find(f => f.endsWith('.gemspec'));\n if (!gemspecFile) return undefined;\n const content = fs.readFileSync(path.join(dir, gemspecFile), 'utf8');\n const match = content.match(/\\.license\\s*=\\s*['\"]([^'\"]+)['\"]/);\n if (match && match[1].trim() !== '') {\n return match[1].trim();\n }\n } catch {\n // best-effort \u2014 ignore errors\n }\n return undefined;\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,200 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var swift_exports = {};
30
+ __export(swift_exports, {
31
+ parseSwiftManifest: () => parseSwiftManifest
32
+ });
33
+ module.exports = __toCommonJS(swift_exports);
34
+ var fs = __toESM(require("fs"));
35
+ var path = __toESM(require("path"));
36
+ var import_errors = require("../../../errors");
37
+ async function parseSwiftManifest(manifestPath, projectRoot) {
38
+ const manifestDir = path.dirname(manifestPath);
39
+ const relativeManifest = path.relative(projectRoot, manifestPath).replace(/\\/g, "/");
40
+ const resolved = loadPackageResolved(manifestDir);
41
+ if (resolved.size > 0 || hasPackageResolved(manifestDir)) {
42
+ return buildFromResolved(resolved, relativeManifest);
43
+ }
44
+ let content;
45
+ try {
46
+ content = fs.readFileSync(manifestPath, "utf8");
47
+ } catch (err) {
48
+ (0, import_errors.logWarn)(`[sec:swift] Failed to read ${relativeManifest}: ${err instanceof Error ? err.message : String(err)}`);
49
+ return [];
50
+ }
51
+ const rawDeps = extractFromPackageSwift(content, relativeManifest);
52
+ return rawDeps.map((dep) => ({
53
+ name: dep.name,
54
+ declaredConstraint: dep.constraint,
55
+ resolvedVersion: dep.resolvedVersion,
56
+ scope: "production",
57
+ ecosystem: "swift",
58
+ sourceManifest: relativeManifest
59
+ }));
60
+ }
61
+ function buildFromResolved(resolved, relativeManifest) {
62
+ const deps = [];
63
+ for (const [name, version] of resolved) {
64
+ deps.push({
65
+ name,
66
+ declaredConstraint: version,
67
+ resolvedVersion: version,
68
+ scope: "production",
69
+ ecosystem: "swift",
70
+ sourceManifest: relativeManifest
71
+ });
72
+ }
73
+ return deps;
74
+ }
75
+ function extractFromPackageSwift(content, relativeManifest) {
76
+ const deps = [];
77
+ const packagePattern = /\.package\s*\(\s*url\s*:\s*"([^"]+)"[^)]+\)/gs;
78
+ let match;
79
+ while ((match = packagePattern.exec(content)) !== null) {
80
+ const url = match[1];
81
+ const fullMatch = match[0];
82
+ const name = packageNameFromUrl(url);
83
+ if (!name) {
84
+ (0, import_errors.logWarn)(`[sec:swift] Could not derive package name from URL "${url}" in ${relativeManifest} \u2014 skipping`);
85
+ continue;
86
+ }
87
+ const constraint = extractVersionConstraint(fullMatch, relativeManifest);
88
+ deps.push({ name, constraint });
89
+ }
90
+ return deps;
91
+ }
92
+ function extractVersionConstraint(packageCall, relativeManifest) {
93
+ const fromMatch = packageCall.match(/\bfrom\s*:\s*"([^"]+)"/);
94
+ if (fromMatch) return `from: ${fromMatch[1]}`;
95
+ const exactMatch = packageCall.match(/\bexact\s*:\s*"([^"]+)"/);
96
+ if (exactMatch) return `exact: ${exactMatch[1]}`;
97
+ const upToMajorMatch = packageCall.match(/\.upToNextMajor\s*\(\s*from\s*:\s*"([^"]+)"\s*\)/);
98
+ if (upToMajorMatch) return `upToNextMajor: ${upToMajorMatch[1]}`;
99
+ const upToMinorMatch = packageCall.match(/\.upToNextMinor\s*\(\s*from\s*:\s*"([^"]+)"\s*\)/);
100
+ if (upToMinorMatch) return `upToNextMinor: ${upToMinorMatch[1]}`;
101
+ const rangeMatch = packageCall.match(/"([^"]+)"\s*\.{2,3}<\s*"([^"]+)"/);
102
+ if (rangeMatch) return `${rangeMatch[1]} ..< ${rangeMatch[2]}`;
103
+ (0, import_errors.logWarn)(`[sec:swift] Unrecognised version specifier in Package.swift at ${relativeManifest} \u2014 using '*'`);
104
+ return "*";
105
+ }
106
+ function packageNameFromUrl(url) {
107
+ try {
108
+ const cleaned = url.replace(/\/+$/, "");
109
+ const segments = cleaned.split("/");
110
+ const last = segments[segments.length - 1];
111
+ if (!last) return null;
112
+ return last.replace(/\.git$/i, "").toLowerCase();
113
+ } catch {
114
+ return null;
115
+ }
116
+ }
117
+ function hasPackageResolved(manifestDir) {
118
+ return fs.existsSync(path.join(manifestDir, "Package.resolved")) || fs.existsSync(path.join(manifestDir, ".build", "Package.resolved"));
119
+ }
120
+ function loadPackageResolved(manifestDir) {
121
+ const map = /* @__PURE__ */ new Map();
122
+ const candidates = [
123
+ path.join(manifestDir, "Package.resolved"),
124
+ path.join(manifestDir, ".build", "Package.resolved")
125
+ ];
126
+ for (const candidate of candidates) {
127
+ if (!fs.existsSync(candidate)) continue;
128
+ try {
129
+ const lockContent = fs.readFileSync(candidate, "utf8");
130
+ extractFromPackageResolved(lockContent, map, candidate);
131
+ return map;
132
+ } catch (err) {
133
+ (0, import_errors.logWarn)(`[sec:swift] Failed to parse ${candidate}: ${err instanceof Error ? err.message : String(err)}`);
134
+ }
135
+ }
136
+ return map;
137
+ }
138
+ function extractFromPackageResolved(content, map, filePath) {
139
+ let data;
140
+ try {
141
+ data = JSON.parse(content);
142
+ } catch {
143
+ (0, import_errors.logWarn)(`[sec:swift] ${filePath} is not valid JSON \u2014 resolved versions unavailable`);
144
+ return;
145
+ }
146
+ let pins = null;
147
+ if (Array.isArray(data["pins"])) {
148
+ pins = data["pins"];
149
+ extractPinsV2(pins, map);
150
+ return;
151
+ }
152
+ const obj = data["object"];
153
+ if (obj && typeof obj === "object" && !Array.isArray(obj)) {
154
+ const objRecord = obj;
155
+ if (Array.isArray(objRecord["pins"])) {
156
+ pins = objRecord["pins"];
157
+ extractPinsV1(pins, map);
158
+ return;
159
+ }
160
+ }
161
+ (0, import_errors.logWarn)(`[sec:swift] ${filePath} has unrecognised Package.resolved format \u2014 resolved versions unavailable`);
162
+ }
163
+ function extractPinsV2(pins, map) {
164
+ for (const pin of pins) {
165
+ if (!pin || typeof pin !== "object") continue;
166
+ const p = pin;
167
+ const identity = typeof p["identity"] === "string" ? p["identity"].toLowerCase() : null;
168
+ const state = p["state"];
169
+ const version = state && typeof state === "object" && !Array.isArray(state) ? state["version"] : null;
170
+ if (identity && typeof version === "string" && version) {
171
+ if (!map.has(identity)) {
172
+ map.set(identity, version);
173
+ }
174
+ }
175
+ }
176
+ }
177
+ function extractPinsV1(pins, map) {
178
+ for (const pin of pins) {
179
+ if (!pin || typeof pin !== "object") continue;
180
+ const p = pin;
181
+ let name = null;
182
+ if (typeof p["package"] === "string" && p["package"]) {
183
+ name = p["package"].toLowerCase();
184
+ } else if (typeof p["repositoryURL"] === "string") {
185
+ name = packageNameFromUrl(p["repositoryURL"]);
186
+ }
187
+ const state = p["state"];
188
+ const version = state && typeof state === "object" && !Array.isArray(state) ? state["version"] : null;
189
+ if (name && typeof version === "string" && version) {
190
+ if (!map.has(name)) {
191
+ map.set(name, version);
192
+ }
193
+ }
194
+ }
195
+ }
196
+ // Annotate the CommonJS export names for ESM import in node:
197
+ 0 && (module.exports = {
198
+ parseSwiftManifest
199
+ });
200
+ //# sourceMappingURL=swift.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/security/manifest/plugins/swift.ts"],
4
+ "sourcesContent": ["/**\n * Swift Package Manager Version Extraction Plugin for KiroGraph-Sec\n *\n * Parses Package.swift manifests to extract Swift package dependencies with\n * version constraints and resolved versions from Package.resolved.\n *\n * Prefers Package.resolved (more reliable) over regex parsing of Package.swift.\n * Handles both v1 and v2 Package.resolved formats.\n *\n * Package.resolved locations searched:\n * - Same directory as Package.swift\n * - `.build/` subdirectory relative to Package.swift\n */\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport type { ParsedDependency } from '../../types';\nimport { logWarn } from '../../../errors';\n\n/**\n * Resolved version map: package identity \u2192 resolved version string.\n * Built from Package.resolved.\n */\ntype ResolvedVersionMap = Map<string, string>;\n\n/**\n * A raw dependency entry extracted from Package.swift or Package.resolved.\n */\ninterface RawDependency {\n name: string;\n constraint: string;\n resolvedVersion?: string;\n}\n\n/**\n * Parse a Package.swift manifest and extract package dependencies with\n * version constraints and resolved versions from Package.resolved.\n *\n * @param manifestPath - Absolute path to the Package.swift file\n * @param projectRoot - Absolute path to the project root directory\n * @returns Array of parsed dependencies with version and scope information\n */\nexport async function parseSwiftManifest(\n manifestPath: string,\n projectRoot: string,\n): Promise<ParsedDependency[]> {\n const manifestDir = path.dirname(manifestPath);\n const relativeManifest = path.relative(projectRoot, manifestPath).replace(/\\\\/g, '/');\n\n // Try to load Package.resolved first \u2014 it's more reliable than parsing Package.swift\n const resolved = loadPackageResolved(manifestDir);\n if (resolved.size > 0 || hasPackageResolved(manifestDir)) {\n // We have a lock file \u2014 use its entries as the authoritative dependency list\n return buildFromResolved(resolved, relativeManifest);\n }\n\n // Fallback: parse Package.swift directly\n let content: string;\n try {\n content = fs.readFileSync(manifestPath, 'utf8');\n } catch (err) {\n logWarn(`[sec:swift] Failed to read ${relativeManifest}: ${err instanceof Error ? err.message : String(err)}`);\n return [];\n }\n\n const rawDeps = extractFromPackageSwift(content, relativeManifest);\n return rawDeps.map((dep) => ({\n name: dep.name,\n declaredConstraint: dep.constraint,\n resolvedVersion: dep.resolvedVersion,\n scope: 'production' as const,\n ecosystem: 'swift',\n sourceManifest: relativeManifest,\n }));\n}\n\n/**\n * Build ParsedDependency entries from a resolved version map.\n * All Swift dependencies are production scope (SPM has no dev deps concept).\n */\nfunction buildFromResolved(\n resolved: ResolvedVersionMap,\n relativeManifest: string,\n): ParsedDependency[] {\n const deps: ParsedDependency[] = [];\n for (const [name, version] of resolved) {\n deps.push({\n name,\n declaredConstraint: version,\n resolvedVersion: version,\n scope: 'production',\n ecosystem: 'swift',\n sourceManifest: relativeManifest,\n });\n }\n return deps;\n}\n\n/**\n * Extract dependencies from Package.swift using regex patterns.\n *\n * Handles:\n * - `.package(url: \"...\", from: \"1.0.0\")`\n * - `.package(url: \"...\", exact: \"1.0.0\")`\n * - `.package(url: \"...\", .upToNextMajor(from: \"1.0.0\"))`\n * - `.package(url: \"...\", .upToNextMinor(from: \"1.0.0\"))`\n */\nfunction extractFromPackageSwift(content: string, relativeManifest: string): RawDependency[] {\n const deps: RawDependency[] = [];\n\n // Match .package(url: \"...\", <version spec>) \u2014 possibly spanning multiple lines\n // We capture the url argument and the version specifier\n const packagePattern = /\\.package\\s*\\(\\s*url\\s*:\\s*\"([^\"]+)\"[^)]+\\)/gs;\n let match: RegExpExecArray | null;\n\n while ((match = packagePattern.exec(content)) !== null) {\n const url = match[1];\n const fullMatch = match[0];\n\n const name = packageNameFromUrl(url);\n if (!name) {\n logWarn(`[sec:swift] Could not derive package name from URL \"${url}\" in ${relativeManifest} \u2014 skipping`);\n continue;\n }\n\n const constraint = extractVersionConstraint(fullMatch, relativeManifest);\n deps.push({ name, constraint });\n }\n\n return deps;\n}\n\n/**\n * Extract a version constraint string from a .package(...) call.\n * Returns '*' if no recognised version spec is found.\n */\nfunction extractVersionConstraint(packageCall: string, relativeManifest: string): string {\n // from: \"1.0.0\"\n const fromMatch = packageCall.match(/\\bfrom\\s*:\\s*\"([^\"]+)\"/);\n if (fromMatch) return `from: ${fromMatch[1]}`;\n\n // exact: \"1.0.0\"\n const exactMatch = packageCall.match(/\\bexact\\s*:\\s*\"([^\"]+)\"/);\n if (exactMatch) return `exact: ${exactMatch[1]}`;\n\n // .upToNextMajor(from: \"1.0.0\")\n const upToMajorMatch = packageCall.match(/\\.upToNextMajor\\s*\\(\\s*from\\s*:\\s*\"([^\"]+)\"\\s*\\)/);\n if (upToMajorMatch) return `upToNextMajor: ${upToMajorMatch[1]}`;\n\n // .upToNextMinor(from: \"1.0.0\")\n const upToMinorMatch = packageCall.match(/\\.upToNextMinor\\s*\\(\\s*from\\s*:\\s*\"([^\"]+)\"\\s*\\)/);\n if (upToMinorMatch) return `upToNextMinor: ${upToMinorMatch[1]}`;\n\n // Range: \"1.0.0\"..<\"2.0.0\"\n const rangeMatch = packageCall.match(/\"([^\"]+)\"\\s*\\.{2,3}<\\s*\"([^\"]+)\"/);\n if (rangeMatch) return `${rangeMatch[1]} ..< ${rangeMatch[2]}`;\n\n logWarn(`[sec:swift] Unrecognised version specifier in Package.swift at ${relativeManifest} \u2014 using '*'`);\n return '*';\n}\n\n/**\n * Derive a package name from a Swift package URL.\n * Extracts the last path component and strips a `.git` suffix.\n *\n * e.g., `https://github.com/apple/swift-argument-parser.git` \u2192 `swift-argument-parser`\n */\nfunction packageNameFromUrl(url: string): string | null {\n try {\n // Remove trailing slash\n const cleaned = url.replace(/\\/+$/, '');\n const segments = cleaned.split('/');\n const last = segments[segments.length - 1];\n if (!last) return null;\n // Strip .git suffix\n return last.replace(/\\.git$/i, '').toLowerCase();\n } catch {\n return null;\n }\n}\n\n/**\n * Check whether Package.resolved exists in the expected locations.\n */\nfunction hasPackageResolved(manifestDir: string): boolean {\n return (\n fs.existsSync(path.join(manifestDir, 'Package.resolved')) ||\n fs.existsSync(path.join(manifestDir, '.build', 'Package.resolved'))\n );\n}\n\n/**\n * Attempt to load resolved versions from Package.resolved.\n * Searches the manifest directory and `.build/` subdirectory.\n * Returns an empty map if Package.resolved is not available.\n *\n * Supports both v1 and v2 Package.resolved formats.\n */\nfunction loadPackageResolved(manifestDir: string): ResolvedVersionMap {\n const map: ResolvedVersionMap = new Map();\n\n const candidates = [\n path.join(manifestDir, 'Package.resolved'),\n path.join(manifestDir, '.build', 'Package.resolved'),\n ];\n\n for (const candidate of candidates) {\n if (!fs.existsSync(candidate)) continue;\n\n try {\n const lockContent = fs.readFileSync(candidate, 'utf8');\n extractFromPackageResolved(lockContent, map, candidate);\n return map; // Use first found\n } catch (err) {\n logWarn(`[sec:swift] Failed to parse ${candidate}: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n return map;\n}\n\n/**\n * Extract resolved versions from Package.resolved content.\n *\n * v2 format:\n * ```json\n * { \"pins\": [{ \"identity\": \"name\", \"kind\": \"remoteSourceControl\",\n * \"location\": \"url\", \"state\": { \"version\": \"1.2.3\" } }] }\n * ```\n *\n * v1 format:\n * ```json\n * { \"object\": { \"pins\": [{ \"package\": \"Name\", \"repositoryURL\": \"url\",\n * \"state\": { \"version\": \"1.2.3\" } }] } }\n * ```\n */\nfunction extractFromPackageResolved(\n content: string,\n map: ResolvedVersionMap,\n filePath: string,\n): void {\n let data: Record<string, unknown>;\n try {\n data = JSON.parse(content) as Record<string, unknown>;\n } catch {\n logWarn(`[sec:swift] ${filePath} is not valid JSON \u2014 resolved versions unavailable`);\n return;\n }\n\n // Determine format version and locate pins array\n let pins: unknown[] | null = null;\n\n // v2: top-level `pins` array\n if (Array.isArray(data['pins'])) {\n pins = data['pins'] as unknown[];\n extractPinsV2(pins, map);\n return;\n }\n\n // v1: `object.pins` array\n const obj = data['object'];\n if (obj && typeof obj === 'object' && !Array.isArray(obj)) {\n const objRecord = obj as Record<string, unknown>;\n if (Array.isArray(objRecord['pins'])) {\n pins = objRecord['pins'] as unknown[];\n extractPinsV1(pins, map);\n return;\n }\n }\n\n logWarn(`[sec:swift] ${filePath} has unrecognised Package.resolved format \u2014 resolved versions unavailable`);\n}\n\n/**\n * Extract pins from Package.resolved v2 format.\n * Each pin has: `{ identity, kind, location, state: { version } }`\n */\nfunction extractPinsV2(pins: unknown[], map: ResolvedVersionMap): void {\n for (const pin of pins) {\n if (!pin || typeof pin !== 'object') continue;\n const p = pin as Record<string, unknown>;\n const identity = typeof p['identity'] === 'string' ? p['identity'].toLowerCase() : null;\n const state = p['state'];\n const version =\n state && typeof state === 'object' && !Array.isArray(state)\n ? (state as Record<string, unknown>)['version']\n : null;\n if (identity && typeof version === 'string' && version) {\n if (!map.has(identity)) {\n map.set(identity, version);\n }\n }\n }\n}\n\n/**\n * Extract pins from Package.resolved v1 format.\n * Each pin has: `{ package, repositoryURL, state: { version } }`\n */\nfunction extractPinsV1(pins: unknown[], map: ResolvedVersionMap): void {\n for (const pin of pins) {\n if (!pin || typeof pin !== 'object') continue;\n const p = pin as Record<string, unknown>;\n // v1 uses `package` or derives name from `repositoryURL`\n let name: string | null = null;\n if (typeof p['package'] === 'string' && p['package']) {\n name = p['package'].toLowerCase();\n } else if (typeof p['repositoryURL'] === 'string') {\n name = packageNameFromUrl(p['repositoryURL']);\n }\n const state = p['state'];\n const version =\n state && typeof state === 'object' && !Array.isArray(state)\n ? (state as Record<string, unknown>)['version']\n : null;\n if (name && typeof version === 'string' && version) {\n if (!map.has(name)) {\n map.set(name, version);\n }\n }\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var owasp_exports = {};
20
+ __export(owasp_exports, {
21
+ OWASP_TOP_10: () => OWASP_TOP_10,
22
+ mapCveToOwasp: () => mapCveToOwasp
23
+ });
24
+ module.exports = __toCommonJS(owasp_exports);
25
+ const OWASP_TOP_10 = {
26
+ A01: {
27
+ category: "A01",
28
+ name: "Broken Access Control",
29
+ description: "Restrictions on authenticated users are not properly enforced.",
30
+ cweIds: [200, 201, 284, 285, 352, 359, 732, 862, 863, 913]
31
+ },
32
+ A02: {
33
+ category: "A02",
34
+ name: "Cryptographic Failures",
35
+ description: "Failures related to cryptography which often lead to exposure of sensitive data.",
36
+ cweIds: [261, 296, 310, 312, 315, 319, 321, 326, 327, 328, 330, 331, 335, 336, 337, 338, 340, 347, 523, 720, 757, 759, 760, 780, 818, 916]
37
+ },
38
+ A03: {
39
+ category: "A03",
40
+ name: "Injection",
41
+ description: "User-supplied data is not validated, filtered, or sanitized by the application.",
42
+ cweIds: [20, 74, 77, 78, 79, 88, 89, 90, 91, 93, 94, 95, 116, 943]
43
+ },
44
+ A04: {
45
+ category: "A04",
46
+ name: "Insecure Design",
47
+ description: "Missing or ineffective control design.",
48
+ cweIds: [73, 183, 209, 213, 235, 256, 257, 266, 269, 280, 311, 312, 313, 316, 419, 434, 444, 451, 454, 602, 620, 636, 841, 862, 1004, 1173]
49
+ },
50
+ A05: {
51
+ category: "A05",
52
+ name: "Security Misconfiguration",
53
+ description: "Missing appropriate security hardening across any part of the application stack.",
54
+ cweIds: [2, 11, 13, 15, 16, 260, 315, 520, 526, 537, 541, 548, 732]
55
+ },
56
+ A06: {
57
+ category: "A06",
58
+ name: "Vulnerable and Outdated Components",
59
+ description: "Components with known vulnerabilities are used.",
60
+ cweIds: [1035, 1104]
61
+ },
62
+ A07: {
63
+ category: "A07",
64
+ name: "Identification and Authentication Failures",
65
+ description: "Confirmation of user identity, authentication, and session management failures.",
66
+ cweIds: [255, 259, 287, 288, 290, 294, 295, 297, 300, 302, 304, 306, 307, 346, 384, 521, 613, 620, 640, 798, 940, 1216]
67
+ },
68
+ A08: {
69
+ category: "A08",
70
+ name: "Software and Data Integrity Failures",
71
+ description: "Code and infrastructure that does not protect against integrity violations.",
72
+ cweIds: [345, 353, 426, 494, 502, 565, 784, 829, 830, 915]
73
+ },
74
+ A09: {
75
+ category: "A09",
76
+ name: "Security Logging and Monitoring Failures",
77
+ description: "Insufficient logging, detection, monitoring, and active response.",
78
+ cweIds: [117, 223, 532, 778]
79
+ },
80
+ A10: {
81
+ category: "A10",
82
+ name: "Server-Side Request Forgery",
83
+ description: "Web application fetches a remote resource without validating user-supplied URL.",
84
+ cweIds: [918]
85
+ }
86
+ };
87
+ function mapCveToOwasp(summary, packageName) {
88
+ const text = (summary + " " + packageName).toLowerCase();
89
+ if (/inject|sql|xss|cross.site|script|command.inject|ldap|xpath/i.test(text)) return "A03";
90
+ if (/auth|authentication|session|credential|password|token|csrf|bypass/i.test(text)) return "A07";
91
+ if (/access.control|privilege|permission|authoriz|rbac|idor/i.test(text)) return "A01";
92
+ if (/crypto|encrypt|tls|ssl|cipher|hash|random|certificate/i.test(text)) return "A02";
93
+ if (/deserializ|pickle|marshal|prototype.pollution|supply.chain|integrity/i.test(text)) return "A08";
94
+ if (/ssrf|request.forgery|server.side/i.test(text)) return "A10";
95
+ if (/config|misconfig|default|expose|disclose|information/i.test(text)) return "A05";
96
+ if (/log|monitor|audit|trace/i.test(text)) return "A09";
97
+ return "A06";
98
+ }
99
+ // Annotate the CommonJS export names for ESM import in node:
100
+ 0 && (module.exports = {
101
+ OWASP_TOP_10,
102
+ mapCveToOwasp
103
+ });
104
+ //# sourceMappingURL=owasp.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/security/owasp.ts"],
4
+ "sourcesContent": ["/**\n * OWASP Top 10 (2021) Mapping Utility\n *\n * Maps CVE findings to OWASP categories and provides associated CWE IDs.\n */\n\nexport type OwaspCategory = 'A01' | 'A02' | 'A03' | 'A04' | 'A05' | 'A06' | 'A07' | 'A08' | 'A09' | 'A10';\n\nexport interface OwaspMapping {\n category: OwaspCategory;\n name: string;\n description: string;\n cweIds: number[];\n}\n\nexport const OWASP_TOP_10: Record<OwaspCategory, OwaspMapping> = {\n A01: {\n category: 'A01',\n name: 'Broken Access Control',\n description: 'Restrictions on authenticated users are not properly enforced.',\n cweIds: [200, 201, 284, 285, 352, 359, 732, 862, 863, 913],\n },\n A02: {\n category: 'A02',\n name: 'Cryptographic Failures',\n description: 'Failures related to cryptography which often lead to exposure of sensitive data.',\n cweIds: [261, 296, 310, 312, 315, 319, 321, 326, 327, 328, 330, 331, 335, 336, 337, 338, 340, 347, 523, 720, 757, 759, 760, 780, 818, 916],\n },\n A03: {\n category: 'A03',\n name: 'Injection',\n description: 'User-supplied data is not validated, filtered, or sanitized by the application.',\n cweIds: [20, 74, 77, 78, 79, 88, 89, 90, 91, 93, 94, 95, 116, 943],\n },\n A04: {\n category: 'A04',\n name: 'Insecure Design',\n description: 'Missing or ineffective control design.',\n cweIds: [73, 183, 209, 213, 235, 256, 257, 266, 269, 280, 311, 312, 313, 316, 419, 434, 444, 451, 454, 602, 620, 636, 841, 862, 1004, 1173],\n },\n A05: {\n category: 'A05',\n name: 'Security Misconfiguration',\n description: 'Missing appropriate security hardening across any part of the application stack.',\n cweIds: [2, 11, 13, 15, 16, 260, 315, 520, 526, 537, 541, 548, 732],\n },\n A06: {\n category: 'A06',\n name: 'Vulnerable and Outdated Components',\n description: 'Components with known vulnerabilities are used.',\n cweIds: [1035, 1104],\n },\n A07: {\n category: 'A07',\n name: 'Identification and Authentication Failures',\n description: 'Confirmation of user identity, authentication, and session management failures.',\n cweIds: [255, 259, 287, 288, 290, 294, 295, 297, 300, 302, 304, 306, 307, 346, 384, 521, 613, 620, 640, 798, 940, 1216],\n },\n A08: {\n category: 'A08',\n name: 'Software and Data Integrity Failures',\n description: 'Code and infrastructure that does not protect against integrity violations.',\n cweIds: [345, 353, 426, 494, 502, 565, 784, 829, 830, 915],\n },\n A09: {\n category: 'A09',\n name: 'Security Logging and Monitoring Failures',\n description: 'Insufficient logging, detection, monitoring, and active response.',\n cweIds: [117, 223, 532, 778],\n },\n A10: {\n category: 'A10',\n name: 'Server-Side Request Forgery',\n description: 'Web application fetches a remote resource without validating user-supplied URL.',\n cweIds: [918],\n },\n};\n\n/** Map a CVE's summary/description to the most likely OWASP category. */\nexport function mapCveToOwasp(summary: string, packageName: string): OwaspCategory {\n const text = (summary + ' ' + packageName).toLowerCase();\n if (/inject|sql|xss|cross.site|script|command.inject|ldap|xpath/i.test(text)) return 'A03';\n if (/auth|authentication|session|credential|password|token|csrf|bypass/i.test(text)) return 'A07';\n if (/access.control|privilege|permission|authoriz|rbac|idor/i.test(text)) return 'A01';\n if (/crypto|encrypt|tls|ssl|cipher|hash|random|certificate/i.test(text)) return 'A02';\n if (/deserializ|pickle|marshal|prototype.pollution|supply.chain|integrity/i.test(text)) return 'A08';\n if (/ssrf|request.forgery|server.side/i.test(text)) return 'A10';\n if (/config|misconfig|default|expose|disclose|information/i.test(text)) return 'A05';\n if (/log|monitor|audit|trace/i.test(text)) return 'A09';\n return 'A06'; // default: vulnerable component\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }