@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
@@ -30,6 +30,10 @@ import {
30
30
  getNonCycloneDxErrorMessage,
31
31
  isCycloneDxBom,
32
32
  } from "../inventory/bomUtils.js";
33
+ import {
34
+ formatReadLossNotice,
35
+ loadBomForAnalysis,
36
+ } from "../inventory/cyclonedx20.js";
33
37
  import {
34
38
  collectPolicyViolations,
35
39
  loadPolicy,
@@ -122,10 +126,14 @@ const PYTHON_OBFUSCATION_PATTERN =
122
126
  const PYTHON_SETUP_CMDCLASS_PATTERN = /\bcmdclass\s*=/i;
123
127
 
124
128
  /**
125
- * Read and validate a CycloneDX BOM file.
129
+ * Read and validate a CycloneDX BOM file. A CycloneDX 2.0 document is read
130
+ * into cdxgen's internal 1.x-shaped model, so the audit rules keep reading
131
+ * `components`, `bom-ref` and `metadata.component`; the number of losses
132
+ * the read reported is printed once on stderr, with the details in
133
+ * thoughtLog.
126
134
  *
127
135
  * @param {string} bomPath BOM file path
128
- * @returns {object} parsed CycloneDX BOM
136
+ * @returns {object} parsed CycloneDX BOM in the 1.x shape
129
137
  */
130
138
  export function loadBomFile(bomPath) {
131
139
  const resolvedPath = resolve(bomPath);
@@ -138,7 +146,21 @@ export function loadBomFile(bomPath) {
138
146
  if (!isCycloneDxBom(bomJson)) {
139
147
  throw new Error(getNonCycloneDxErrorMessage(bomJson, "cdx-audit"));
140
148
  }
141
- return bomJson;
149
+ let analysis;
150
+ try {
151
+ analysis = loadBomForAnalysis(bomJson);
152
+ } catch (error) {
153
+ throw new Error(`Failed to read ${resolvedPath}: ${error.message}`);
154
+ }
155
+ const { internalBom, losses } = analysis;
156
+ if (losses.length) {
157
+ // stderr: stdout carries the --report json/sarif payload.
158
+ console.warn(formatReadLossNotice(losses));
159
+ for (const loss of losses) {
160
+ thoughtLog(`cdx-audit 2.0 loss at ${loss.pointer}: ${loss.reason}`);
161
+ }
162
+ }
163
+ return internalBom;
142
164
  }
143
165
 
144
166
  /**
@@ -25,6 +25,7 @@ import {
25
25
  CDXGEN_VERSION,
26
26
  frameworksList,
27
27
  } from "../core/state.js";
28
+ import { getExecutedTools } from "../core/toolRegistry.js";
28
29
  import {
29
30
  isPkgTypeOnlyImport,
30
31
  setNpmCleanedVersionProperty,
@@ -60,7 +61,7 @@ import {
60
61
  } from "../inventory/purl.js";
61
62
  import { repairPurl } from "../inventory/sbomDocument.js";
62
63
  import { getLicenses } from "../inventory/spdx.js";
63
- import { getBinaryBom } from "../managers/binary.js";
64
+ import { getBinaryBom, getPluginToolComponents } from "../managers/binary.js";
64
65
  import { isValidIriReference } from "../parsers/iri.js";
65
66
 
66
67
  /**
@@ -293,10 +294,85 @@ function anchorDetectedParent(
293
294
  return anchored;
294
295
  }
295
296
 
297
+ /**
298
+ * Builds the tool components for the external helpers and build tools this
299
+ * run executed, from the run-scoped registry (issue #598). Bundled plugin
300
+ * helpers are enriched with the manifest component of the plugin package that
301
+ * ships them, so the plugin package's version and identity travel with the
302
+ * helper. Empty when the run spawned nothing external, which keeps such BOMs
303
+ * byte-identical to the previous behaviour.
304
+ *
305
+ * @returns {object[]} Sorted CycloneDX tool components
306
+ */
307
+ export const buildExternalToolComponents = () => {
308
+ const recordedTools = getExecutedTools();
309
+ if (!recordedTools.length) {
310
+ return [];
311
+ }
312
+ const recordedNames = recordedTools.map((tool) => tool.name);
313
+ const pluginComponents = getPluginToolComponents(recordedNames);
314
+ const pluginByName = new Map(
315
+ pluginComponents.map((component) => [component.name, component]),
316
+ );
317
+ const components = [];
318
+ for (const tool of recordedTools) {
319
+ const pluginComponent = pluginByName.get(tool.name);
320
+ if (pluginComponent?.["bom-ref"]) {
321
+ components.push(pluginComponent);
322
+ continue;
323
+ }
324
+ const component = {
325
+ type: "application",
326
+ name: tool.name,
327
+ };
328
+ if (tool.version) {
329
+ component.version = tool.version;
330
+ }
331
+ components.push(component);
332
+ }
333
+ return components;
334
+ };
335
+
336
+ /**
337
+ * Drops the executed tools that are already present: a tool whose bom-ref or
338
+ * name matches an explicitly passed context tool, or whose bom-ref an earlier
339
+ * executed tool already carries (several bundled helpers can share one plugin
340
+ * package component). The context tools themselves are never touched.
341
+ *
342
+ * @param {object[]} contextTools Tool components passed in by the caller
343
+ * @param {object[]} executedTools Tool components from the run's registry
344
+ * @returns {object[]} The executed tools to append
345
+ */
346
+ const newExecutedTools = (contextTools, executedTools) => {
347
+ const seenRefs = new Set();
348
+ const seenNames = new Set();
349
+ for (const component of contextTools) {
350
+ if (component?.["bom-ref"]) {
351
+ seenRefs.add(component["bom-ref"]);
352
+ }
353
+ if (component?.name) {
354
+ seenNames.add(component.name);
355
+ }
356
+ }
357
+ const unique = [];
358
+ for (const component of executedTools) {
359
+ const ref = component["bom-ref"];
360
+ if ((ref && seenRefs.has(ref)) || seenNames.has(component.name)) {
361
+ continue;
362
+ }
363
+ if (ref) {
364
+ seenRefs.add(ref);
365
+ }
366
+ unique.push(component);
367
+ }
368
+ return unique;
369
+ };
370
+
296
371
  /**
297
372
  * Assembles the `metadata.tools` block, including the cdxgen tool entry and,
298
373
  * for spec versions prior to 1.5, the legacy tools array. For spec version
299
- * 1.6+ the author field is converted to the authors array.
374
+ * 1.6+ the author field is converted to the authors array. The tools this run
375
+ * executed follow the context tools, sorted by name, and cdxgen comes last.
300
376
  *
301
377
  * @param {object} options CLI options
302
378
  * @param {object} [context={}] Additional context carrying existing components
@@ -304,6 +380,7 @@ function anchorDetectedParent(
304
380
  * tools array (1.4) or a components array with tool components (1.5+)
305
381
  */
306
382
  export const addToolsSection = (options, context = {}) => {
383
+ const externalTools = buildExternalToolComponents();
307
384
  if (options.specVersion === 1.4) {
308
385
  return [
309
386
  {
@@ -311,6 +388,11 @@ export const addToolsSection = (options, context = {}) => {
311
388
  name: "cdxgen",
312
389
  version: CDXGEN_VERSION,
313
390
  },
391
+ ...newExecutedTools([], externalTools).map((tool) =>
392
+ tool.version
393
+ ? { name: tool.name, version: tool.version }
394
+ : { name: tool.name },
395
+ ),
314
396
  ];
315
397
  }
316
398
  let components = [];
@@ -331,6 +413,7 @@ export const addToolsSection = (options, context = {}) => {
331
413
  } else if (tools && Object.keys(tools).length && tools.components) {
332
414
  components = components.concat(tools.components);
333
415
  }
416
+ components = components.concat(newExecutedTools(components, externalTools));
334
417
  const cdxToolComponent = {
335
418
  group: CDXGEN_TOOL_GROUP,
336
419
  name: CDXGEN_TOOL_NAME,
@@ -524,7 +607,13 @@ export function addMetadata(parentComponent = {}, options = {}, context = {}) {
524
607
  // We cannot use purl or bom-ref here since they would not match
525
608
  // purl - could have application on one side and a different type
526
609
  // bom-ref could have qualifiers on one side
527
- if (fullName !== parentFullName) {
610
+ // A purl subpath marks a separate project that declares the
611
+ // parent's coordinates, such as a second Maven project or a Gradle
612
+ // subproject with the same group, name and version.
613
+ const separateProject =
614
+ comp.purl?.includes("#") &&
615
+ comp.purl.split("#")[1] !== parentComponent.purl?.split("#")[1];
616
+ if (fullName !== parentFullName || separateProject) {
528
617
  if (!comp["bom-ref"]) {
529
618
  comp["bom-ref"] = `pkg:${comp.type}/${decodeURIComponent(
530
619
  fullName,
@@ -1024,6 +1113,65 @@ export function hasNpmBinCommandEvidence(allImports, pkg) {
1024
1113
  return false;
1025
1114
  }
1026
1115
 
1116
+ /**
1117
+ * Return a CycloneDX organisational entity built from a collector-supplied
1118
+ * supplier or manufacturer, or undefined when the value is not a well-formed
1119
+ * entity.
1120
+ *
1121
+ * An entity needs a non-empty string name. When a url is present it must be
1122
+ * an array of valid IRI references; any other shape (a single string, an
1123
+ * array holding non-strings) drops the entity so the BOM stays schema
1124
+ * valid. Each contact is reduced to its string name, email and phone, and a
1125
+ * contact with none of them is left out. The entity bom-ref is not copied,
1126
+ * because CycloneDX 1.4 does not allow it there.
1127
+ *
1128
+ * @param {Object} entity Collector-supplied organisational entity
1129
+ * @returns {Object|undefined} Organisational entity, or undefined
1130
+ */
1131
+ export function toOrganizationalEntity(entity) {
1132
+ if (!entity || typeof entity !== "object" || Array.isArray(entity)) {
1133
+ return undefined;
1134
+ }
1135
+ if (typeof entity.name !== "string" || !entity.name.trim().length) {
1136
+ return undefined;
1137
+ }
1138
+ const result = { name: entity.name.trim() };
1139
+ if (entity.url !== undefined) {
1140
+ if (
1141
+ !Array.isArray(entity.url) ||
1142
+ !entity.url.every(
1143
+ (u) => typeof u === "string" && u.length && isValidIriReference(u),
1144
+ )
1145
+ ) {
1146
+ return undefined;
1147
+ }
1148
+ if (entity.url.length) {
1149
+ result.url = [...entity.url];
1150
+ }
1151
+ }
1152
+ if (Array.isArray(entity.contact)) {
1153
+ const contacts = [];
1154
+ for (const contact of entity.contact) {
1155
+ if (!contact || typeof contact !== "object" || Array.isArray(contact)) {
1156
+ continue;
1157
+ }
1158
+ const reduced = {};
1159
+ for (const field of ["name", "email", "phone"]) {
1160
+ if (typeof contact[field] === "string" && contact[field].trim()) {
1161
+ reduced[field] = contact[field].trim();
1162
+ }
1163
+ }
1164
+ if (Object.keys(reduced).length) {
1165
+ contacts.push(reduced);
1166
+ }
1167
+ }
1168
+ if (contacts.length) {
1169
+ result.contact = contacts;
1170
+ }
1171
+ }
1172
+ return result;
1173
+ }
1174
+
1027
1175
  /**
1028
1176
  * Given the specified package, create a CycloneDX component and add it to the list.
1029
1177
  */
@@ -1103,7 +1251,9 @@ export function addComponent(
1103
1251
  const description = pkg.description || undefined;
1104
1252
  let compScope = pkg.scope;
1105
1253
  let isTypeOnlyPkg = false;
1106
- if (allImports) {
1254
+ // addEvidenceForImports flags an installed version that none of the
1255
+ // project's imports resolve to; its name matching an import is no use.
1256
+ if (allImports && !pkg._npmImportsResolveElsewhere) {
1107
1257
  const impPkgs = Object.keys(allImports);
1108
1258
  const hasBinCommandEvidence = hasNpmBinCommandEvidence(allImports, pkg);
1109
1259
  if (
@@ -1192,6 +1342,24 @@ export function addComponent(
1192
1342
  delete component.swhid;
1193
1343
  }
1194
1344
  processHashes(pkg, component);
1345
+ // A collector that resolved the organisations behind a component keeps
1346
+ // them here: the AI collectors record the Hugging Face namespace that
1347
+ // published a model or dataset as the supplier, and the organisation
1348
+ // that created a model as the manufacturer. The supplier is a valid
1349
+ // component field in every spec version cdxgen emits; the manufacturer
1350
+ // arrived in CycloneDX 1.6. Only a well-formed organisational entity is
1351
+ // copied, so a collector that puts a string url or a build string on the
1352
+ // package cannot make the BOM fail schema validation.
1353
+ const supplier = toOrganizationalEntity(pkg.supplier);
1354
+ if (supplier) {
1355
+ component.supplier = supplier;
1356
+ }
1357
+ if (options.specVersion >= 1.6) {
1358
+ const manufacturer = toOrganizationalEntity(pkg.manufacturer);
1359
+ if (manufacturer) {
1360
+ component.manufacturer = manufacturer;
1361
+ }
1362
+ }
1195
1363
  // Upgrade authors section
1196
1364
  if (options.specVersion >= 1.6 && component.author) {
1197
1365
  const authorsList = [];
@@ -94,20 +94,35 @@ const POST_BUILD_SUPPORTED_PROJECT_TYPES = new Set([
94
94
  // ---------------------------------------------------------------------------
95
95
 
96
96
  /**
97
- * The formulation privacy notice, shared by every path that turns formulation
98
- * collection on automatically: the warning about emails and secrets is
99
- * identical whichever caller adds the section.
97
+ * The notice for formulation that cdxgen turned on by itself. It names what
98
+ * turned formulation on, and, when the BOM is submitted to a server, the
99
+ * warning also names that server, as it does for an explicit
100
+ * --include-formulation.
100
101
  *
102
+ * @param {object} options The options object
103
+ * @param {string} reasons What turned formulation on, such as "CI=true"
101
104
  * @returns {OptionsWarning} The notice.
102
105
  */
103
- function formulationPrivacyNotice() {
106
+ function autoFormulationNotice(options, reasons) {
107
+ if (options.serverUrl) {
108
+ return {
109
+ level: "warn",
110
+ message: `WARNING: Automatically collecting formulation information for ${reasons}. The formulation section may include sensitive data such as emails and secrets. This data will be submitted to '${options.serverUrl}' automatically. Pass --no-include-formulation to leave it out.`,
111
+ };
112
+ }
104
113
  return {
105
114
  level: "info",
106
- message:
107
- "NOTE: Automatically collecting formulation information. The section may include sensitive data such as emails and secrets.\nPlease review the generated SBOM before distribution or LLM training.",
115
+ message: `NOTE: Automatically collecting formulation information for ${reasons}. The section may include sensitive data such as emails and secrets. Pass --no-include-formulation to leave it out.\nPlease review the generated SBOM before distribution or LLM training.`,
108
116
  };
109
117
  }
110
118
 
119
+ /**
120
+ * Options objects whose formulation notes were already reported, so the CLI,
121
+ * which applies the advanced options twice, prints each note once.
122
+ */
123
+ const formulationRefusalNoted = new WeakSet();
124
+ const secureFormulationNoteNoted = new WeakSet();
125
+
111
126
  /**
112
127
  * Check whether a value was explicitly provided by the user (i.e., is not
113
128
  * the yargs default). Yargs always populates default values, so we cannot
@@ -400,6 +415,28 @@ function resolveIntrospectOption(args, argv) {
400
415
  : undefined;
401
416
  }
402
417
 
418
+ /**
419
+ * Whether the operator explicitly refused formulation with
420
+ * `--no-include-formulation`, `--include-formulation=false` or
421
+ * `CDXGEN_INCLUDE_FORMULATION=false`.
422
+ *
423
+ * @param {string[]} argv Raw command-line arguments the parser was given.
424
+ * @returns {boolean} True when formulation was refused explicitly.
425
+ */
426
+ function isFormulationRefused(argv) {
427
+ return (
428
+ operatorOptionChoice("include-formulation", {
429
+ argv,
430
+ boolean: true,
431
+ env: {
432
+ CDXGEN_INCLUDE_FORMULATION: readEnvironmentVariable(
433
+ "CDXGEN_INCLUDE_FORMULATION",
434
+ ),
435
+ },
436
+ }) === false
437
+ );
438
+ }
439
+
403
440
  export function buildInitialOptions(
404
441
  args,
405
442
  { filePath, isRemoteOrPurl, argv = process.argv, projectConfig },
@@ -427,6 +464,11 @@ export function buildInitialOptions(
427
464
  // explicit --no-introspect stays `false` and beats both, while an
428
465
  // unmentioned flag stays undefined so a profile can still enable it.
429
466
  introspect: resolveIntrospectOption(args, argv),
467
+ // An explicit --no-include-formulation (or CDXGEN_INCLUDE_FORMULATION
468
+ // set to false) is the operator's refusal, which no automatic trigger
469
+ // such as CI=true, a profile, obom or cbom may override. The yargs
470
+ // default is also false, so only the raw arguments tell them apart.
471
+ includeFormulationRefused: isFormulationRefused(argv) || undefined,
430
472
  // License normalization and enrichment are on by default; the only escape
431
473
  // hatch is the corresponding environment variable.
432
474
  licenseEnhance:
@@ -439,6 +481,10 @@ export function buildInitialOptions(
439
481
  readEnvironmentVariable("CDXGEN_LICENSE_REF") === "true",
440
482
  });
441
483
 
484
+ // A command default such as aibom's does not outrank the refusal either.
485
+ if (res.includeFormulationRefused) {
486
+ res.includeFormulation = false;
487
+ }
442
488
  if (res.licenseEnhance !== undefined) {
443
489
  process.env.CDXGEN_LICENSE_ENHANCE = String(res.licenseEnhance);
444
490
  }
@@ -628,6 +674,8 @@ export function applyPostConstructionOverrides(options, context) {
628
674
  * @param {object} options The options object
629
675
  * @param {object} [context]
630
676
  * @param {boolean} [context.isSecureMode] Whether cdxgen runs in secure mode
677
+ * @param {string} [context.invokedCommandName] Binary name (e.g. "cbom"),
678
+ * which can turn on formulation
631
679
  * @returns {OptionsWarning[]} Warnings for the caller
632
680
  */
633
681
  export function applyAdvancedOptions(options, context = {}) {
@@ -635,6 +683,7 @@ export function applyAdvancedOptions(options, context = {}) {
635
683
  const warnings = [];
636
684
  const isHbomOnly = isHbomOnlyProjectTypes(options.projectType);
637
685
  const includeFormulationBeforeProfiles = options.includeFormulation === true;
686
+ const formulationRefused = options.includeFormulationRefused === true;
638
687
  const introspectExplicitlyDisabled = options.introspect === false;
639
688
 
640
689
  // --- Profile expansion -------------------------------------------------
@@ -672,7 +721,7 @@ export function applyAdvancedOptions(options, context = {}) {
672
721
  options.introspectAnnotate = options.introspectAnnotate !== false;
673
722
  // The ledger's own record of what ran; formulation is where a consumer
674
723
  // looks for the build environment the SBOM was produced in.
675
- options.includeFormulation = !isHbomOnly;
724
+ options.includeFormulation = !isHbomOnly && !formulationRefused;
676
725
  options.evidence = true;
677
726
  break;
678
727
  case "ml-tiny":
@@ -752,17 +801,67 @@ export function applyAdvancedOptions(options, context = {}) {
752
801
  });
753
802
  }
754
803
 
755
- // --- BOM audit → auto-formulation --------------------------------------
756
- const introspectProfileAddsFormulation =
757
- options.profile === "introspect" && !includeFormulationBeforeProfiles;
758
- if (options.bomAudit || introspectProfileAddsFormulation) {
759
- if (isHbomOnly) {
760
- // HBOM-only: skip formulation
804
+ // --- Auto-formulation: BOM audit, profiles, CI, obom and cbom ----------
805
+ // Formulation is included without a flag when a BOM audit reads it, when
806
+ // the research or introspect profile runs, in CI (CI=true), and for obom
807
+ // (an OS project type such as os, linux or windows) and cbom output
808
+ // (cdxgen#859). These runs are where the build environment and inputs are
809
+ // wanted next to the inventory. Formulation does not supply the CISA 2026
810
+ // generation context element: CISA-MIN-004 reads metadata.lifecycles.
811
+ // An explicit --no-include-formulation wins over every trigger.
812
+ const profileAddsFormulation =
813
+ ["research", "introspect"].includes(options.profile) &&
814
+ !includeFormulationBeforeProfiles;
815
+ const autoFormulationReasons = [];
816
+ if (options.bomAudit) {
817
+ autoFormulationReasons.push("a BOM audit");
818
+ }
819
+ if (profileAddsFormulation) {
820
+ autoFormulationReasons.push(`the ${options.profile} profile`);
821
+ }
822
+ if ((readEnvironmentVariable("CI") || "").toLowerCase() === "true") {
823
+ autoFormulationReasons.push("CI=true");
824
+ }
825
+ if (hasOsProjectType(options.projectType)) {
826
+ autoFormulationReasons.push("an OS project type");
827
+ }
828
+ if (`${context.invokedCommandName || ""}`.includes("cbom")) {
829
+ autoFormulationReasons.push("the cbom command");
830
+ }
831
+ if (autoFormulationReasons.length && !isHbomOnly) {
832
+ const reasons = autoFormulationReasons.join(", ");
833
+ if (formulationRefused) {
834
+ options.includeFormulation = false;
835
+ if (!formulationRefusalNoted.has(options)) {
836
+ formulationRefusalNoted.add(options);
837
+ warnings.push({
838
+ level: "info",
839
+ message: `NOTE: Formulation stays off because it was refused explicitly (--no-include-formulation, --include-formulation=false or CDXGEN_INCLUDE_FORMULATION=false), although ${reasons} would include it.`,
840
+ });
841
+ }
761
842
  } else if (!options.includeFormulation) {
762
- warnings.push(formulationPrivacyNotice());
763
- options.includeFormulation = true;
764
- } else if (introspectProfileAddsFormulation) {
765
- warnings.push(formulationPrivacyNotice());
843
+ if (options.serverUrl && secureMode) {
844
+ // Secure mode refuses to submit formulation to a server, so an
845
+ // automatic default must not turn a secure run into a failed one.
846
+ if (!secureFormulationNoteNoted.has(options)) {
847
+ secureFormulationNoteNoted.add(options);
848
+ warnings.push({
849
+ level: "info",
850
+ message: `NOTE: Formulation is not collected automatically for ${reasons} because secure mode does not submit formulation to '${options.serverUrl}'. Pass --include-formulation to request it.`,
851
+ });
852
+ }
853
+ } else {
854
+ warnings.push(autoFormulationNotice(options, reasons));
855
+ options.includeFormulation = true;
856
+ }
857
+ } else if (profileAddsFormulation) {
858
+ warnings.push(autoFormulationNotice(options, reasons));
859
+ }
860
+ // Formulation that no flag asked for leaves out the scanning host's
861
+ // certificates, authorized keys and keychain items (see
862
+ // addFormulationSection).
863
+ if (options.includeFormulation && !includeFormulationBeforeProfiles) {
864
+ options.formulationAutomatic = true;
766
865
  }
767
866
  }
768
867
 
@@ -795,6 +894,8 @@ export function applyAdvancedOptions(options, context = {}) {
795
894
  * @param {object} [context.projectConfig] Sanitized config file contents,
796
895
  * whose metadata properties merge
797
896
  * with the other sources'
897
+ * @param {string[]} [context.argv] Raw command-line arguments,
898
+ * process.argv when absent
798
899
  * @returns {{ options: object, warnings: OptionsWarning[] }}
799
900
  */
800
901
  export function buildOptionsFromArgs(args, context) {
@@ -805,6 +906,7 @@ export function buildOptionsFromArgs(args, context) {
805
906
  userSetSpecVersion,
806
907
  isDryRun = false,
807
908
  projectConfig,
909
+ argv,
808
910
  } = context;
809
911
 
810
912
  const expandedArgs = applyCommandNameDefaults(args, invokedCommandName);
@@ -812,6 +914,7 @@ export function buildOptionsFromArgs(args, context) {
812
914
  filePath,
813
915
  isRemoteOrPurl,
814
916
  projectConfig,
917
+ ...(argv ? { argv } : {}),
815
918
  });
816
919
  const phase3Warnings = applyPostConstructionOverrides(options, {
817
920
  invokedCommandName,
@@ -820,6 +923,7 @@ export function buildOptionsFromArgs(args, context) {
820
923
  });
821
924
  const phase4Warnings = applyAdvancedOptions(options, {
822
925
  isSecureMode: context.isSecureMode,
926
+ invokedCommandName,
823
927
  });
824
928
 
825
929
  return {