@cdxgen/cdxgen 13.5.0 → 13.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (380) hide show
  1. package/README.md +17 -10
  2. package/bin/audit.js +7 -4
  3. package/bin/cdxgen.js +260 -37
  4. package/bin/convert.js +146 -22
  5. package/bin/evinse.js +28 -3
  6. package/bin/repl.js +47 -3
  7. package/bin/sign.js +211 -34
  8. package/bin/tracebom.js +18 -6
  9. package/bin/validate.js +24 -3
  10. package/bin/verify.js +113 -5
  11. package/data/behavior-taxonomy.schema.json +1491 -0
  12. package/data/cyclonedx-2.0-bundled.schema.json +18606 -5528
  13. package/data/cyclonedx-2.0-cryptography-defs.schema.json +857 -0
  14. package/data/license-aliases.json +24 -2
  15. package/data/pqc-migration.json +239 -0
  16. package/data/remediations.json +176 -0
  17. package/data/rules/ai-bom.yaml +1 -1
  18. package/data/rules/brotli-decoder.yaml +107 -0
  19. package/data/rules/cbom-security.yaml +4 -3
  20. package/data/rules/package-integrity.yaml +28 -0
  21. package/data/rules/vscode-extensions.yaml +75 -0
  22. package/data/spdx-license-list.json +121 -7
  23. package/data/spdx-licenses.json +69 -0
  24. package/data/spdx.schema.json +845 -2
  25. package/lib/audit/index.js +25 -3
  26. package/lib/cli/bomAssembly.js +172 -4
  27. package/lib/cli/cliOptions.js +121 -17
  28. package/lib/cli/index.js +720 -902
  29. package/lib/cli/jsBom.js +156 -64
  30. package/lib/cli/jvmBom.js +602 -86
  31. package/lib/cli/managedBom.js +161 -19
  32. package/lib/cli/nativeBom.js +52 -5
  33. package/lib/core/boundedFile.js +344 -0
  34. package/lib/core/brotliProbe.js +182 -0
  35. package/lib/core/env.js +34 -0
  36. package/lib/core/fs.js +138 -3
  37. package/lib/core/globPatterns.js +218 -0
  38. package/lib/core/httpClient.js +98 -1
  39. package/lib/core/lockPaths.js +38 -0
  40. package/lib/core/paths.js +24 -1
  41. package/lib/core/processTree.js +100 -8
  42. package/lib/core/projectConfig.js +332 -25
  43. package/lib/core/toolRegistry.js +184 -0
  44. package/lib/ecosystems/cppEvidence.js +263 -106
  45. package/lib/ecosystems/cppIncludeResolver.js +16 -5
  46. package/lib/ecosystems/denoutils.js +2 -2
  47. package/lib/ecosystems/ecosystems.js +25 -10
  48. package/lib/ecosystems/gemHostProbe.js +301 -0
  49. package/lib/ecosystems/golem.js +3 -8
  50. package/lib/ecosystems/gradleutils.js +1909 -229
  51. package/lib/ecosystems/jsEvidence.js +90 -38
  52. package/lib/ecosystems/kosi.js +3 -5
  53. package/lib/ecosystems/npmVersionResolution.js +376 -0
  54. package/lib/ecosystems/parsers-bazel.js +107 -6
  55. package/lib/ecosystems/parsers-js.js +505 -22
  56. package/lib/ecosystems/parsers-misc.js +209 -20
  57. package/lib/ecosystems/parsers-python.js +178 -30
  58. package/lib/ecosystems/parsers-rust.js +117 -15
  59. package/lib/ecosystems/pythonutils.js +128 -2
  60. package/lib/ecosystems/remote/huggingface.js +22 -0
  61. package/lib/ecosystems/rubyutils.js +538 -31
  62. package/lib/ecosystems/rusi.js +2 -4
  63. package/lib/ecosystems/scalacliutils.js +2 -0
  64. package/lib/ecosystems/scalasem.js +798 -152
  65. package/lib/ecosystems/vendoredCode.js +237 -3
  66. package/lib/ecosystems/venvProbe.js +360 -0
  67. package/lib/evinser/evinser.js +536 -71
  68. package/lib/evinser/scalasem.js +5 -1
  69. package/lib/helpers/agenticToolutils.js +525 -94
  70. package/lib/helpers/bomSigner.js +43 -9
  71. package/lib/helpers/jssSigner.js +1276 -0
  72. package/lib/helpers/vsixutils.js +1574 -315
  73. package/lib/inventory/agentBlueprint.js +193 -0
  74. package/lib/inventory/agentToolNames.js +145 -0
  75. package/lib/inventory/aiCollector.js +153 -7
  76. package/lib/inventory/aiInventory.js +44 -8
  77. package/lib/inventory/aiProviders.js +324 -0
  78. package/lib/inventory/atomUtils.js +77 -0
  79. package/lib/inventory/bomUtils.js +8 -1
  80. package/lib/inventory/brotliDecoder.js +142 -0
  81. package/lib/inventory/buildToolRateLimit.js +1 -1
  82. package/lib/inventory/cbomutils.js +56 -7
  83. package/lib/inventory/ciParsers/githubActionsLock.js +821 -0
  84. package/lib/inventory/citations.js +31 -2
  85. package/lib/inventory/communityAiConfigParser.js +978 -80
  86. package/lib/inventory/cyclonedx20.js +152 -0
  87. package/lib/inventory/cyclonedx20Common.js +286 -0
  88. package/lib/inventory/cyclonedx20Derived.js +159 -0
  89. package/lib/inventory/cyclonedx20Parties.js +552 -0
  90. package/lib/inventory/cyclonedx20Read.js +768 -0
  91. package/lib/inventory/cyclonedx20ReadCommon.js +374 -0
  92. package/lib/inventory/cyclonedx20ReadComponents.js +692 -0
  93. package/lib/inventory/cyclonedx20ReadContext.js +380 -0
  94. package/lib/inventory/cyclonedx20ReadEvidence.js +466 -0
  95. package/lib/inventory/cyclonedx20ReadSections.js +599 -0
  96. package/lib/inventory/cyclonedx20Render.js +766 -0
  97. package/lib/inventory/cyclonedx20RenderComponents.js +716 -0
  98. package/lib/inventory/cyclonedx20RenderDefinitions.js +405 -0
  99. package/lib/inventory/cyclonedx20RenderEvidence.js +726 -0
  100. package/lib/inventory/cyclonedx20RenderHardware.js +203 -0
  101. package/lib/inventory/cyclonedx20RenderPatents.js +174 -0
  102. package/lib/inventory/cyclonedx20RenderRefIds.js +314 -0
  103. package/lib/inventory/cyclonedx20RenderSections.js +499 -0
  104. package/lib/inventory/cyclonedx20Tables.js +594 -0
  105. package/lib/inventory/deps.js +141 -13
  106. package/lib/inventory/dosai.js +375 -6
  107. package/lib/inventory/dosaiParsers.js +3 -6
  108. package/lib/inventory/dotnetRuntime.js +367 -0
  109. package/lib/inventory/ecosystemFormulationParsers.js +979 -0
  110. package/lib/inventory/envcontext.js +436 -48
  111. package/lib/inventory/evidenceUtils.js +13 -1
  112. package/lib/inventory/fetchBatch.js +1 -1
  113. package/lib/inventory/formulationParsers.js +124 -14
  114. package/lib/inventory/gtfobins.js +13 -0
  115. package/lib/inventory/hbom.js +45 -6
  116. package/lib/inventory/hbomLoader.js +166 -0
  117. package/lib/inventory/hostRuntimeProbe.js +686 -0
  118. package/lib/inventory/jvmLocalRepos.js +9 -2
  119. package/lib/inventory/jvmToolEnv.js +29 -0
  120. package/lib/inventory/licenseEnhancer.js +12 -0
  121. package/lib/inventory/mavenCentralMirror.js +534 -0
  122. package/lib/inventory/mcpConfigParser.js +5 -0
  123. package/lib/inventory/nodeBuildInfo.js +218 -0
  124. package/lib/inventory/nodeHostProbe.js +202 -0
  125. package/lib/inventory/occurrenceKey.js +90 -0
  126. package/lib/inventory/osPackageResolver.js +182 -0
  127. package/lib/inventory/phpBuildInfo.js +10 -59
  128. package/lib/inventory/phpHostProbe.js +32 -488
  129. package/lib/inventory/pqcMigration.js +426 -0
  130. package/lib/inventory/rubyBuildInfo.js +972 -0
  131. package/lib/inventory/rubyHostProbe.js +218 -0
  132. package/lib/inventory/rustFormulationParser.js +21 -10
  133. package/lib/inventory/scalaCoords.js +4 -3
  134. package/lib/inventory/scalaDedupe.js +440 -0
  135. package/lib/inventory/source.js +114 -8
  136. package/lib/managers/binary.js +337 -3
  137. package/lib/managers/docker.js +79 -0
  138. package/lib/parsers/huggingfaceManifest.js +9 -1
  139. package/lib/parsers/huggingfaceUtils.js +18 -0
  140. package/lib/parsers/kiroPermissions.js +166 -0
  141. package/lib/parsers/largeJson.js +28 -11
  142. package/lib/parsers/vscodeExtensionId.js +183 -0
  143. package/lib/server/server.js +48 -35
  144. package/lib/stages/postgen/postgen.js +41 -1
  145. package/lib/stages/postgen/ruleEngine.js +13 -5
  146. package/lib/stages/postgen/specVersionCompat.js +76 -0
  147. package/lib/stages/pregen/envAudit.js +1 -0
  148. package/lib/stages/pregen/pregen.js +114 -57
  149. package/lib/validator/bomValidator.js +14 -2
  150. package/lib/validator/complianceEngine.js +30 -3
  151. package/lib/validator/complianceRules.js +1416 -4
  152. package/lib/validator/generated/validate-1.6.mjs +1 -1
  153. package/lib/validator/generated/validate-1.7.mjs +1 -1
  154. package/lib/validator/generated/validate-2.0.mjs +57554 -13851
  155. package/lib/validator/index.js +49 -8
  156. package/lib/validator/reporters/json.js +6 -0
  157. package/package.json +11 -10
  158. package/types/bin/repl.d.ts.map +1 -1
  159. package/types/lib/audit/index.d.ts +6 -2
  160. package/types/lib/audit/index.d.ts.map +1 -1
  161. package/types/lib/cli/bomAssembly.d.ts +29 -1
  162. package/types/lib/cli/bomAssembly.d.ts.map +1 -1
  163. package/types/lib/cli/cliOptions.d.ts +6 -0
  164. package/types/lib/cli/cliOptions.d.ts.map +1 -1
  165. package/types/lib/cli/index.d.ts.map +1 -1
  166. package/types/lib/cli/jsBom.d.ts +3 -18
  167. package/types/lib/cli/jsBom.d.ts.map +1 -1
  168. package/types/lib/cli/jvmBom.d.ts +15 -0
  169. package/types/lib/cli/jvmBom.d.ts.map +1 -1
  170. package/types/lib/cli/managedBom.d.ts.map +1 -1
  171. package/types/lib/cli/nativeBom.d.ts.map +1 -1
  172. package/types/lib/core/boundedFile.d.ts +100 -0
  173. package/types/lib/core/boundedFile.d.ts.map +1 -0
  174. package/types/lib/core/brotliProbe.d.ts +37 -0
  175. package/types/lib/core/brotliProbe.d.ts.map +1 -0
  176. package/types/lib/core/env.d.ts +14 -0
  177. package/types/lib/core/env.d.ts.map +1 -1
  178. package/types/lib/core/fs.d.ts +4 -0
  179. package/types/lib/core/fs.d.ts.map +1 -1
  180. package/types/lib/core/globPatterns.d.ts +70 -0
  181. package/types/lib/core/globPatterns.d.ts.map +1 -0
  182. package/types/lib/core/httpClient.d.ts +24 -0
  183. package/types/lib/core/httpClient.d.ts.map +1 -1
  184. package/types/lib/core/lockPaths.d.ts +19 -0
  185. package/types/lib/core/lockPaths.d.ts.map +1 -0
  186. package/types/lib/core/paths.d.ts +9 -0
  187. package/types/lib/core/paths.d.ts.map +1 -1
  188. package/types/lib/core/processTree.d.ts +17 -4
  189. package/types/lib/core/processTree.d.ts.map +1 -1
  190. package/types/lib/core/projectConfig.d.ts +47 -8
  191. package/types/lib/core/projectConfig.d.ts.map +1 -1
  192. package/types/lib/core/toolRegistry.d.ts +36 -0
  193. package/types/lib/core/toolRegistry.d.ts.map +1 -0
  194. package/types/lib/ecosystems/cppEvidence.d.ts +40 -13
  195. package/types/lib/ecosystems/cppEvidence.d.ts.map +1 -1
  196. package/types/lib/ecosystems/cppIncludeResolver.d.ts +2 -1
  197. package/types/lib/ecosystems/cppIncludeResolver.d.ts.map +1 -1
  198. package/types/lib/ecosystems/ecosystems.d.ts.map +1 -1
  199. package/types/lib/ecosystems/gemHostProbe.d.ts +28 -0
  200. package/types/lib/ecosystems/gemHostProbe.d.ts.map +1 -0
  201. package/types/lib/ecosystems/golem.d.ts.map +1 -1
  202. package/types/lib/ecosystems/gradleutils.d.ts +294 -20
  203. package/types/lib/ecosystems/gradleutils.d.ts.map +1 -1
  204. package/types/lib/ecosystems/jsEvidence.d.ts +14 -1
  205. package/types/lib/ecosystems/jsEvidence.d.ts.map +1 -1
  206. package/types/lib/ecosystems/kosi.d.ts.map +1 -1
  207. package/types/lib/ecosystems/npmVersionResolution.d.ts +119 -0
  208. package/types/lib/ecosystems/npmVersionResolution.d.ts.map +1 -0
  209. package/types/lib/ecosystems/parsers-bazel.d.ts.map +1 -1
  210. package/types/lib/ecosystems/parsers-js.d.ts +17 -20
  211. package/types/lib/ecosystems/parsers-js.d.ts.map +1 -1
  212. package/types/lib/ecosystems/parsers-misc.d.ts +19 -0
  213. package/types/lib/ecosystems/parsers-misc.d.ts.map +1 -1
  214. package/types/lib/ecosystems/parsers-python.d.ts +10 -0
  215. package/types/lib/ecosystems/parsers-python.d.ts.map +1 -1
  216. package/types/lib/ecosystems/parsers-rust.d.ts.map +1 -1
  217. package/types/lib/ecosystems/pythonutils.d.ts +19 -1
  218. package/types/lib/ecosystems/pythonutils.d.ts.map +1 -1
  219. package/types/lib/ecosystems/remote/huggingface.d.ts.map +1 -1
  220. package/types/lib/ecosystems/rubyutils.d.ts +144 -12
  221. package/types/lib/ecosystems/rubyutils.d.ts.map +1 -1
  222. package/types/lib/ecosystems/rusi.d.ts.map +1 -1
  223. package/types/lib/ecosystems/scalacliutils.d.ts.map +1 -1
  224. package/types/lib/ecosystems/scalasem.d.ts +58 -16
  225. package/types/lib/ecosystems/scalasem.d.ts.map +1 -1
  226. package/types/lib/ecosystems/vendoredCode.d.ts +26 -0
  227. package/types/lib/ecosystems/vendoredCode.d.ts.map +1 -1
  228. package/types/lib/ecosystems/venvProbe.d.ts +40 -0
  229. package/types/lib/ecosystems/venvProbe.d.ts.map +1 -0
  230. package/types/lib/evinser/evinser.d.ts +120 -13
  231. package/types/lib/evinser/evinser.d.ts.map +1 -1
  232. package/types/lib/evinser/scalasem.d.ts.map +1 -1
  233. package/types/lib/helpers/agenticToolutils.d.ts +53 -19
  234. package/types/lib/helpers/agenticToolutils.d.ts.map +1 -1
  235. package/types/lib/helpers/bomSigner.d.ts +20 -3
  236. package/types/lib/helpers/bomSigner.d.ts.map +1 -1
  237. package/types/lib/helpers/jssSigner.d.ts +288 -0
  238. package/types/lib/helpers/jssSigner.d.ts.map +1 -0
  239. package/types/lib/helpers/vsixutils.d.ts +303 -19
  240. package/types/lib/helpers/vsixutils.d.ts.map +1 -1
  241. package/types/lib/inventory/agentBlueprint.d.ts +70 -0
  242. package/types/lib/inventory/agentBlueprint.d.ts.map +1 -0
  243. package/types/lib/inventory/agentToolNames.d.ts +51 -0
  244. package/types/lib/inventory/agentToolNames.d.ts.map +1 -0
  245. package/types/lib/inventory/aiCollector.d.ts.map +1 -1
  246. package/types/lib/inventory/aiInventory.d.ts.map +1 -1
  247. package/types/lib/inventory/aiProviders.d.ts +85 -0
  248. package/types/lib/inventory/aiProviders.d.ts.map +1 -0
  249. package/types/lib/inventory/atomUtils.d.ts +19 -0
  250. package/types/lib/inventory/atomUtils.d.ts.map +1 -1
  251. package/types/lib/inventory/bomUtils.d.ts.map +1 -1
  252. package/types/lib/inventory/brotliDecoder.d.ts +58 -0
  253. package/types/lib/inventory/brotliDecoder.d.ts.map +1 -0
  254. package/types/lib/inventory/cbomutils.d.ts +17 -0
  255. package/types/lib/inventory/cbomutils.d.ts.map +1 -1
  256. package/types/lib/inventory/ciParsers/githubActionsLock.d.ts +101 -0
  257. package/types/lib/inventory/ciParsers/githubActionsLock.d.ts.map +1 -0
  258. package/types/lib/inventory/citations.d.ts +5 -0
  259. package/types/lib/inventory/citations.d.ts.map +1 -1
  260. package/types/lib/inventory/communityAiConfigParser.d.ts.map +1 -1
  261. package/types/lib/inventory/cyclonedx20.d.ts +99 -0
  262. package/types/lib/inventory/cyclonedx20.d.ts.map +1 -0
  263. package/types/lib/inventory/cyclonedx20Common.d.ts +102 -0
  264. package/types/lib/inventory/cyclonedx20Common.d.ts.map +1 -0
  265. package/types/lib/inventory/cyclonedx20Derived.d.ts +74 -0
  266. package/types/lib/inventory/cyclonedx20Derived.d.ts.map +1 -0
  267. package/types/lib/inventory/cyclonedx20Parties.d.ts +91 -0
  268. package/types/lib/inventory/cyclonedx20Parties.d.ts.map +1 -0
  269. package/types/lib/inventory/cyclonedx20Read.d.ts +51 -0
  270. package/types/lib/inventory/cyclonedx20Read.d.ts.map +1 -0
  271. package/types/lib/inventory/cyclonedx20ReadCommon.d.ts +69 -0
  272. package/types/lib/inventory/cyclonedx20ReadCommon.d.ts.map +1 -0
  273. package/types/lib/inventory/cyclonedx20ReadComponents.d.ts +77 -0
  274. package/types/lib/inventory/cyclonedx20ReadComponents.d.ts.map +1 -0
  275. package/types/lib/inventory/cyclonedx20ReadContext.d.ts +118 -0
  276. package/types/lib/inventory/cyclonedx20ReadContext.d.ts.map +1 -0
  277. package/types/lib/inventory/cyclonedx20ReadEvidence.d.ts +40 -0
  278. package/types/lib/inventory/cyclonedx20ReadEvidence.d.ts.map +1 -0
  279. package/types/lib/inventory/cyclonedx20ReadSections.d.ts +45 -0
  280. package/types/lib/inventory/cyclonedx20ReadSections.d.ts.map +1 -0
  281. package/types/lib/inventory/cyclonedx20Render.d.ts +53 -0
  282. package/types/lib/inventory/cyclonedx20Render.d.ts.map +1 -0
  283. package/types/lib/inventory/cyclonedx20RenderComponents.d.ts +73 -0
  284. package/types/lib/inventory/cyclonedx20RenderComponents.d.ts.map +1 -0
  285. package/types/lib/inventory/cyclonedx20RenderDefinitions.d.ts +29 -0
  286. package/types/lib/inventory/cyclonedx20RenderDefinitions.d.ts.map +1 -0
  287. package/types/lib/inventory/cyclonedx20RenderEvidence.d.ts +110 -0
  288. package/types/lib/inventory/cyclonedx20RenderEvidence.d.ts.map +1 -0
  289. package/types/lib/inventory/cyclonedx20RenderHardware.d.ts +42 -0
  290. package/types/lib/inventory/cyclonedx20RenderHardware.d.ts.map +1 -0
  291. package/types/lib/inventory/cyclonedx20RenderPatents.d.ts +26 -0
  292. package/types/lib/inventory/cyclonedx20RenderPatents.d.ts.map +1 -0
  293. package/types/lib/inventory/cyclonedx20RenderRefIds.d.ts +55 -0
  294. package/types/lib/inventory/cyclonedx20RenderRefIds.d.ts.map +1 -0
  295. package/types/lib/inventory/cyclonedx20RenderSections.d.ts +45 -0
  296. package/types/lib/inventory/cyclonedx20RenderSections.d.ts.map +1 -0
  297. package/types/lib/inventory/cyclonedx20Tables.d.ts +134 -0
  298. package/types/lib/inventory/cyclonedx20Tables.d.ts.map +1 -0
  299. package/types/lib/inventory/deps.d.ts +35 -2
  300. package/types/lib/inventory/deps.d.ts.map +1 -1
  301. package/types/lib/inventory/dosai.d.ts +36 -1
  302. package/types/lib/inventory/dosai.d.ts.map +1 -1
  303. package/types/lib/inventory/dosaiParsers.d.ts.map +1 -1
  304. package/types/lib/inventory/dotnetRuntime.d.ts +91 -0
  305. package/types/lib/inventory/dotnetRuntime.d.ts.map +1 -0
  306. package/types/lib/inventory/ecosystemFormulationParsers.d.ts +73 -0
  307. package/types/lib/inventory/ecosystemFormulationParsers.d.ts.map +1 -0
  308. package/types/lib/inventory/envcontext.d.ts +74 -12
  309. package/types/lib/inventory/envcontext.d.ts.map +1 -1
  310. package/types/lib/inventory/evidenceUtils.d.ts.map +1 -1
  311. package/types/lib/inventory/formulationParsers.d.ts.map +1 -1
  312. package/types/lib/inventory/gtfobins.d.ts.map +1 -1
  313. package/types/lib/inventory/hbom.d.ts +11 -0
  314. package/types/lib/inventory/hbom.d.ts.map +1 -1
  315. package/types/lib/inventory/hbomLoader.d.ts +54 -0
  316. package/types/lib/inventory/hbomLoader.d.ts.map +1 -1
  317. package/types/lib/inventory/hostRuntimeProbe.d.ts +44 -0
  318. package/types/lib/inventory/hostRuntimeProbe.d.ts.map +1 -0
  319. package/types/lib/inventory/jvmLocalRepos.d.ts +5 -1
  320. package/types/lib/inventory/jvmLocalRepos.d.ts.map +1 -1
  321. package/types/lib/inventory/jvmToolEnv.d.ts +12 -0
  322. package/types/lib/inventory/jvmToolEnv.d.ts.map +1 -1
  323. package/types/lib/inventory/licenseEnhancer.d.ts.map +1 -1
  324. package/types/lib/inventory/mavenCentralMirror.d.ts +170 -0
  325. package/types/lib/inventory/mavenCentralMirror.d.ts.map +1 -0
  326. package/types/lib/inventory/mcpConfigParser.d.ts.map +1 -1
  327. package/types/lib/inventory/nodeBuildInfo.d.ts +95 -0
  328. package/types/lib/inventory/nodeBuildInfo.d.ts.map +1 -0
  329. package/types/lib/inventory/nodeHostProbe.d.ts +15 -0
  330. package/types/lib/inventory/nodeHostProbe.d.ts.map +1 -0
  331. package/types/lib/inventory/occurrenceKey.d.ts +52 -0
  332. package/types/lib/inventory/occurrenceKey.d.ts.map +1 -0
  333. package/types/lib/inventory/osPackageResolver.d.ts +38 -0
  334. package/types/lib/inventory/osPackageResolver.d.ts.map +1 -1
  335. package/types/lib/inventory/phpBuildInfo.d.ts.map +1 -1
  336. package/types/lib/inventory/phpHostProbe.d.ts.map +1 -1
  337. package/types/lib/inventory/pqcMigration.d.ts +84 -0
  338. package/types/lib/inventory/pqcMigration.d.ts.map +1 -0
  339. package/types/lib/inventory/rubyBuildInfo.d.ts +271 -0
  340. package/types/lib/inventory/rubyBuildInfo.d.ts.map +1 -0
  341. package/types/lib/inventory/rubyHostProbe.d.ts +47 -0
  342. package/types/lib/inventory/rubyHostProbe.d.ts.map +1 -0
  343. package/types/lib/inventory/rustFormulationParser.d.ts +7 -2
  344. package/types/lib/inventory/rustFormulationParser.d.ts.map +1 -1
  345. package/types/lib/inventory/scalaCoords.d.ts.map +1 -1
  346. package/types/lib/inventory/scalaDedupe.d.ts +43 -0
  347. package/types/lib/inventory/scalaDedupe.d.ts.map +1 -0
  348. package/types/lib/inventory/source.d.ts +25 -0
  349. package/types/lib/inventory/source.d.ts.map +1 -1
  350. package/types/lib/managers/binary.d.ts.map +1 -1
  351. package/types/lib/managers/docker.d.ts +12 -0
  352. package/types/lib/managers/docker.d.ts.map +1 -1
  353. package/types/lib/parsers/huggingfaceManifest.d.ts +10 -1
  354. package/types/lib/parsers/huggingfaceManifest.d.ts.map +1 -1
  355. package/types/lib/parsers/huggingfaceUtils.d.ts +12 -0
  356. package/types/lib/parsers/huggingfaceUtils.d.ts.map +1 -1
  357. package/types/lib/parsers/kiroPermissions.d.ts +62 -0
  358. package/types/lib/parsers/kiroPermissions.d.ts.map +1 -0
  359. package/types/lib/parsers/largeJson.d.ts +4 -3
  360. package/types/lib/parsers/largeJson.d.ts.map +1 -1
  361. package/types/lib/parsers/vscodeExtensionId.d.ts +48 -0
  362. package/types/lib/parsers/vscodeExtensionId.d.ts.map +1 -0
  363. package/types/lib/server/server.d.ts.map +1 -1
  364. package/types/lib/stages/postgen/postgen.d.ts +7 -0
  365. package/types/lib/stages/postgen/postgen.d.ts.map +1 -1
  366. package/types/lib/stages/postgen/ruleEngine.d.ts.map +1 -1
  367. package/types/lib/stages/postgen/specVersionCompat.d.ts +25 -0
  368. package/types/lib/stages/postgen/specVersionCompat.d.ts.map +1 -1
  369. package/types/lib/stages/pregen/envAudit.d.ts.map +1 -1
  370. package/types/lib/stages/pregen/pregen.d.ts +12 -8
  371. package/types/lib/stages/pregen/pregen.d.ts.map +1 -1
  372. package/types/lib/validator/bomValidator.d.ts +5 -1
  373. package/types/lib/validator/bomValidator.d.ts.map +1 -1
  374. package/types/lib/validator/complianceEngine.d.ts +4 -4
  375. package/types/lib/validator/complianceEngine.d.ts.map +1 -1
  376. package/types/lib/validator/complianceRules.d.ts +14 -2
  377. package/types/lib/validator/complianceRules.d.ts.map +1 -1
  378. package/types/lib/validator/index.d.ts +10 -0
  379. package/types/lib/validator/index.d.ts.map +1 -1
  380. package/types/lib/validator/reporters/json.d.ts.map +1 -1
