@cdxgen/cdxgen 13.6.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 (264) hide show
  1. package/README.md +15 -8
  2. package/bin/audit.js +7 -4
  3. package/bin/cdxgen.js +256 -37
  4. package/bin/convert.js +146 -22
  5. package/bin/evinse.js +25 -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 +18 -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/pqc-migration.json +239 -0
  15. package/data/remediations.json +52 -0
  16. package/data/rules/cbom-security.yaml +4 -3
  17. package/data/rules/package-integrity.yaml +28 -0
  18. package/lib/audit/index.js +25 -3
  19. package/lib/cli/bomAssembly.js +80 -1
  20. package/lib/cli/cliOptions.js +121 -17
  21. package/lib/cli/index.js +609 -898
  22. package/lib/cli/jsBom.js +3 -0
  23. package/lib/cli/jvmBom.js +365 -40
  24. package/lib/cli/managedBom.js +19 -3
  25. package/lib/cli/nativeBom.js +10 -0
  26. package/lib/core/env.js +26 -0
  27. package/lib/core/fs.js +126 -3
  28. package/lib/core/globPatterns.js +218 -0
  29. package/lib/core/processTree.js +99 -12
  30. package/lib/core/projectConfig.js +332 -25
  31. package/lib/core/toolRegistry.js +15 -1
  32. package/lib/ecosystems/denoutils.js +2 -2
  33. package/lib/ecosystems/golem.js +3 -8
  34. package/lib/ecosystems/gradleutils.js +1082 -6
  35. package/lib/ecosystems/jsEvidence.js +90 -38
  36. package/lib/ecosystems/kosi.js +3 -5
  37. package/lib/ecosystems/npmVersionResolution.js +376 -0
  38. package/lib/ecosystems/parsers-python.js +89 -28
  39. package/lib/ecosystems/parsers-rust.js +117 -15
  40. package/lib/ecosystems/remote/huggingface.js +22 -0
  41. package/lib/ecosystems/rusi.js +2 -4
  42. package/lib/ecosystems/scalasem.js +2 -1
  43. package/lib/evinser/evinser.js +196 -34
  44. package/lib/evinser/scalasem.js +5 -1
  45. package/lib/helpers/agenticToolutils.js +112 -1
  46. package/lib/helpers/bomSigner.js +43 -9
  47. package/lib/helpers/jssSigner.js +1276 -0
  48. package/lib/inventory/agentBlueprint.js +193 -0
  49. package/lib/inventory/agentToolNames.js +145 -0
  50. package/lib/inventory/aiCollector.js +153 -7
  51. package/lib/inventory/aiInventory.js +44 -8
  52. package/lib/inventory/aiProviders.js +324 -0
  53. package/lib/inventory/bomUtils.js +8 -1
  54. package/lib/inventory/ciParsers/githubActionsLock.js +821 -0
  55. package/lib/inventory/citations.js +31 -2
  56. package/lib/inventory/communityAiConfigParser.js +978 -80
  57. package/lib/inventory/cyclonedx20.js +152 -0
  58. package/lib/inventory/cyclonedx20Common.js +286 -0
  59. package/lib/inventory/cyclonedx20Derived.js +159 -0
  60. package/lib/inventory/cyclonedx20Parties.js +552 -0
  61. package/lib/inventory/cyclonedx20Read.js +768 -0
  62. package/lib/inventory/cyclonedx20ReadCommon.js +374 -0
  63. package/lib/inventory/cyclonedx20ReadComponents.js +692 -0
  64. package/lib/inventory/cyclonedx20ReadContext.js +380 -0
  65. package/lib/inventory/cyclonedx20ReadEvidence.js +466 -0
  66. package/lib/inventory/cyclonedx20ReadSections.js +599 -0
  67. package/lib/inventory/cyclonedx20Render.js +766 -0
  68. package/lib/inventory/cyclonedx20RenderComponents.js +716 -0
  69. package/lib/inventory/cyclonedx20RenderDefinitions.js +405 -0
  70. package/lib/inventory/cyclonedx20RenderEvidence.js +726 -0
  71. package/lib/inventory/cyclonedx20RenderHardware.js +203 -0
  72. package/lib/inventory/cyclonedx20RenderPatents.js +174 -0
  73. package/lib/inventory/cyclonedx20RenderRefIds.js +314 -0
  74. package/lib/inventory/cyclonedx20RenderSections.js +499 -0
  75. package/lib/inventory/cyclonedx20Tables.js +594 -0
  76. package/lib/inventory/deps.js +106 -13
  77. package/lib/inventory/dosai.js +236 -1
  78. package/lib/inventory/dosaiParsers.js +3 -6
  79. package/lib/inventory/dotnetRuntime.js +164 -14
  80. package/lib/inventory/ecosystemFormulationParsers.js +979 -0
  81. package/lib/inventory/envcontext.js +132 -38
  82. package/lib/inventory/evidenceUtils.js +2 -1
  83. package/lib/inventory/formulationParsers.js +95 -13
  84. package/lib/inventory/hbom.js +45 -6
  85. package/lib/inventory/hbomLoader.js +166 -0
  86. package/lib/inventory/mcpConfigParser.js +5 -0
  87. package/lib/inventory/occurrenceKey.js +90 -0
  88. package/lib/inventory/pqcMigration.js +426 -0
  89. package/lib/inventory/rustFormulationParser.js +21 -10
  90. package/lib/inventory/source.js +65 -6
  91. package/lib/parsers/huggingfaceManifest.js +9 -1
  92. package/lib/parsers/huggingfaceUtils.js +18 -0
  93. package/lib/parsers/kiroPermissions.js +166 -0
  94. package/lib/server/server.js +36 -34
  95. package/lib/stages/postgen/postgen.js +41 -1
  96. package/lib/stages/postgen/specVersionCompat.js +76 -0
  97. package/lib/validator/bomValidator.js +8 -1
  98. package/lib/validator/complianceEngine.js +30 -3
  99. package/lib/validator/complianceRules.js +1416 -4
  100. package/lib/validator/generated/validate-2.0.mjs +57554 -13851
  101. package/lib/validator/index.js +48 -7
  102. package/lib/validator/reporters/json.js +6 -0
  103. package/package.json +9 -9
  104. package/types/bin/repl.d.ts.map +1 -1
  105. package/types/lib/audit/index.d.ts +6 -2
  106. package/types/lib/audit/index.d.ts.map +1 -1
  107. package/types/lib/cli/bomAssembly.d.ts +16 -0
  108. package/types/lib/cli/bomAssembly.d.ts.map +1 -1
  109. package/types/lib/cli/cliOptions.d.ts +6 -0
  110. package/types/lib/cli/cliOptions.d.ts.map +1 -1
  111. package/types/lib/cli/index.d.ts.map +1 -1
  112. package/types/lib/cli/jsBom.d.ts +2 -1
  113. package/types/lib/cli/jsBom.d.ts.map +1 -1
  114. package/types/lib/cli/jvmBom.d.ts +15 -0
  115. package/types/lib/cli/jvmBom.d.ts.map +1 -1
  116. package/types/lib/cli/managedBom.d.ts.map +1 -1
  117. package/types/lib/cli/nativeBom.d.ts.map +1 -1
  118. package/types/lib/core/boundedFile.d.ts +30 -0
  119. package/types/lib/core/boundedFile.d.ts.map +1 -1
  120. package/types/lib/core/env.d.ts +10 -0
  121. package/types/lib/core/env.d.ts.map +1 -1
  122. package/types/lib/core/fs.d.ts +4 -0
  123. package/types/lib/core/fs.d.ts.map +1 -1
  124. package/types/lib/core/globPatterns.d.ts +70 -0
  125. package/types/lib/core/globPatterns.d.ts.map +1 -0
  126. package/types/lib/core/paths.d.ts +9 -0
  127. package/types/lib/core/paths.d.ts.map +1 -1
  128. package/types/lib/core/processTree.d.ts +16 -5
  129. package/types/lib/core/processTree.d.ts.map +1 -1
  130. package/types/lib/core/projectConfig.d.ts +47 -8
  131. package/types/lib/core/projectConfig.d.ts.map +1 -1
  132. package/types/lib/core/toolRegistry.d.ts.map +1 -1
  133. package/types/lib/ecosystems/golem.d.ts.map +1 -1
  134. package/types/lib/ecosystems/gradleutils.d.ts +248 -8
  135. package/types/lib/ecosystems/gradleutils.d.ts.map +1 -1
  136. package/types/lib/ecosystems/jsEvidence.d.ts +14 -1
  137. package/types/lib/ecosystems/jsEvidence.d.ts.map +1 -1
  138. package/types/lib/ecosystems/kosi.d.ts.map +1 -1
  139. package/types/lib/ecosystems/npmVersionResolution.d.ts +119 -0
  140. package/types/lib/ecosystems/npmVersionResolution.d.ts.map +1 -0
  141. package/types/lib/ecosystems/parsers-python.d.ts.map +1 -1
  142. package/types/lib/ecosystems/parsers-rust.d.ts.map +1 -1
  143. package/types/lib/ecosystems/pythonutils.d.ts +1 -1
  144. package/types/lib/ecosystems/remote/huggingface.d.ts.map +1 -1
  145. package/types/lib/ecosystems/rusi.d.ts.map +1 -1
  146. package/types/lib/ecosystems/scalasem.d.ts +58 -16
  147. package/types/lib/ecosystems/scalasem.d.ts.map +1 -1
  148. package/types/lib/evinser/evinser.d.ts +61 -9
  149. package/types/lib/evinser/evinser.d.ts.map +1 -1
  150. package/types/lib/evinser/scalasem.d.ts.map +1 -1
  151. package/types/lib/helpers/agenticToolutils.d.ts +53 -19
  152. package/types/lib/helpers/agenticToolutils.d.ts.map +1 -1
  153. package/types/lib/helpers/bomSigner.d.ts +20 -3
  154. package/types/lib/helpers/bomSigner.d.ts.map +1 -1
  155. package/types/lib/helpers/jssSigner.d.ts +288 -0
  156. package/types/lib/helpers/jssSigner.d.ts.map +1 -0
  157. package/types/lib/helpers/vsixutils.d.ts +303 -19
  158. package/types/lib/helpers/vsixutils.d.ts.map +1 -1
  159. package/types/lib/inventory/agentBlueprint.d.ts +70 -0
  160. package/types/lib/inventory/agentBlueprint.d.ts.map +1 -0
  161. package/types/lib/inventory/agentToolNames.d.ts +51 -0
  162. package/types/lib/inventory/agentToolNames.d.ts.map +1 -0
  163. package/types/lib/inventory/aiCollector.d.ts.map +1 -1
  164. package/types/lib/inventory/aiInventory.d.ts.map +1 -1
  165. package/types/lib/inventory/aiProviders.d.ts +85 -0
  166. package/types/lib/inventory/aiProviders.d.ts.map +1 -0
  167. package/types/lib/inventory/bomUtils.d.ts.map +1 -1
  168. package/types/lib/inventory/ciParsers/githubActionsLock.d.ts +101 -0
  169. package/types/lib/inventory/ciParsers/githubActionsLock.d.ts.map +1 -0
  170. package/types/lib/inventory/citations.d.ts +5 -0
  171. package/types/lib/inventory/citations.d.ts.map +1 -1
  172. package/types/lib/inventory/communityAiConfigParser.d.ts.map +1 -1
  173. package/types/lib/inventory/cyclonedx20.d.ts +99 -0
  174. package/types/lib/inventory/cyclonedx20.d.ts.map +1 -0
  175. package/types/lib/inventory/cyclonedx20Common.d.ts +102 -0
  176. package/types/lib/inventory/cyclonedx20Common.d.ts.map +1 -0
  177. package/types/lib/inventory/cyclonedx20Derived.d.ts +74 -0
  178. package/types/lib/inventory/cyclonedx20Derived.d.ts.map +1 -0
  179. package/types/lib/inventory/cyclonedx20Parties.d.ts +91 -0
  180. package/types/lib/inventory/cyclonedx20Parties.d.ts.map +1 -0
  181. package/types/lib/inventory/cyclonedx20Read.d.ts +51 -0
  182. package/types/lib/inventory/cyclonedx20Read.d.ts.map +1 -0
  183. package/types/lib/inventory/cyclonedx20ReadCommon.d.ts +69 -0
  184. package/types/lib/inventory/cyclonedx20ReadCommon.d.ts.map +1 -0
  185. package/types/lib/inventory/cyclonedx20ReadComponents.d.ts +77 -0
  186. package/types/lib/inventory/cyclonedx20ReadComponents.d.ts.map +1 -0
  187. package/types/lib/inventory/cyclonedx20ReadContext.d.ts +118 -0
  188. package/types/lib/inventory/cyclonedx20ReadContext.d.ts.map +1 -0
  189. package/types/lib/inventory/cyclonedx20ReadEvidence.d.ts +40 -0
  190. package/types/lib/inventory/cyclonedx20ReadEvidence.d.ts.map +1 -0
  191. package/types/lib/inventory/cyclonedx20ReadSections.d.ts +45 -0
  192. package/types/lib/inventory/cyclonedx20ReadSections.d.ts.map +1 -0
  193. package/types/lib/inventory/cyclonedx20Render.d.ts +53 -0
  194. package/types/lib/inventory/cyclonedx20Render.d.ts.map +1 -0
  195. package/types/lib/inventory/cyclonedx20RenderComponents.d.ts +73 -0
  196. package/types/lib/inventory/cyclonedx20RenderComponents.d.ts.map +1 -0
  197. package/types/lib/inventory/cyclonedx20RenderDefinitions.d.ts +29 -0
  198. package/types/lib/inventory/cyclonedx20RenderDefinitions.d.ts.map +1 -0
  199. package/types/lib/inventory/cyclonedx20RenderEvidence.d.ts +110 -0
  200. package/types/lib/inventory/cyclonedx20RenderEvidence.d.ts.map +1 -0
  201. package/types/lib/inventory/cyclonedx20RenderHardware.d.ts +42 -0
  202. package/types/lib/inventory/cyclonedx20RenderHardware.d.ts.map +1 -0
  203. package/types/lib/inventory/cyclonedx20RenderPatents.d.ts +26 -0
  204. package/types/lib/inventory/cyclonedx20RenderPatents.d.ts.map +1 -0
  205. package/types/lib/inventory/cyclonedx20RenderRefIds.d.ts +55 -0
  206. package/types/lib/inventory/cyclonedx20RenderRefIds.d.ts.map +1 -0
  207. package/types/lib/inventory/cyclonedx20RenderSections.d.ts +45 -0
  208. package/types/lib/inventory/cyclonedx20RenderSections.d.ts.map +1 -0
  209. package/types/lib/inventory/cyclonedx20Tables.d.ts +134 -0
  210. package/types/lib/inventory/cyclonedx20Tables.d.ts.map +1 -0
  211. package/types/lib/inventory/deps.d.ts +35 -2
  212. package/types/lib/inventory/deps.d.ts.map +1 -1
  213. package/types/lib/inventory/dosai.d.ts +19 -0
  214. package/types/lib/inventory/dosai.d.ts.map +1 -1
  215. package/types/lib/inventory/dosaiParsers.d.ts.map +1 -1
  216. package/types/lib/inventory/dotnetRuntime.d.ts +51 -4
  217. package/types/lib/inventory/dotnetRuntime.d.ts.map +1 -1
  218. package/types/lib/inventory/ecosystemFormulationParsers.d.ts +73 -0
  219. package/types/lib/inventory/ecosystemFormulationParsers.d.ts.map +1 -0
  220. package/types/lib/inventory/envcontext.d.ts +22 -6
  221. package/types/lib/inventory/envcontext.d.ts.map +1 -1
  222. package/types/lib/inventory/evidenceUtils.d.ts.map +1 -1
  223. package/types/lib/inventory/formulationParsers.d.ts.map +1 -1
  224. package/types/lib/inventory/hbom.d.ts +11 -0
  225. package/types/lib/inventory/hbom.d.ts.map +1 -1
  226. package/types/lib/inventory/hbomLoader.d.ts +54 -0
  227. package/types/lib/inventory/hbomLoader.d.ts.map +1 -1
  228. package/types/lib/inventory/jvmLocalRepos.d.ts +5 -1
  229. package/types/lib/inventory/jvmLocalRepos.d.ts.map +1 -1
  230. package/types/lib/inventory/mcpConfigParser.d.ts.map +1 -1
  231. package/types/lib/inventory/occurrenceKey.d.ts +52 -0
  232. package/types/lib/inventory/occurrenceKey.d.ts.map +1 -0
  233. package/types/lib/inventory/pqcMigration.d.ts +84 -0
  234. package/types/lib/inventory/pqcMigration.d.ts.map +1 -0
  235. package/types/lib/inventory/rustFormulationParser.d.ts +7 -2
  236. package/types/lib/inventory/rustFormulationParser.d.ts.map +1 -1
  237. package/types/lib/inventory/scalaCoords.d.ts.map +1 -1
  238. package/types/lib/inventory/scalaDedupe.d.ts +43 -0
  239. package/types/lib/inventory/scalaDedupe.d.ts.map +1 -0
  240. package/types/lib/inventory/source.d.ts +15 -0
  241. package/types/lib/inventory/source.d.ts.map +1 -1
  242. package/types/lib/parsers/huggingfaceManifest.d.ts +10 -1
  243. package/types/lib/parsers/huggingfaceManifest.d.ts.map +1 -1
  244. package/types/lib/parsers/huggingfaceUtils.d.ts +12 -0
  245. package/types/lib/parsers/huggingfaceUtils.d.ts.map +1 -1
  246. package/types/lib/parsers/kiroPermissions.d.ts +62 -0
  247. package/types/lib/parsers/kiroPermissions.d.ts.map +1 -0
  248. package/types/lib/parsers/vscodeExtensionId.d.ts +48 -0
  249. package/types/lib/parsers/vscodeExtensionId.d.ts.map +1 -0
  250. package/types/lib/server/server.d.ts.map +1 -1
  251. package/types/lib/stages/postgen/postgen.d.ts +7 -0
  252. package/types/lib/stages/postgen/postgen.d.ts.map +1 -1
  253. package/types/lib/stages/postgen/ruleEngine.d.ts.map +1 -1
  254. package/types/lib/stages/postgen/specVersionCompat.d.ts +25 -0
  255. package/types/lib/stages/postgen/specVersionCompat.d.ts.map +1 -1
  256. package/types/lib/validator/bomValidator.d.ts +5 -1
  257. package/types/lib/validator/bomValidator.d.ts.map +1 -1
  258. package/types/lib/validator/complianceEngine.d.ts +4 -4
  259. package/types/lib/validator/complianceEngine.d.ts.map +1 -1
  260. package/types/lib/validator/complianceRules.d.ts +14 -2
  261. package/types/lib/validator/complianceRules.d.ts.map +1 -1
  262. package/types/lib/validator/index.d.ts +10 -0
  263. package/types/lib/validator/index.d.ts.map +1 -1
  264. package/types/lib/validator/reporters/json.d.ts.map +1 -1
@@ -7,6 +7,21 @@ const LOCAL_HBOM_MODULE_URL = new URL(
7
7
  import.meta.url,
8
8
  );
9
9
  const LOCAL_HBOM_MODULE_PATH = fileURLToPath(LOCAL_HBOM_MODULE_URL);
10
+ // The ./cdx20 export of @cdxgen/cdx-hbom (cdx-hbom#26), at the same place
11
+ // relative to a local checkout as the package's exports map gives it.
12
+ const LOCAL_HBOM_MAPPER_PATH = fileURLToPath(
13
+ new URL("../../cdx-hbom/src/common/cdx20.js", import.meta.url),
14
+ );
15
+
16
+ /**
17
+ * The places cdx-hbom is loaded from, in order: a local checkout next to
18
+ * cdxgen, else the installed package.
19
+ */
20
+ export const HBOM_MODULE_LOCATIONS = Object.freeze({
21
+ localModulePath: LOCAL_HBOM_MODULE_PATH,
22
+ localMapperPath: LOCAL_HBOM_MAPPER_PATH,
23
+ packageMapperSpecifier: "@cdxgen/cdx-hbom/cdx20",
24
+ });
10
25
 
11
26
  /**
12
27
  * Resolve the optional cdx-hbom module.
@@ -33,3 +48,154 @@ export async function importHbomModule() {
33
48
  }
34
49
  return hbomModule;
35
50
  }
51
+
52
+ /**
53
+ * Load the optional CycloneDX 2.0 hardware mapper,
54
+ * `toCdx20HardwareComponent`, from the same cdx-hbom that importHbomModule
55
+ * loads: the local checkout when it exists (its src/common/cdx20.js), else
56
+ * the installed package's `./cdx20` export. A cdx-hbom without the mapper
57
+ * (the published 0.7.0 has no `./cdx20` export) or one that fails to load
58
+ * gives null, and the 2.0 render then keeps its generic conversion.
59
+ *
60
+ * @param {object} [locations] Where to look; defaults to
61
+ * HBOM_MODULE_LOCATIONS
62
+ * @returns {Promise<Function|null>} The mapper, or null
63
+ */
64
+ export async function loadHardwareMapper(locations = HBOM_MODULE_LOCATIONS) {
65
+ let specifier = locations.packageMapperSpecifier;
66
+ if (safeExistsSync(locations.localModulePath)) {
67
+ if (!safeExistsSync(locations.localMapperPath)) {
68
+ return null;
69
+ }
70
+ specifier = pathToFileURL(locations.localMapperPath).href;
71
+ }
72
+ let mapperModule;
73
+ try {
74
+ mapperModule = await import(specifier);
75
+ } catch (err) {
76
+ // cdx-hbom not installed, or a release without the ./cdx20 export: the
77
+ // generic conversion applies and nothing is wrong. Any other failure is
78
+ // a broken cdx-hbom and is reported before falling back.
79
+ if (!isMissingMapperError(err, specifier)) {
80
+ console.warn(
81
+ `The cdx-hbom CycloneDX 2.0 hardware mapper could not be loaded, so hardware components use the generic 2.0 conversion: ${err?.message || err}`,
82
+ );
83
+ }
84
+ return null;
85
+ }
86
+ return typeof mapperModule.toCdx20HardwareComponent === "function"
87
+ ? mapperModule.toCdx20HardwareComponent
88
+ : null;
89
+ }
90
+
91
+ /**
92
+ * Whether an import error means the mapper is simply absent: the package is
93
+ * not installed, or its exports map has no `./cdx20`. A missing module
94
+ * imported from inside the mapper is a fault, not an absence.
95
+ *
96
+ * @param {Error} err Import error
97
+ * @param {string} specifier The specifier that was imported
98
+ * @returns {boolean} true when the mapper is absent
99
+ */
100
+ function isMissingMapperError(err, specifier) {
101
+ if (err?.code === "ERR_PACKAGE_PATH_NOT_EXPORTED") {
102
+ return true;
103
+ }
104
+ const message = String(err?.message || "");
105
+ const packageName = specifier.startsWith("@")
106
+ ? specifier.split("/").slice(0, 2).join("/")
107
+ : undefined;
108
+ if (packageName) {
109
+ // Node.js and Bun name the missing package; Deno reports an import that
110
+ // its import map or node_modules cannot resolve.
111
+ return (
112
+ message.includes(`'${packageName}'`) ||
113
+ message.includes(`"${packageName}"`) ||
114
+ message.includes(`${packageName}/cdx20`) ||
115
+ (err?.code === "ERR_MODULE_NOT_FOUND" && message.includes(packageName))
116
+ );
117
+ }
118
+ return false;
119
+ }
120
+
121
+ /** The identifier policy cdx-hbom records when raw identifiers were kept. */
122
+ export const RAW_IDENTIFIER_POLICY = "raw-identifiers-enabled";
123
+
124
+ /**
125
+ * The identifier policy the collector recorded for the run, on the HBOM
126
+ * subject (`metadata.component`) or in `metadata.properties`.
127
+ *
128
+ * @param {object} internalBom The 1.x-shaped internal model
129
+ * @returns {string|undefined} The `cdx:hbom:identifierPolicy` value
130
+ */
131
+ export function recordedIdentifierPolicy(internalBom) {
132
+ for (const properties of [
133
+ internalBom?.metadata?.component?.properties,
134
+ internalBom?.metadata?.properties,
135
+ ]) {
136
+ const value = (Array.isArray(properties) ? properties : []).find(
137
+ (property) => property?.name === "cdx:hbom:identifierPolicy",
138
+ )?.value;
139
+ if (typeof value === "string") {
140
+ return value;
141
+ }
142
+ }
143
+ return undefined;
144
+ }
145
+
146
+ /**
147
+ * The renderCycloneDx20 context for an internal model: the hardware mapper
148
+ * and its identifier options when the model has a component with a
149
+ * cdx:hbom:* property and a mapper is available, otherwise an empty context,
150
+ * so a BOM without hardware never loads cdx-hbom. Hardware identifiers are
151
+ * asserted only when the collector recorded `raw-identifiers-enabled` for the
152
+ * run (it does when HBOM generation was asked to include sensitive
153
+ * identifiers); a redacted run never yields identifiers, whichever command
154
+ * renders it.
155
+ *
156
+ * @param {object} internalBom The 1.x-shaped internal model
157
+ * @param {object} [locations] Passed to loadHardwareMapper
158
+ * @returns {Promise<{hardwareMapper?: Function, hardwareOptions?: {includeSensitiveIdentifiers: boolean, identifierPolicy?: string}}>}
159
+ * The render context
160
+ */
161
+ export async function hardwareRenderContext(internalBom, locations) {
162
+ if (!hasHardwareComponent(internalBom)) {
163
+ return {};
164
+ }
165
+ const hardwareMapper = await loadHardwareMapper(locations);
166
+ if (!hardwareMapper) {
167
+ return {};
168
+ }
169
+ const identifierPolicy = recordedIdentifierPolicy(internalBom);
170
+ const hardwareOptions = {
171
+ includeSensitiveIdentifiers: identifierPolicy === RAW_IDENTIFIER_POLICY,
172
+ };
173
+ if (identifierPolicy !== undefined) {
174
+ hardwareOptions.identifierPolicy = identifierPolicy;
175
+ }
176
+ return { hardwareMapper, hardwareOptions };
177
+ }
178
+
179
+ function hasHardwareComponent(internalBom) {
180
+ const pending = [
181
+ internalBom?.metadata?.component,
182
+ ...(Array.isArray(internalBom?.components) ? internalBom.components : []),
183
+ ];
184
+ while (pending.length) {
185
+ const component = pending.pop();
186
+ if (!component || typeof component !== "object") {
187
+ continue;
188
+ }
189
+ if (
190
+ (component.properties || []).some((property) =>
191
+ `${property?.name ?? ""}`.startsWith("cdx:hbom:"),
192
+ )
193
+ ) {
194
+ return true;
195
+ }
196
+ if (Array.isArray(component.components)) {
197
+ pending.push(...component.components);
198
+ }
199
+ }
200
+ return false;
201
+ }
@@ -39,6 +39,8 @@ const MCP_CONFIG_PATTERNS = [
39
39
  "**/.zed/settings.json",
40
40
  ".roo/mcp.json",
41
41
  "**/.roo/mcp.json",
42
+ ".kiro/settings/mcp.json",
43
+ "**/.kiro/settings/mcp.json",
42
44
  ".codex/config.toml",
43
45
  "**/.codex/config.toml",
44
46
  ];