@@ -43,6 +43,7 @@ const AI_INVENTORY_FILE_KINDS = new Set([
43
43
  "agent-config",
44
44
  "agent-definition",
45
45
  "agent-instructions",
46
+ "agent-spec",
46
47
  "ai-agent-file",
47
48
  "copilot-instructions",
48
49
  "copilot-setup-workflow",
@@ -52,6 +53,10 @@ const AI_INVENTORY_FILE_KINDS = new Set([
52
53
  "custom-command",
53
54
  "custom-tool",
54
55
  "graph-definition",
56
+ "hook-file",
57
+ "permission-policy",
58
+ "settings",
59
+ "workflow-file",
55
60
  AI_SKILL_FILE_KIND,
56
61
  ]);
57
62
 
@@ -80,6 +85,11 @@ const AI_INVENTORY_PARSERS = [
80
85
  id: communityAiConfigParser.id,
81
86
  parser: communityAiConfigParser,
82
87
  types: ["ai-skill"],
88
+ // The community agent configurations (.kiro, .cursor/rules,
89
+ // .claude/agents, and similar) also belong in an AI-BOM next to the
90
+ // models and services, so `-t ai` runs this parser and keeps its
91
+ // ai-skill components.
92
+ aiOverlay: true,
83
93
  },
84
94
  ];
85
95
 
@@ -301,8 +311,23 @@ export function collectAiInventory(discoveryPath, options, types) {
301
311
  let components = [];
302
312
  const dependencies = [];
303
313
  let services = [];
314
+ // Output of an aiOverlay parser that runs only because `-t ai` was
315
+ // requested. It is filtered with ai-skill added to the requested types, and
316
+ // kept apart so the extra type never widens the filter for other parsers
317
+ // or the language collectors. `--exclude-type ai-skill` turns it off.
318
+ const overlayTypes = uniqueNonEmptyTypes([...requestedTypes, "ai-skill"]);
319
+ const overlayEnabled =
320
+ requestedTypes.includes("ai") &&
321
+ !requestedTypes.includes("ai-skill") &&
322
+ !optionIncludesAiInventoryProjectType(options?.excludeType, "ai-skill");
323
+ let overlayComponents = [];
324
+ let overlayServices = [];
304
325
  for (const parserEntry of AI_INVENTORY_PARSERS) {
305
- if (!parserEntry.types.some((type) => requestedTypes.includes(type))) {
326
+ const requested = parserEntry.types.some((type) =>
327
+ requestedTypes.includes(type),
328
+ );
329
+ const isOverlay = !requested && overlayEnabled && parserEntry.aiOverlay;
330
+ if (!requested && !isOverlay) {
306
331
  continue;
307
332
  }
308
333
  const matchedFiles = [];
@@ -326,11 +351,20 @@ export function collectAiInventory(discoveryPath, options, types) {
326
351
  );
327
352
  continue;
328
353
  }
329
- if (result?.components?.length) {
330
- components = components.concat(result.components);
331
- }
332
- if (result?.services?.length) {
333
- services = mergeServices(services, result.services);
354
+ if (isOverlay) {
355
+ overlayComponents = overlayComponents.concat(
356
+ filterInventorySubjectsByTypes(result?.components, overlayTypes),
357
+ );
358
+ overlayServices = overlayServices.concat(
359
+ filterInventorySubjectsByTypes(result?.services, overlayTypes),
360
+ );
361
+ } else {
362
+ if (result?.components?.length) {
363
+ components = components.concat(result.components);
364
+ }
365
+ if (result?.services?.length) {
366
+ services = mergeServices(services, result.services);
367
+ }
334
368
  }
335
369
  if (result?.dependencies?.length) {
336
370
  dependencies.push(...result.dependencies);
@@ -365,11 +399,13 @@ export function collectAiInventory(discoveryPath, options, types) {
365
399
  }
366
400
 
367
401
  components = trimComponents(
368
- filterInventorySubjectsByTypes(components, requestedTypes),
402
+ filterInventorySubjectsByTypes(components, requestedTypes).concat(
403
+ overlayComponents,
404
+ ),
369
405
  );
370
406
  services = mergeServices(
371
- [],
372
407
  filterInventorySubjectsByTypes(services, requestedTypes),
408
+ overlayServices,
373
409
  );
374
410
  return {
375
411
  components,
@@ -0,0 +1,324 @@
1
+ /**
2
+ * Organisations that create AI models, keyed by the short creator id cdxgen
3
+ * uses internally. The value is the full organisation name written to the
4
+ * `manufacturer` of a model component, since the minimum elements guidance
5
+ * asks for full names rather than acronyms or product names.
6
+ */
7
+ export const MODEL_CREATOR_NAMES = new Map([
8
+ ["alibaba", "Alibaba Cloud"],
9
+ ["anthropic", "Anthropic"],
10
+ ["cohere", "Cohere"],
11
+ ["deepseek", "DeepSeek"],
12
+ ["google", "Google"],
13
+ ["meta", "Meta"],
14
+ ["mistral", "Mistral AI"],
15
+ ["openai", "OpenAI"],
16
+ ["xai", "xAI"],
17
+ ["zhipu", "Zhipu AI"],
18
+ ]);
19
+
20
+ /**
21
+ * Providers that are a creator's own SDK or API, mapped to that creator.
22
+ * Hosting, routing and local providers such as groq, together, fireworks,
23
+ * openrouter, replicate, aws-bedrock, azure-openai, vertex-ai, huggingface
24
+ * and ollama serve models other organisations made, so they are absent.
25
+ */
26
+ const CREATOR_OWN_PROVIDERS = new Map([
27
+ ["anthropic", "anthropic"],
28
+ ["cohere", "cohere"],
29
+ ["dashscope", "alibaba"],
30
+ ["deepseek", "deepseek"],
31
+ ["gemini", "google"],
32
+ ["google", "google"],
33
+ ["meta", "meta"],
34
+ ["mistral", "mistral"],
35
+ ["openai", "openai"],
36
+ ["xai", "xai"],
37
+ ["zhipu", "zhipu"],
38
+ ]);
39
+
40
+ // Creators whose own API serves only the models they made, so any model
41
+ // called through that API is theirs even when its name is not recognised.
42
+ // OpenAI-compatible clients, Google (Vertex Model Garden) and DashScope also
43
+ // serve models from other creators, so they are not in this set.
44
+ const SINGLE_CATALOGUE_CREATORS = new Set([
45
+ "anthropic",
46
+ "cohere",
47
+ "deepseek",
48
+ "mistral",
49
+ "xai",
50
+ "zhipu",
51
+ ]);
52
+
53
+ /**
54
+ * Local runtimes and inference servers. They serve whatever tag or served
55
+ * model name the user chose, so a model they run names no creator.
56
+ */
57
+ export const LOCAL_MODEL_RUNTIMES = new Set([
58
+ "gpt4all",
59
+ "jan",
60
+ "llama.cpp",
61
+ "llamafile",
62
+ "lm-studio",
63
+ "local",
64
+ "local-inference",
65
+ "mlc",
66
+ "ollama",
67
+ "vllm",
68
+ "xinference",
69
+ ]);
70
+
71
+ // Provider prefixes of model routes such as the litellm `groq/llama3-8b`
72
+ // form, mapped to the provider the route names. Matching is case-sensitive
73
+ // because the routes are lowercase while some Hugging Face organisations
74
+ // share the name in another case (Groq, Anthropic, Cohere). Prefixes that are
75
+ // also real lowercase Hub organisations (openai, google, databricks,
76
+ // cerebras, huggingface) are left out.
77
+ const MODEL_ROUTE_PROVIDERS = new Map([
78
+ ["anthropic", "anthropic"],
79
+ ["azure", "azure-openai"],
80
+ ["azure_ai", "azure-ai"],
81
+ ["bedrock", "aws-bedrock"],
82
+ ["codestral", "mistral"],
83
+ ["cohere", "cohere"],
84
+ ["cohere_chat", "cohere"],
85
+ ["dashscope", "dashscope"],
86
+ ["deepseek", "deepseek"],
87
+ ["fireworks_ai", "fireworks"],
88
+ ["friendliai", "friendliai"],
89
+ ["gemini", "gemini"],
90
+ ["groq", "groq"],
91
+ ["hosted_vllm", "vllm"],
92
+ ["llamafile", "llamafile"],
93
+ ["lm_studio", "lm-studio"],
94
+ ["mistral", "mistral"],
95
+ ["moonshot", "moonshot"],
96
+ ["nvidia_nim", "nvidia-nim"],
97
+ ["ollama", "ollama"],
98
+ ["ollama_chat", "ollama"],
99
+ ["openrouter", "openrouter"],
100
+ ["perplexity", "perplexity"],
101
+ ["replicate", "replicate"],
102
+ ["sagemaker", "aws-sagemaker"],
103
+ ["sambanova", "sambanova"],
104
+ ["together_ai", "together"],
105
+ ["vertex_ai", "vertex-ai"],
106
+ ["watsonx", "watsonx"],
107
+ ["xai", "xai"],
108
+ ["xinference", "xinference"],
109
+ ]);
110
+
111
+ // Google API resource collections that hold a model name, as in
112
+ // `models/gemini-1.5-flash` or `tunedModels/my-model`.
113
+ const GOOGLE_MODEL_COLLECTIONS = new Set(["models", "tunedModels"]);
114
+
115
+ // Model name prefixes that only one creator publishes under. A prefix, not a
116
+ // substring, so a community fine-tune such as openhermes-2.5-mistral-7b is
117
+ // not credited to Mistral AI. The OpenAI entries name its model lines,
118
+ // because a bare gpt prefix also covers open-weight families from other
119
+ // creators (gpt-j, gpt-neo, gpt-neox, gpt-sw3, gpt4all).
120
+ const MODEL_NAME_CREATOR_PREFIXES = [
121
+ ["chatgpt", "openai"],
122
+ ["claude", "anthropic"],
123
+ ["codestral", "mistral"],
124
+ ["command-r", "cohere"],
125
+ ["dall-e", "openai"],
126
+ ["deepseek", "deepseek"],
127
+ ["gemini", "google"],
128
+ ["gemma", "google"],
129
+ ["glm", "zhipu"],
130
+ ["gpt-3", "openai"],
131
+ ["gpt-4", "openai"],
132
+ ["gpt-5", "openai"],
133
+ ["gpt-audio", "openai"],
134
+ ["gpt-image", "openai"],
135
+ ["gpt-oss", "openai"],
136
+ ["gpt-realtime", "openai"],
137
+ ["gpt2", "openai"],
138
+ ["grok", "xai"],
139
+ ["llama", "meta"],
140
+ ["meta-llama", "meta"],
141
+ ["mistral", "mistral"],
142
+ ["mixtral", "mistral"],
143
+ ["qwen", "alibaba"],
144
+ ["text-embedding-3", "openai"],
145
+ ["text-embedding-ada", "openai"],
146
+ ];
147
+
148
+ // Spellings of a creator's name, compared after lowercasing and dropping
149
+ // everything but letters and digits. They cover the creator ids, the full
150
+ // names, the creators' own Hugging Face organisations and the way GGUF
151
+ // converters write general.organization ("Meta Llama", "Mistralai").
152
+ const MODEL_CREATOR_ALIASES = new Map([
153
+ ["alibaba", "alibaba"],
154
+ ["alibabacloud", "alibaba"],
155
+ ["qwen", "alibaba"],
156
+ ["anthropic", "anthropic"],
157
+ ["cohere", "cohere"],
158
+ ["cohereforai", "cohere"],
159
+ ["coherelabs", "cohere"],
160
+ ["deepseek", "deepseek"],
161
+ ["deepseekai", "deepseek"],
162
+ ["google", "google"],
163
+ ["googledeepmind", "google"],
164
+ ["facebook", "meta"],
165
+ ["meta", "meta"],
166
+ ["metallama", "meta"],
167
+ ["mistral", "mistral"],
168
+ ["mistralai", "mistral"],
169
+ ["openai", "openai"],
170
+ ["xai", "xai"],
171
+ ["xaiorg", "xai"],
172
+ ["thudm", "zhipu"],
173
+ ["zaiorg", "zhipu"],
174
+ ["zhipu", "zhipu"],
175
+ ["zhipuai", "zhipu"],
176
+ ]);
177
+
178
+ const normalizeProviderId = (provider) =>
179
+ typeof provider === "string" ? provider.trim().toLowerCase() : "";
180
+
181
+ const aliasKey = (value) =>
182
+ String(value || "")
183
+ .toLowerCase()
184
+ .replace(/[^a-z0-9]/gu, "");
185
+
186
+ /**
187
+ * Split a model reference written in source code into the route provider it
188
+ * names, if any, and the model name a creator lookup should read.
189
+ *
190
+ * `groq/llama3-8b-8192` names the groq route and the model `llama3-8b-8192`.
191
+ * `models/gemini-1.5-flash`, `tunedModels/x` and
192
+ * `projects/p/locations/l/publishers/google/models/gemini-1.5-pro` are Google
193
+ * API resource names, and the model is the part after the last `models`
194
+ * segment. Neither form is a Hugging Face repository id.
195
+ *
196
+ * @param {string} modelId Model reference as written in the source
197
+ * @returns {{ name: string, nonHub: boolean, route?: string, routeProvider?: string }}
198
+ * The model name, whether the reference is not a Hub repository id, and the
199
+ * route and its provider when one is named
200
+ */
201
+ export function splitModelReference(modelId) {
202
+ const value = String(modelId || "").trim();
203
+ const segments = value.split("/");
204
+ if (segments.length < 2 || segments.some((segment) => !segment)) {
205
+ return { name: value, nonHub: false };
206
+ }
207
+ if (GOOGLE_MODEL_COLLECTIONS.has(segments[0])) {
208
+ return { name: segments.slice(1).join("/"), nonHub: true };
209
+ }
210
+ const publishersIndex = segments.indexOf("publishers");
211
+ const modelsIndex = segments.lastIndexOf("models");
212
+ if (publishersIndex >= 0 && modelsIndex > publishersIndex) {
213
+ return { name: segments.slice(modelsIndex + 1).join("/"), nonHub: true };
214
+ }
215
+ const routeProvider = MODEL_ROUTE_PROVIDERS.get(segments[0]);
216
+ if (routeProvider) {
217
+ return {
218
+ name: segments.slice(1).join("/"),
219
+ nonHub: true,
220
+ route: segments[0],
221
+ routeProvider,
222
+ };
223
+ }
224
+ return { name: value, nonHub: false };
225
+ }
226
+
227
+ /**
228
+ * Name the creator of a model from its name alone, when only one creator
229
+ * publishes under that name.
230
+ *
231
+ * @param {string} modelName Model name without route or namespace
232
+ * @returns {string|undefined} Creator id
233
+ */
234
+ export function modelCreatorFromName(modelName) {
235
+ const normalized = String(modelName || "")
236
+ .trim()
237
+ .toLowerCase();
238
+ for (const [prefix, creator] of MODEL_NAME_CREATOR_PREFIXES) {
239
+ if (normalized.startsWith(prefix)) {
240
+ return creator;
241
+ }
242
+ }
243
+ return /^o[134](?:$|[-:])/u.test(normalized) ? "openai" : undefined;
244
+ }
245
+
246
+ /**
247
+ * Resolve a creator spelling, such as a Hugging Face organisation or a
248
+ * GGUF general.organization value, to a known creator id.
249
+ *
250
+ * @param {string} name Organisation name or namespace
251
+ * @returns {string|undefined} Creator id, or undefined when unknown
252
+ */
253
+ export function modelCreatorFromOrganization(name) {
254
+ return MODEL_CREATOR_ALIASES.get(aliasKey(name));
255
+ }
256
+
257
+ /**
258
+ * Pick the creator of a model that source code calls by name.
259
+ *
260
+ * The provider of such a model is the SDK, AI host or route the code uses,
261
+ * which names the client rather than the model: the openai SDK is the usual
262
+ * client for self-hosted Llama or DeepSeek servers, and a file may use
263
+ * several SDKs. So the creator is the one the model name names, when the
264
+ * provider is that creator, is a hosting or routing service, or the file
265
+ * also uses the creator's own SDK or host. A different creator's SDK leaves
266
+ * it unset. A model name that names no creator is credited only to a
267
+ * provider whose own API serves nothing but its own models. A local runtime
268
+ * serves whatever tag the user created, so it names no creator, and neither
269
+ * does a file that only uses a local runtime.
270
+ *
271
+ * @param {string} modelId Model reference as written in the source
272
+ * @param {{ provider?: string, fileProviders?: Iterable<string>, runtimes?: Iterable<string> }} [context]
273
+ * The provider the code declares through an SDK import, AI host or dosai
274
+ * report (never a guess from the model name), every provider the file
275
+ * references, and the runtimes it uses
276
+ * @returns {string|undefined} Creator id
277
+ */
278
+ export function resolveModelCreator(modelId, context = {}) {
279
+ const reference = splitModelReference(modelId);
280
+ const provider = normalizeProviderId(
281
+ reference.routeProvider || context.provider,
282
+ );
283
+ if (LOCAL_MODEL_RUNTIMES.has(provider)) {
284
+ return undefined;
285
+ }
286
+ if (
287
+ !provider &&
288
+ [...(context.runtimes || [])].some((runtime) =>
289
+ LOCAL_MODEL_RUNTIMES.has(normalizeProviderId(runtime)),
290
+ )
291
+ ) {
292
+ return undefined;
293
+ }
294
+ const nameCreator = modelCreatorFromName(reference.name);
295
+ const providerCreator = CREATOR_OWN_PROVIDERS.get(provider);
296
+ if (!nameCreator) {
297
+ return SINGLE_CATALOGUE_CREATORS.has(providerCreator)
298
+ ? providerCreator
299
+ : undefined;
300
+ }
301
+ if (!providerCreator || providerCreator === nameCreator) {
302
+ return nameCreator;
303
+ }
304
+ for (const fileProvider of context.fileProviders || []) {
305
+ if (
306
+ CREATOR_OWN_PROVIDERS.get(normalizeProviderId(fileProvider)) ===
307
+ nameCreator
308
+ ) {
309
+ return nameCreator;
310
+ }
311
+ }
312
+ return undefined;
313
+ }
314
+
315
+ /**
316
+ * Build the CycloneDX organisational entity for a creator id.
317
+ *
318
+ * @param {string} creator Creator id
319
+ * @returns {{ name: string }|undefined} Manufacturer entity
320
+ */
321
+ export function modelCreatorEntity(creator) {
322
+ const name = MODEL_CREATOR_NAMES.get(creator);
323
+ return name ? { name } : undefined;
324
+ }
@@ -183,6 +183,7 @@ export function findCompileCommands(src, options = {}) {
183
183
  }
184
184
 
185
185
  const atomFrontendArgKeysCache = new Map();
186
+ const atomOptionsCache = new Map();
186
187
 
187
188
  /**
188
189
  * Split an atom command that may carry a leading argument (`node
@@ -271,6 +272,43 @@ export function atomFrontendArgKeys(language) {
271
272
  return keys;
272
273
  }
273
274
 
275
+ /**
276
+ * The options the installed atom accepts, as `atom --help` lists them. Asked
277
+ * once per atom command. An atom that fails to start accepts none.
278
+ *
279
+ * @returns {Set<string>} Supported options, such as `--bom-file`
280
+ */
281
+ export function atomOptions() {
282
+ const command = getAtomCommand();
283
+ if (atomOptionsCache.has(command)) {
284
+ return atomOptionsCache.get(command);
285
+ }
286
+ const [bin, leadingArg] = splitAtomCommand(command);
287
+ const args = ["--help"];
288
+ if (leadingArg !== undefined) {
289
+ args.unshift(leadingArg);
290
+ }
291
+ const env = { ...process.env };
292
+ if (readEnvironmentVariable("ATOM_JAVA_HOME")) {
293
+ env.JAVA_HOME = readEnvironmentVariable("ATOM_JAVA_HOME");
294
+ }
295
+ const options = new Set();
296
+ const result = safeSpawnSync(bin, args, {
297
+ shell: isWin,
298
+ env,
299
+ timeout: 120000,
300
+ });
301
+ if (result?.status === 0 && result.stdout) {
302
+ for (const match of `${result.stdout}`.matchAll(
303
+ /(?:^|\s)(--[a-z][a-z0-9-]*)/g,
304
+ )) {
305
+ options.add(match[1]);
306
+ }
307
+ }
308
+ atomOptionsCache.set(command, options);
309
+ return options;
310
+ }
311
+
274
312
  /**
275
313
  * The `--frontend-args` atom takes for a C/C++ language: the project's
276
314
  * compilation database, when there is one and the installed atom reads it
@@ -315,6 +353,45 @@ export function atomCompileCommandsArgs(src, language, options = {}) {
315
353
  return ["--frontend-args", `compile-commands=${database}`];
316
354
  }
317
355
 
356
+ /**
357
+ * The `--bom-file` a reachables slice takes package purls from: the BOM evinse
358
+ * annotates. atom would otherwise only find a BOM saved as `bom.json` inside
359
+ * the scanned directory, so a BOM written anywhere else gave every reachable
360
+ * flow no purl. An atom without `--bom-file` is given the arguments it has
361
+ * always been given, and still reads a `bom.json` in the scanned directory.
362
+ *
363
+ * @param {string} sliceType atom slice command
364
+ * @param {Object} options CLI options, for `input`
365
+ * @returns {string[]} Arguments to add to the atom command
366
+ */
367
+ export function atomBomFileArgs(sliceType, options = {}) {
368
+ if (
369
+ sliceType !== "reachables" ||
370
+ !options?.input ||
371
+ !safeExistsSync(options.input)
372
+ ) {
373
+ return [];
374
+ }
375
+ const bomFile = resolve(options.input);
376
+ // The argument reaches a Windows shell command line through `shell: isWin`
377
+ // in executeAtom, so a path a shell would interpret is never passed on.
378
+ if (UNSAFE_SHELL_CHARS_RE.test(bomFile)) {
379
+ console.warn(
380
+ `The BOM path ${bomFile} contains characters a shell would interpret. Reachable flows will carry purls only if a bom.json is in the scanned directory.`,
381
+ );
382
+ return [];
383
+ }
384
+ if (!atomOptions().has("--bom-file")) {
385
+ if (DEBUG_MODE) {
386
+ console.log(
387
+ "The installed atom does not take --bom-file. Reachable flows will carry purls only if a bom.json is in the scanned directory.",
388
+ );
389
+ }
390
+ return [];
391
+ }
392
+ return ["--bom-file", bomFile];
393
+ }
394
+
318
395
  /**
319
396
  * The arguments that stop atom's Java frontend from running the scanned
320
397
  * project's build. In its default delombok mode, atom runs
@@ -43,6 +43,13 @@ const COMPONENT_TYPES_1_5 = [
43
43
  "data",
44
44
  ];
45
45
  const COMPONENT_TYPES_1_6 = [...COMPONENT_TYPES_1_5, "cryptographic-asset"];
46
+ // CycloneDX 2.0 keeps every 1.6 type and turns services into components of
47
+ // type `service` (`#/$defs/cyclonedx-component-2.0/$defs/component/properties/type`),
48
+ // next to the new physical type `material`. The draft's enum, quoted:
49
+ // application, framework, library, container, platform, operating-system,
50
+ // device, device-driver, firmware, file, machine-learning-model, data,
51
+ // cryptographic-asset, material, service.
52
+ const COMPONENT_TYPES_2_0 = [...COMPONENT_TYPES_1_6, "material", "service"];
46
53
 
47
54
  /**
48
55
  * Frozen map of CycloneDX spec versions (as "major.minor" strings) to the
@@ -53,7 +60,7 @@ export const CYCLONEDX_COMPONENT_TYPES_BY_SPEC_VERSION = Object.freeze({
53
60
  1.5: Object.freeze(COMPONENT_TYPES_1_5),
54
61
  1.6: Object.freeze(COMPONENT_TYPES_1_6),
55
62
  1.7: Object.freeze(COMPONENT_TYPES_1_6),
56
- "2.0": Object.freeze(COMPONENT_TYPES_1_6),
63
+ "2.0": Object.freeze(COMPONENT_TYPES_2_0),
57
64
  });
58
65
 
59
66
  /**
@@ -0,0 +1,142 @@
1
+ // BOM components for the Brotli decoders compiled into native files. The
2
+ // detection itself, and why its markers can be trusted, is in
3
+ // lib/core/brotliProbe.js.
4
+
5
+ import {
6
+ MAX_BROTLI_PROBE_BYTES,
7
+ MAX_BROTLI_PROBES,
8
+ readBrotliDecoder,
9
+ } from "../core/brotliProbe.js";
10
+ import { applyPurl, tryBuildPurl } from "./purl.js";
11
+
12
+ export { MAX_BROTLI_PROBE_BYTES, MAX_BROTLI_PROBES, readBrotliDecoder };
13
+
14
+ /**
15
+ * The properties a file component carries once it has been probed: the fix
16
+ * state of each decoder found in it, or why it could not be read.
17
+ *
18
+ * @param {Object} decoder result of readBrotliDecoder
19
+ * @returns {{name: string, value: string}[]} properties to append
20
+ */
21
+ export function brotliDecoderProperties(decoder) {
22
+ const properties = [];
23
+ if (decoder?.skipped) {
24
+ properties.push({ name: "cdx:brotli:probe", value: decoder.skipped });
25
+ }
26
+ if (decoder?.c) {
27
+ properties.push(
28
+ { name: "cdx:brotli:c:blockSwitchFix", value: decoder.c.blockSwitchFix },
29
+ { name: "cdx:brotli:c:evidence", value: decoder.c.evidence },
30
+ );
31
+ }
32
+ if (decoder?.go) {
33
+ properties.push({
34
+ name: "cdx:brotli:go:blockSwitchFix",
35
+ value: decoder.go.blockSwitchFix,
36
+ });
37
+ }
38
+ return properties;
39
+ }
40
+
41
+ /**
42
+ * The library component every embedded decoder links to. It has no version:
43
+ * no build records one, and only the per-file cdx:brotli:*:blockSwitchFix
44
+ * properties say whether a copy is vulnerable. The `vcs_url` qualifier names
45
+ * the project and keeps the identity apart from an unpackaged `brotli`
46
+ * executable, which is `pkg:generic/brotli`. The purl has no namespace: a
47
+ * `pkg:github` purl is typed as an application and `pkg:generic/google` as a
48
+ * framework when the BOM is assembled, and this is neither.
49
+ *
50
+ * @returns {Object} component with `purl` and `bom-ref`
51
+ */
52
+ export function createBrotliComponent() {
53
+ return applyPurl(
54
+ {
55
+ type: "library",
56
+ name: "brotli",
57
+ description:
58
+ "Brotli decoder compiled into native files; see the cdx:brotli properties on each file",
59
+ properties: [],
60
+ },
61
+ tryBuildPurl({
62
+ type: "generic",
63
+ name: "brotli",
64
+ qualifiers: { vcs_url: "git+https://github.com/google/brotli" },
65
+ }),
66
+ );
67
+ }
68
+
69
+ /**
70
+ * Start collecting the decoder copies of one scan.
71
+ *
72
+ * @returns {{component: Object|undefined, dependencies: Object[], copies: number, unpatched: number, unknown: number}}
73
+ */
74
+ export function createBrotliInventory() {
75
+ return {
76
+ component: undefined,
77
+ dependencies: [],
78
+ copies: 0,
79
+ unpatched: 0,
80
+ unknown: 0,
81
+ };
82
+ }
83
+
84
+ /**
85
+ * Tag a probed file component and, when it holds a decoder, link it to the
86
+ * shared brotli component, creating that component on first use. Mutates the
87
+ * file component in place.
88
+ *
89
+ * @param {Object} inventory accumulator from createBrotliInventory
90
+ * @param {Object} fileComponent file component with a `properties` array
91
+ * @param {Object} decoder result of readBrotliDecoder
92
+ */
93
+ export function attachBrotliDecoder(inventory, fileComponent, decoder) {
94
+ const properties = brotliDecoderProperties(decoder);
95
+ if (!properties.length) {
96
+ return;
97
+ }
98
+ fileComponent.properties.push(...properties);
99
+ if (!decoder.c && !decoder.go) {
100
+ return;
101
+ }
102
+ if (!inventory.component) {
103
+ inventory.component = createBrotliComponent();
104
+ }
105
+ const states = [decoder.c?.blockSwitchFix, decoder.go?.blockSwitchFix];
106
+ inventory.copies += 1;
107
+ if (states.includes("false")) {
108
+ inventory.unpatched += 1;
109
+ } else if (states.includes("unknown")) {
110
+ inventory.unknown += 1;
111
+ }
112
+ if (fileComponent["bom-ref"] && inventory.component["bom-ref"]) {
113
+ inventory.dependencies.push({
114
+ ref: fileComponent["bom-ref"],
115
+ dependsOn: [inventory.component["bom-ref"]],
116
+ });
117
+ }
118
+ }
119
+
120
+ /**
121
+ * Finish an inventory: record the copy counts on the brotli component.
122
+ *
123
+ * @param {Object} inventory accumulator from createBrotliInventory
124
+ * @returns {{components: Object[], dependencies: Object[]}} what to add to the BOM
125
+ */
126
+ export function finishBrotliInventory(inventory) {
127
+ if (!inventory?.component) {
128
+ return { components: [], dependencies: [] };
129
+ }
130
+ inventory.component.properties = [
131
+ { name: "cdx:brotli:embeddedCopies", value: String(inventory.copies) },
132
+ { name: "cdx:brotli:unpatchedCopies", value: String(inventory.unpatched) },
133
+ { name: "cdx:brotli:unknownCopies", value: String(inventory.unknown) },
134
+ ];
135
+ return {
136
+ components: [inventory.component],
137
+ dependencies: [
138
+ { ref: inventory.component["bom-ref"], dependsOn: [] },
139
+ ...inventory.dependencies,
140
+ ],
141
+ };
142
+ }
@@ -129,7 +129,7 @@ export function noteBuildToolRateLimit(tool, output, context = {}) {
129
129
  ? `, so cdxgen runs no further ${tool} resolution in this scan and`
130
130
  : ", so";
131
131
  console.warn(
132
- `The repository ${tool} downloads from is rate limiting this machine (HTTP 429)${stopped} its dependency tree is incomplete. ${MIRROR_SETTINGS[tool] || MIRROR_SETTINGS[TOOL_MATCHER[tool]]} cdxgen's own lookups can be moved with MAVEN_CENTRAL_URL.`,
132
+ `The repository ${tool} downloads from is rate limiting this machine (HTTP 429)${stopped} its dependency tree is incomplete. ${MIRROR_SETTINGS[tool] || MIRROR_SETTINGS[TOOL_MATCHER[tool]]} Set MAVEN_CENTRAL_MIRROR=true to point every build tool at Google's Maven Central mirror, or MAVEN_CENTRAL_URL for cdxgen's own lookups.`,
133
133
  );
134
134
  recordDegradation("build.rate-limited", {
135
135
  ecosystem: "java",