@@ -115,6 +117,9 @@ function configFormat(filePath) {
115
117
  if (lowerPath.includes("/.roo/")) {
116
118
  return "roo";
117
119
  }
120
+ if (lowerPath.includes("/.kiro/settings/")) {
121
+ return "kiro";
122
+ }
118
123
  if (
119
124
  lowerPath.includes("/.codex/") ||
120
125
  lowerPath.endsWith(".codex/config.toml")
@@ -0,0 +1,90 @@
1
+ /**
2
+ * The key of a place in a purl's occurrence set (`purlLocationMap`).
3
+ *
4
+ * Every location that enters an occurrence set is keyed by this function,
5
+ * whatever evidence source added it: the seeding from the input BOM
6
+ * (`initFromSbom`), the atom `usages` and `callsites` slices, the golem, rusi,
7
+ * kosi, dosai and scalasem reports, the C include attribution and the Swift
8
+ * semantics slices. Backslashes become `/`, so a place spelled with `\` in the
9
+ * input BOM (Windows cdxgen output) and `/` in a slice is one occurrence, not
10
+ * two (issue 4726). The path is otherwise left as spelled: no resolving, no
11
+ * case folding, no stripping of a leading `./`.
12
+ *
13
+ * A place a line already names is keyed `file#line`; a place a callsites
14
+ * record names down to its column (counted from 0, as atom writes it) is keyed
15
+ * `file:line:offset`, so two use
16
+ * sites on one line are two occurrences. An occurrence with only `location`
17
+ * and `line` names the line as a whole: it is the same place as any use site
18
+ * that line carries, and it is kept as an occurrence of its own only while no
19
+ * `file:line:offset` key of that line exists (the writer drops the line-only
20
+ * key then, see `dropSubsumedOccurrenceKeys`). That rule is what keeps a
21
+ * re-run of evinse over its own output at the same occurrences: the first run
22
+ * writes the `file:line:offset` keys, and the second run seeds and re-adds
23
+ * exactly those.
24
+ *
25
+ * @param {string} location File path or other location text
26
+ * @param {number} [line] Line number; not a positive number means the location names no line
27
+ * @param {number} [offset] Column within the line, counted from 0 as atom writes it; a value that is not an integer of 0 or more (atom writes -1 for an unknown column) means the place is the line
28
+ * @returns {string|undefined} Key in the `file:line:offset`, `file#line` or plain `file` shape; undefined when the location is empty
29
+ */
30
+ export function occurrenceLocationKey(location, line, offset) {
31
+ const normalized = `${location ?? ""}`.trim().replaceAll("\\", "/");
32
+ if (!normalized) {
33
+ return undefined;
34
+ }
35
+ if (!(line > 0)) {
36
+ return normalized;
37
+ }
38
+ return Number.isInteger(offset) && offset >= 0
39
+ ? `${normalized}:${line}:${offset}`
40
+ : `${normalized}#${line}`;
41
+ }
42
+
43
+ /**
44
+ * Drop the occurrence keys a use-site key subsumes.
45
+ *
46
+ * A `file:line:offset` key names a use site on a line; the line-only
47
+ * `file#line` key of the same line names no place of its own any more, so it
48
+ * is removed rather than counted beside the use sites (issue 4726: an
49
+ * occurrence seeded from an input BOM with only `location` and `line` is the
50
+ * same place as a callsites occurrence at that line).
51
+ *
52
+ * @param {string[]} keys Occurrence-set keys
53
+ * @returns {string[]} The keys without the subsumed line-only entries
54
+ */
55
+ export function dropSubsumedOccurrenceKeys(keys) {
56
+ const linesWithOffset = new Set();
57
+ for (const key of keys) {
58
+ const withOffset = /^(.*):(\d+):(\d+)$/.exec(key);
59
+ if (withOffset) {
60
+ linesWithOffset.add(`${withOffset[1]}#${withOffset[2]}`);
61
+ }
62
+ }
63
+ if (!linesWithOffset.size) {
64
+ return keys;
65
+ }
66
+ return keys.filter((key) => {
67
+ const lineOnly = /^(.*)#(\d+)$/.exec(key);
68
+ return !(lineOnly && linesWithOffset.has(`${lineOnly[1]}#${lineOnly[2]}`));
69
+ });
70
+ }
71
+
72
+ /**
73
+ * The location part of an occurrence-set key: `src/a.js` for `src/a.js#3`,
74
+ * `src/a.js:3:14` and `src/a.js` alike.
75
+ *
76
+ * @param {string} key Key made by `occurrenceLocationKey`
77
+ * @returns {string} The location the key names
78
+ */
79
+ export function occurrenceKeyLocation(key) {
80
+ const text = `${key ?? ""}`;
81
+ const withOffset = /^(.*):(\d+):(\d+)$/.exec(text);
82
+ if (withOffset) {
83
+ return withOffset[1];
84
+ }
85
+ const hash = text.lastIndexOf("#");
86
+ if (hash > 0 && /^\d+$/.test(text.slice(hash + 1))) {
87
+ return text.slice(0, hash);
88
+ }
89
+ return text;
90
+ }