@cdxgen/cdxgen 13.0.1 → 13.2.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.
- package/README.md +30 -16
- package/bin/audit.js +6 -0
- package/bin/cdxgen.js +141 -7
- package/bin/evinse.js +3 -1
- package/data/component-tags.json +8 -1
- package/data/crypto-oid.json +88 -12
- package/data/frameworks-list.json +86 -1
- package/data/remediations.json +1167 -0
- package/data/rules/ai-bom.yaml +78 -0
- package/data/rules/asar-archives.yaml +1 -1
- package/data/rules/build-fidelity.yaml +782 -0
- package/data/rules/cargo-rust.yaml +132 -0
- package/data/rules/mcp-servers.yaml +122 -0
- package/data/rules/package-integrity.yaml +13 -13
- package/lib/audit/index.js +48 -4
- package/lib/audit/scoring.js +2 -8
- package/lib/audit/targets.js +6 -1
- package/lib/cli/bomAssembly.js +32 -1
- package/lib/cli/cliOptions.js +94 -7
- package/lib/cli/index.js +268 -49
- package/lib/cli/jsBom.js +91 -5
- package/lib/cli/jvmBom.js +1515 -1314
- package/lib/cli/managedBom.js +249 -28
- package/lib/cli/nativeBom.js +986 -10
- package/lib/core/activity.js +120 -2
- package/lib/core/buildLedger.js +799 -0
- package/lib/core/deferredExit.js +141 -0
- package/lib/core/env.js +108 -2
- package/lib/core/fs.js +60 -0
- package/lib/core/logger.js +12 -99
- package/lib/core/severity.js +16 -0
- package/lib/core/syncFileWriter.js +106 -0
- package/lib/core/userAgent.js +151 -0
- package/lib/ecosystems/cargoCache.js +364 -0
- package/lib/ecosystems/caxa.js +13 -5
- package/lib/ecosystems/cppEvidence.js +40 -2
- package/lib/ecosystems/ecosystems.js +250 -91
- package/lib/ecosystems/golem.js +11 -1
- package/lib/ecosystems/gradleutils.js +498 -17
- package/lib/ecosystems/kosi.js +1256 -0
- package/lib/ecosystems/parsers-crystal.js +179 -0
- package/lib/ecosystems/parsers-dotnet.js +69 -39
- package/lib/ecosystems/parsers-elm.js +816 -0
- package/lib/ecosystems/parsers-gleam.js +1 -1
- package/lib/ecosystems/parsers-js.js +26 -0
- package/lib/ecosystems/parsers-julia.js +268 -0
- package/lib/ecosystems/parsers-jvm.js +9 -0
- package/lib/ecosystems/parsers-lua.js +218 -0
- package/lib/ecosystems/parsers-misc.js +188 -2
- package/lib/ecosystems/parsers-nim.js +221 -0
- package/lib/ecosystems/parsers-opam.js +180 -0
- package/lib/ecosystems/parsers-perl.js +277 -0
- package/lib/ecosystems/parsers-python.js +172 -36
- package/lib/ecosystems/parsers-r.js +148 -0
- package/lib/ecosystems/parsers-rebar.js +411 -0
- package/lib/ecosystems/parsers-rust.js +944 -19
- package/lib/ecosystems/parsers-spack.js +204 -0
- package/lib/ecosystems/parsers-stack.js +264 -0
- package/lib/ecosystems/parsers-terraform.js +194 -0
- package/lib/ecosystems/pypiClassifiers.js +326 -0
- package/lib/ecosystems/pythonutils.js +49 -1
- package/lib/ecosystems/rubyutils.js +13 -0
- package/lib/ecosystems/rusi.js +126 -6
- package/lib/evinser/evinser.js +141 -13
- package/lib/helpers/agenticToolutils.js +925 -0
- package/lib/helpers/remote/dependency-track.js +81 -14
- package/lib/inventory/agentFormulationParser.js +57 -4
- package/lib/inventory/aiCollector.js +504 -10
- package/lib/inventory/aiInventory.js +12 -0
- package/lib/inventory/analyzer.js +488 -30
- package/lib/inventory/astWorker.js +6 -0
- package/lib/inventory/auditCategories.js +17 -0
- package/lib/inventory/cbomutils.js +30 -0
- package/lib/inventory/cdxrs.js +7 -2
- package/lib/inventory/communityAiConfigParser.js +215 -2
- package/lib/inventory/depsUtils.js +72 -0
- package/lib/inventory/dosai.js +508 -22
- package/lib/inventory/envcontext.js +215 -24
- package/lib/inventory/evidenceUtils.js +13 -0
- package/lib/inventory/fetchBatch.js +131 -2
- package/lib/inventory/fetchRate.js +74 -11
- package/lib/inventory/forgeEnricher.js +3 -2
- package/lib/inventory/jvmToolEnv.js +594 -0
- package/lib/inventory/mcpConfigParser.js +166 -2
- package/lib/inventory/mcpDiscovery.js +11 -0
- package/lib/inventory/mcpServerManifest.js +389 -0
- package/lib/inventory/mcpbBundle.js +419 -0
- package/lib/inventory/osinfo.js +1 -0
- package/lib/inventory/plugins.js +3 -0
- package/lib/inventory/protobom.js +54 -88
- package/lib/inventory/protobomLoader.js +4 -0
- package/lib/inventory/rustFormulationParser.js +1 -1
- package/lib/inventory/source.js +10 -4
- package/lib/inventory/stylePackageRefs.js +41 -0
- package/lib/inventory/svelteUtils.js +524 -0
- package/lib/inventory/toolRequirements.js +903 -0
- package/lib/managers/binary.js +24 -0
- package/lib/managers/docker.js +26 -5
- package/lib/parsers/huggingfaceUtils.js +15 -7
- package/lib/parsers/onnx.js +294 -0
- package/lib/parsers/safetensors.js +114 -0
- package/lib/server/server.js +1 -1
- package/lib/stages/postgen/annotationBuilder.js +97 -0
- package/lib/stages/postgen/auditBom.js +76 -79
- package/lib/stages/postgen/introspection/annotate.js +320 -0
- package/lib/stages/postgen/introspection/commandFacts.js +293 -0
- package/lib/stages/postgen/introspection/emit.js +192 -0
- package/lib/stages/postgen/introspection/formulationEvidence.js +427 -0
- package/lib/stages/postgen/introspection/markers.js +250 -0
- package/lib/stages/postgen/introspection/reflect.js +1214 -0
- package/lib/stages/postgen/introspection/report.js +1208 -0
- package/lib/stages/postgen/introspection/score.js +1067 -0
- package/lib/stages/postgen/introspection/shapeCommand.js +304 -0
- package/lib/stages/postgen/parentEdge.js +156 -0
- package/lib/stages/postgen/postgen.js +284 -3
- package/lib/stages/postgen/ruleEngine.js +17 -0
- package/lib/stages/pregen/envAudit.js +42 -2
- package/lib/stages/pregen/pregen.js +1171 -6
- package/lib/third-party/arborist/snapshots/calc-dep-flags.test.cjs +462 -0
- package/lib/validator/bomValidator.js +11 -2
- package/package.json +26 -26
- package/types/lib/audit/index.d.ts.map +1 -1
- package/types/lib/audit/scoring.d.ts +2 -8
- package/types/lib/audit/scoring.d.ts.map +1 -1
- package/types/lib/audit/targets.d.ts.map +1 -1
- package/types/lib/cli/bomAssembly.d.ts.map +1 -1
- package/types/lib/cli/cliOptions.d.ts +2 -1
- package/types/lib/cli/cliOptions.d.ts.map +1 -1
- package/types/lib/cli/index.d.ts +10 -2
- package/types/lib/cli/index.d.ts.map +1 -1
- package/types/lib/cli/jsBom.d.ts +23 -0
- package/types/lib/cli/jsBom.d.ts.map +1 -1
- package/types/lib/cli/jvmBom.d.ts.map +1 -1
- package/types/lib/cli/managedBom.d.ts +33 -0
- package/types/lib/cli/managedBom.d.ts.map +1 -1
- package/types/lib/cli/nativeBom.d.ts +88 -8
- package/types/lib/cli/nativeBom.d.ts.map +1 -1
- package/types/lib/core/activity.d.ts.map +1 -1
- package/types/lib/core/buildLedger.d.ts +272 -0
- package/types/lib/core/buildLedger.d.ts.map +1 -0
- package/types/lib/core/deferredExit.d.ts +84 -0
- package/types/lib/core/deferredExit.d.ts.map +1 -0
- package/types/lib/core/env.d.ts +43 -1
- package/types/lib/core/env.d.ts.map +1 -1
- package/types/lib/core/fs.d.ts +21 -0
- package/types/lib/core/fs.d.ts.map +1 -1
- package/types/lib/core/logger.d.ts +2 -11
- package/types/lib/core/logger.d.ts.map +1 -1
- package/types/lib/core/severity.d.ts +11 -0
- package/types/lib/core/severity.d.ts.map +1 -0
- package/types/lib/core/syncFileWriter.d.ts +33 -0
- package/types/lib/core/syncFileWriter.d.ts.map +1 -0
- package/types/lib/core/userAgent.d.ts +56 -0
- package/types/lib/core/userAgent.d.ts.map +1 -0
- package/types/lib/ecosystems/cargoCache.d.ts +75 -0
- package/types/lib/ecosystems/cargoCache.d.ts.map +1 -0
- package/types/lib/ecosystems/caxa.d.ts.map +1 -1
- package/types/lib/ecosystems/cppEvidence.d.ts +1 -1
- package/types/lib/ecosystems/cppEvidence.d.ts.map +1 -1
- package/types/lib/ecosystems/ecosystems.d.ts +15 -1
- package/types/lib/ecosystems/ecosystems.d.ts.map +1 -1
- package/types/lib/ecosystems/gradleutils.d.ts +53 -0
- package/types/lib/ecosystems/gradleutils.d.ts.map +1 -1
- package/types/lib/ecosystems/kosi.d.ts +73 -0
- package/types/lib/ecosystems/kosi.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-crystal.d.ts +27 -0
- package/types/lib/ecosystems/parsers-crystal.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-dotnet.d.ts +19 -0
- package/types/lib/ecosystems/parsers-dotnet.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-elm.d.ts +79 -0
- package/types/lib/ecosystems/parsers-elm.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-js.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-julia.d.ts +57 -0
- package/types/lib/ecosystems/parsers-julia.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-jvm.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-lua.d.ts +50 -0
- package/types/lib/ecosystems/parsers-lua.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-misc.d.ts +23 -0
- package/types/lib/ecosystems/parsers-misc.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-nim.d.ts +43 -0
- package/types/lib/ecosystems/parsers-nim.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-opam.d.ts +31 -0
- package/types/lib/ecosystems/parsers-opam.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-perl.d.ts +36 -0
- package/types/lib/ecosystems/parsers-perl.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-python.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-r.d.ts +35 -0
- package/types/lib/ecosystems/parsers-r.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-rebar.d.ts +42 -0
- package/types/lib/ecosystems/parsers-rebar.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-rust.d.ts +199 -0
- package/types/lib/ecosystems/parsers-rust.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-spack.d.ts +33 -0
- package/types/lib/ecosystems/parsers-spack.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-stack.d.ts +35 -0
- package/types/lib/ecosystems/parsers-stack.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-terraform.d.ts +34 -0
- package/types/lib/ecosystems/parsers-terraform.d.ts.map +1 -0
- package/types/lib/ecosystems/pypiClassifiers.d.ts +80 -0
- package/types/lib/ecosystems/pypiClassifiers.d.ts.map +1 -0
- package/types/lib/ecosystems/pythonutils.d.ts +21 -1
- package/types/lib/ecosystems/pythonutils.d.ts.map +1 -1
- package/types/lib/ecosystems/rubyutils.d.ts.map +1 -1
- package/types/lib/ecosystems/rusi.d.ts.map +1 -1
- package/types/lib/evinser/evinser.d.ts +34 -1
- package/types/lib/evinser/evinser.d.ts.map +1 -1
- package/types/lib/helpers/agenticToolutils.d.ts +87 -0
- package/types/lib/helpers/agenticToolutils.d.ts.map +1 -0
- package/types/lib/helpers/remote/dependency-track.d.ts +45 -4
- package/types/lib/helpers/remote/dependency-track.d.ts.map +1 -1
- package/types/lib/inventory/agentFormulationParser.d.ts.map +1 -1
- package/types/lib/inventory/aiCollector.d.ts.map +1 -1
- package/types/lib/inventory/aiInventory.d.ts.map +1 -1
- package/types/lib/inventory/analyzer.d.ts.map +1 -1
- package/types/lib/inventory/auditCategories.d.ts +12 -0
- package/types/lib/inventory/auditCategories.d.ts.map +1 -1
- package/types/lib/inventory/cbomutils.d.ts.map +1 -1
- package/types/lib/inventory/communityAiConfigParser.d.ts.map +1 -1
- package/types/lib/inventory/depsUtils.d.ts.map +1 -1
- package/types/lib/inventory/dosai.d.ts +43 -0
- package/types/lib/inventory/dosai.d.ts.map +1 -1
- package/types/lib/inventory/envcontext.d.ts.map +1 -1
- package/types/lib/inventory/evidenceUtils.d.ts.map +1 -1
- package/types/lib/inventory/fetchBatch.d.ts +43 -0
- package/types/lib/inventory/fetchBatch.d.ts.map +1 -1
- package/types/lib/inventory/fetchRate.d.ts +9 -6
- package/types/lib/inventory/fetchRate.d.ts.map +1 -1
- package/types/lib/inventory/forgeEnricher.d.ts.map +1 -1
- package/types/lib/inventory/jvmToolEnv.d.ts +190 -0
- package/types/lib/inventory/jvmToolEnv.d.ts.map +1 -0
- package/types/lib/inventory/mcpConfigParser.d.ts.map +1 -1
- package/types/lib/inventory/mcpDiscovery.d.ts.map +1 -1
- package/types/lib/inventory/mcpServerManifest.d.ts +19 -0
- package/types/lib/inventory/mcpServerManifest.d.ts.map +1 -0
- package/types/lib/inventory/mcpbBundle.d.ts +19 -0
- package/types/lib/inventory/mcpbBundle.d.ts.map +1 -0
- package/types/lib/inventory/osinfo.d.ts.map +1 -1
- package/types/lib/inventory/plugins.d.ts.map +1 -1
- package/types/lib/inventory/protobom.d.ts +18 -13
- package/types/lib/inventory/protobom.d.ts.map +1 -1
- package/types/lib/inventory/protobomLoader.d.ts.map +1 -1
- package/types/lib/inventory/source.d.ts.map +1 -1
- package/types/lib/inventory/stylePackageRefs.d.ts +17 -0
- package/types/lib/inventory/stylePackageRefs.d.ts.map +1 -0
- package/types/lib/inventory/svelteUtils.d.ts +124 -0
- package/types/lib/inventory/svelteUtils.d.ts.map +1 -0
- package/types/lib/inventory/toolRequirements.d.ts +216 -0
- package/types/lib/inventory/toolRequirements.d.ts.map +1 -0
- package/types/lib/managers/binary.d.ts.map +1 -1
- package/types/lib/managers/docker.d.ts.map +1 -1
- package/types/lib/parsers/huggingfaceUtils.d.ts +8 -1
- package/types/lib/parsers/huggingfaceUtils.d.ts.map +1 -1
- package/types/lib/parsers/onnx.d.ts +28 -0
- package/types/lib/parsers/onnx.d.ts.map +1 -0
- package/types/lib/parsers/safetensors.d.ts +22 -0
- package/types/lib/parsers/safetensors.d.ts.map +1 -0
- package/types/lib/stages/postgen/annotationBuilder.d.ts +53 -0
- package/types/lib/stages/postgen/annotationBuilder.d.ts.map +1 -0
- package/types/lib/stages/postgen/auditBom.d.ts.map +1 -1
- package/types/lib/stages/postgen/introspection/annotate.d.ts +81 -0
- package/types/lib/stages/postgen/introspection/annotate.d.ts.map +1 -0
- package/types/lib/stages/postgen/introspection/commandFacts.d.ts +32 -0
- package/types/lib/stages/postgen/introspection/commandFacts.d.ts.map +1 -0
- package/types/lib/stages/postgen/introspection/emit.d.ts +71 -0
- package/types/lib/stages/postgen/introspection/emit.d.ts.map +1 -0
- package/types/lib/stages/postgen/introspection/formulationEvidence.d.ts +154 -0
- package/types/lib/stages/postgen/introspection/formulationEvidence.d.ts.map +1 -0
- package/types/lib/stages/postgen/introspection/markers.d.ts +58 -0
- package/types/lib/stages/postgen/introspection/markers.d.ts.map +1 -0
- package/types/lib/stages/postgen/introspection/reflect.d.ts +77 -0
- package/types/lib/stages/postgen/introspection/reflect.d.ts.map +1 -0
- package/types/lib/stages/postgen/introspection/report.d.ts +85 -0
- package/types/lib/stages/postgen/introspection/report.d.ts.map +1 -0
- package/types/lib/stages/postgen/introspection/score.d.ts +149 -0
- package/types/lib/stages/postgen/introspection/score.d.ts.map +1 -0
- package/types/lib/stages/postgen/introspection/shapeCommand.d.ts +79 -0
- package/types/lib/stages/postgen/introspection/shapeCommand.d.ts.map +1 -0
- package/types/lib/stages/postgen/parentEdge.d.ts +35 -0
- package/types/lib/stages/postgen/parentEdge.d.ts.map +1 -0
- package/types/lib/stages/postgen/postgen.d.ts +35 -2
- package/types/lib/stages/postgen/postgen.d.ts.map +1 -1
- package/types/lib/stages/postgen/ruleEngine.d.ts.map +1 -1
- package/types/lib/stages/pregen/envAudit.d.ts.map +1 -1
- package/types/lib/stages/pregen/pregen.d.ts +131 -0
- package/types/lib/stages/pregen/pregen.d.ts.map +1 -1
- package/types/lib/validator/bomValidator.d.ts.map +1 -1
package/lib/cli/index.js
CHANGED
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
recordActivity,
|
|
19
19
|
setActivityContext,
|
|
20
20
|
} from "../core/activity.js";
|
|
21
|
+
import { recordDegradation } from "../core/buildLedger.js";
|
|
21
22
|
import { hasAnyProjectType, PROJECT_TYPE_ALIASES } from "../core/env.js";
|
|
22
23
|
import {
|
|
23
24
|
clearFileDiscoveryCache,
|
|
@@ -31,6 +32,11 @@ import { thoughtLog } from "../core/logger.js";
|
|
|
31
32
|
import { mapWithConcurrency } from "../core/parallel.js";
|
|
32
33
|
import { dirNameStr } from "../core/paths.js";
|
|
33
34
|
import { ui } from "../core/ui.js";
|
|
35
|
+
import { isElmProjectFile } from "../ecosystems/parsers-elm.js";
|
|
36
|
+
import {
|
|
37
|
+
isJuliaManifestFile,
|
|
38
|
+
isJuliaProjectFile,
|
|
39
|
+
} from "../ecosystems/parsers-julia.js";
|
|
34
40
|
import {
|
|
35
41
|
parseBitbucketPipelinesFile,
|
|
36
42
|
parseContainerFile,
|
|
@@ -40,7 +46,7 @@ import {
|
|
|
40
46
|
} from "../ecosystems/parsers-misc.js";
|
|
41
47
|
import { isPyLockFile } from "../ecosystems/pylockutils.js";
|
|
42
48
|
import {
|
|
43
|
-
|
|
49
|
+
buildDependencyTrackBomRequest,
|
|
44
50
|
getDependencyTrackBomApiUrl,
|
|
45
51
|
} from "../helpers/remote/dependency-track.js";
|
|
46
52
|
import { optionIncludesAiInventoryProjectType } from "../inventory/aiInventory.js";
|
|
@@ -89,6 +95,7 @@ import {
|
|
|
89
95
|
determineParentComponent,
|
|
90
96
|
} from "./bomAssembly.js";
|
|
91
97
|
import {
|
|
98
|
+
createAgenticBom,
|
|
92
99
|
createAsarBom,
|
|
93
100
|
createCaxaBom,
|
|
94
101
|
createChromeExtensionBom,
|
|
@@ -125,24 +132,36 @@ import {
|
|
|
125
132
|
createGitHubBom,
|
|
126
133
|
createHelmBom,
|
|
127
134
|
createJenkinsBom,
|
|
135
|
+
createPerlBom,
|
|
128
136
|
createPHPBom,
|
|
129
137
|
createPythonBom,
|
|
138
|
+
createRBom,
|
|
130
139
|
createRubyBom,
|
|
140
|
+
createTerraformBom,
|
|
131
141
|
} from "./managedBom.js";
|
|
132
142
|
import {
|
|
133
143
|
createCargoCacheBom,
|
|
134
144
|
createClojureBom,
|
|
135
145
|
createCocoaBom,
|
|
136
146
|
createCppBom,
|
|
147
|
+
createCrystalBom,
|
|
137
148
|
createDartBom,
|
|
138
149
|
createElixirBom,
|
|
150
|
+
createElmBom,
|
|
151
|
+
createErlangBom,
|
|
139
152
|
createGleamBom,
|
|
140
153
|
createGoBom,
|
|
141
154
|
createHaskellBom,
|
|
155
|
+
createJuliaBom,
|
|
156
|
+
createLuaBom,
|
|
157
|
+
createNimBom,
|
|
142
158
|
createNixBom,
|
|
159
|
+
createOCamlBom,
|
|
143
160
|
createRustBom,
|
|
161
|
+
createSpackBom,
|
|
144
162
|
createSwiftBom,
|
|
145
163
|
createZigBom,
|
|
164
|
+
findStackLockFiles,
|
|
146
165
|
getCargoCacheDir,
|
|
147
166
|
} from "./nativeBom.js";
|
|
148
167
|
|
|
@@ -153,26 +172,42 @@ export {
|
|
|
153
172
|
createGitHubBom,
|
|
154
173
|
createHelmBom,
|
|
155
174
|
createJenkinsBom,
|
|
175
|
+
createPerlBom,
|
|
156
176
|
createPHPBom,
|
|
157
177
|
createPixiBom,
|
|
158
178
|
createPythonBom,
|
|
179
|
+
createRBom,
|
|
159
180
|
createRubyBom,
|
|
181
|
+
createTerraformBom,
|
|
160
182
|
} from "./managedBom.js";
|
|
161
183
|
export {
|
|
162
184
|
createClojureBom,
|
|
163
185
|
createCocoaBom,
|
|
164
186
|
createCppBom,
|
|
187
|
+
createCrystalBom,
|
|
165
188
|
createDartBom,
|
|
166
189
|
createElixirBom,
|
|
190
|
+
createElmBom,
|
|
191
|
+
createErlangBom,
|
|
167
192
|
createGleamBom,
|
|
168
193
|
createGoBom,
|
|
169
194
|
createHaskellBom,
|
|
195
|
+
createJuliaBom,
|
|
196
|
+
createLuaBom,
|
|
197
|
+
createNimBom,
|
|
170
198
|
createNixBom,
|
|
199
|
+
createOCamlBom,
|
|
171
200
|
createRustBom,
|
|
201
|
+
createSpackBom,
|
|
172
202
|
createSwiftBom,
|
|
173
203
|
createZigBom,
|
|
174
204
|
} from "./nativeBom.js";
|
|
175
205
|
|
|
206
|
+
import {
|
|
207
|
+
deferFailOnError,
|
|
208
|
+
isDeferredFailOnError,
|
|
209
|
+
} from "../core/deferredExit.js";
|
|
210
|
+
|
|
176
211
|
const dirName = dirNameStr;
|
|
177
212
|
|
|
178
213
|
const isWin = _platform() === "win32";
|
|
@@ -816,6 +851,23 @@ export async function createMultiXBom(pathList, options) {
|
|
|
816
851
|
// from here on, so repeated walks of them can share one view of the tree.
|
|
817
852
|
setDirWalkCacheRoot(options.allLayersExplodedDir);
|
|
818
853
|
const scanOnePath = async (path) => {
|
|
854
|
+
try {
|
|
855
|
+
return await scanOnePathInner(path);
|
|
856
|
+
} catch (err) {
|
|
857
|
+
if (!isDeferredFailOnError(err)) {
|
|
858
|
+
throw err;
|
|
859
|
+
}
|
|
860
|
+
// The failing path contributes nothing, and the remaining paths still
|
|
861
|
+
// do: fail-on-error scopes the loss to the leg that failed.
|
|
862
|
+
return {
|
|
863
|
+
components: [],
|
|
864
|
+
dependencies: [],
|
|
865
|
+
options: { ...sharedOptions },
|
|
866
|
+
parentSubComponents: [],
|
|
867
|
+
};
|
|
868
|
+
}
|
|
869
|
+
};
|
|
870
|
+
const scanOnePathInner = async (path) => {
|
|
819
871
|
// Each path accumulates into its own lists and its own view of options, so
|
|
820
872
|
// that legs which record a parent component or a tool cannot overwrite
|
|
821
873
|
// another path's. The lists are merged below in pathList order.
|
|
@@ -1433,6 +1485,14 @@ export async function createMultiXBom(pathList, options) {
|
|
|
1433
1485
|
);
|
|
1434
1486
|
}
|
|
1435
1487
|
setProjectTypeActivityContext("jar", path);
|
|
1488
|
+
recordDegradation("jvm.jar.heuristic", {
|
|
1489
|
+
ecosystem: "java",
|
|
1490
|
+
tool: "jar",
|
|
1491
|
+
impact: "versions",
|
|
1492
|
+
path,
|
|
1493
|
+
detail:
|
|
1494
|
+
"Components are being inferred by scanning jar/war/ear files from disk.",
|
|
1495
|
+
});
|
|
1436
1496
|
bomData = await createJarBom(path, options);
|
|
1437
1497
|
if (bomData?.bomJson?.components?.length) {
|
|
1438
1498
|
thoughtLog(
|
|
@@ -2029,7 +2089,8 @@ export async function createXBom(path, options) {
|
|
|
2029
2089
|
`${options.multiProject ? "**/" : ""}cabal.project.freeze`,
|
|
2030
2090
|
options,
|
|
2031
2091
|
);
|
|
2032
|
-
|
|
2092
|
+
const stackLockDetectFiles = findStackLockFiles(path, options);
|
|
2093
|
+
if (hackageFiles.length || stackLockDetectFiles.length) {
|
|
2033
2094
|
return createHaskellBom(path, options);
|
|
2034
2095
|
}
|
|
2035
2096
|
|
|
@@ -2254,6 +2315,131 @@ export async function createXBom(path, options) {
|
|
|
2254
2315
|
if (gleamTomlFiles.length) {
|
|
2255
2316
|
return await createGleamBom(path, options);
|
|
2256
2317
|
}
|
|
2318
|
+
|
|
2319
|
+
// Julia
|
|
2320
|
+
const juliaProjectFiles = getAllFiles(
|
|
2321
|
+
path,
|
|
2322
|
+
`${options.multiProject ? "**/" : ""}Project.toml`,
|
|
2323
|
+
options,
|
|
2324
|
+
);
|
|
2325
|
+
const juliaManifestFiles = getAllFiles(
|
|
2326
|
+
path,
|
|
2327
|
+
`${options.multiProject ? "**/" : ""}Manifest.toml`,
|
|
2328
|
+
options,
|
|
2329
|
+
);
|
|
2330
|
+
// `Project.toml` is not a name Julia owns — Cloud Native Buildpacks use it
|
|
2331
|
+
// too — so dispatch only when a file actually declares a Julia environment.
|
|
2332
|
+
if (
|
|
2333
|
+
juliaManifestFiles.some(isJuliaManifestFile) ||
|
|
2334
|
+
juliaProjectFiles.some(isJuliaProjectFile)
|
|
2335
|
+
) {
|
|
2336
|
+
return await createJuliaBom(path, options);
|
|
2337
|
+
}
|
|
2338
|
+
|
|
2339
|
+
// Erlang with rebar3
|
|
2340
|
+
const rebarLockFiles = getAllFiles(
|
|
2341
|
+
path,
|
|
2342
|
+
`${options.multiProject ? "**/" : ""}rebar.lock`,
|
|
2343
|
+
options,
|
|
2344
|
+
);
|
|
2345
|
+
if (rebarLockFiles.length) {
|
|
2346
|
+
return await createErlangBom(path, options);
|
|
2347
|
+
}
|
|
2348
|
+
|
|
2349
|
+
// OCaml with opam
|
|
2350
|
+
const opamLockedFiles = getAllFiles(
|
|
2351
|
+
path,
|
|
2352
|
+
`${options.multiProject ? "**/" : ""}*.opam.locked`,
|
|
2353
|
+
options,
|
|
2354
|
+
);
|
|
2355
|
+
if (opamLockedFiles.length) {
|
|
2356
|
+
return await createOCamlBom(path, options);
|
|
2357
|
+
}
|
|
2358
|
+
|
|
2359
|
+
// Elm with elm.json (0.19) or elm-package.json (0.18)
|
|
2360
|
+
const elmJsonFiles = getAllFiles(
|
|
2361
|
+
path,
|
|
2362
|
+
`${options.multiProject ? "**/" : ""}elm.json`,
|
|
2363
|
+
options,
|
|
2364
|
+
).filter(isElmProjectFile);
|
|
2365
|
+
const legacyElmFiles = getAllFiles(
|
|
2366
|
+
path,
|
|
2367
|
+
`${options.multiProject ? "**/" : ""}elm-package.json`,
|
|
2368
|
+
options,
|
|
2369
|
+
);
|
|
2370
|
+
if (elmJsonFiles.length || legacyElmFiles.length) {
|
|
2371
|
+
return await createElmBom(path, options);
|
|
2372
|
+
}
|
|
2373
|
+
|
|
2374
|
+
// Crystal with shards
|
|
2375
|
+
const shardYmlFiles = getAllFiles(
|
|
2376
|
+
path,
|
|
2377
|
+
`${options.multiProject ? "**/" : ""}shard.yml`,
|
|
2378
|
+
options,
|
|
2379
|
+
);
|
|
2380
|
+
if (shardYmlFiles.length) {
|
|
2381
|
+
return await createCrystalBom(path, options);
|
|
2382
|
+
}
|
|
2383
|
+
|
|
2384
|
+
// Nim with nimble
|
|
2385
|
+
const nimbleFiles = getAllFiles(
|
|
2386
|
+
path,
|
|
2387
|
+
`${options.multiProject ? "**/" : ""}*.nimble`,
|
|
2388
|
+
options,
|
|
2389
|
+
);
|
|
2390
|
+
if (nimbleFiles.length) {
|
|
2391
|
+
return await createNimBom(path, options);
|
|
2392
|
+
}
|
|
2393
|
+
|
|
2394
|
+
// Lua with LuaRocks
|
|
2395
|
+
const rockspecFiles = getAllFiles(
|
|
2396
|
+
path,
|
|
2397
|
+
`${options.multiProject ? "**/" : ""}*.rockspec`,
|
|
2398
|
+
options,
|
|
2399
|
+
);
|
|
2400
|
+
if (rockspecFiles.length) {
|
|
2401
|
+
return await createLuaBom(path, options);
|
|
2402
|
+
}
|
|
2403
|
+
|
|
2404
|
+
// Spack environments
|
|
2405
|
+
const spackLockFiles = getAllFiles(
|
|
2406
|
+
path,
|
|
2407
|
+
`${options.multiProject ? "**/" : ""}spack.lock`,
|
|
2408
|
+
options,
|
|
2409
|
+
);
|
|
2410
|
+
if (spackLockFiles.length) {
|
|
2411
|
+
return await createSpackBom(path, options);
|
|
2412
|
+
}
|
|
2413
|
+
|
|
2414
|
+
// R with renv
|
|
2415
|
+
const renvLockFiles = getAllFiles(
|
|
2416
|
+
path,
|
|
2417
|
+
`${options.multiProject ? "**/" : ""}renv.lock`,
|
|
2418
|
+
options,
|
|
2419
|
+
);
|
|
2420
|
+
if (renvLockFiles.length) {
|
|
2421
|
+
return createRBom(path, options);
|
|
2422
|
+
}
|
|
2423
|
+
|
|
2424
|
+
// Perl with Carton
|
|
2425
|
+
const cpanSnapshotFiles = getAllFiles(
|
|
2426
|
+
path,
|
|
2427
|
+
`${options.multiProject ? "**/" : ""}cpanfile.snapshot`,
|
|
2428
|
+
options,
|
|
2429
|
+
);
|
|
2430
|
+
if (cpanSnapshotFiles.length) {
|
|
2431
|
+
return createPerlBom(path, options);
|
|
2432
|
+
}
|
|
2433
|
+
|
|
2434
|
+
// Terraform and OpenTofu providers
|
|
2435
|
+
const tfLockFiles = getAllFiles(
|
|
2436
|
+
path,
|
|
2437
|
+
`${options.multiProject ? "**/" : ""}.terraform.lock.hcl`,
|
|
2438
|
+
options,
|
|
2439
|
+
);
|
|
2440
|
+
if (tfLockFiles.length) {
|
|
2441
|
+
return createTerraformBom(path, options);
|
|
2442
|
+
}
|
|
2257
2443
|
}
|
|
2258
2444
|
|
|
2259
2445
|
/**
|
|
@@ -2292,7 +2478,28 @@ export async function createHBom(_path, options) {
|
|
|
2292
2478
|
* @param {Object} options Parse options from the cli
|
|
2293
2479
|
* @returns {Promise<Object>} Promise resolving to BOM object
|
|
2294
2480
|
*/
|
|
2481
|
+
/**
|
|
2482
|
+
* Generate a BOM for one path, letting a deferred fail-on-error abort return
|
|
2483
|
+
* the empty BOM the flag promises rather than unwinding past the reports.
|
|
2484
|
+
*
|
|
2485
|
+
* @param {string} path Source path.
|
|
2486
|
+
* @param {Object} options CLI options.
|
|
2487
|
+
* @returns {Promise<Object>} BOM NS data.
|
|
2488
|
+
*/
|
|
2295
2489
|
export async function createBom(path, options) {
|
|
2490
|
+
try {
|
|
2491
|
+
return await createBomForPath(path, options);
|
|
2492
|
+
} catch (err) {
|
|
2493
|
+
if (!isDeferredFailOnError(err)) {
|
|
2494
|
+
throw err;
|
|
2495
|
+
}
|
|
2496
|
+
// fail-on-error forbids an incomplete result, so the extractor kept
|
|
2497
|
+
// nothing; the CLI still writes the reports and exits non-zero.
|
|
2498
|
+
return buildBomNSData(options, [], "", { src: path, filename: "" });
|
|
2499
|
+
}
|
|
2500
|
+
}
|
|
2501
|
+
|
|
2502
|
+
async function createBomForPath(path, options) {
|
|
2296
2503
|
clearFileDiscoveryCache();
|
|
2297
2504
|
let { projectType } = options;
|
|
2298
2505
|
if (!projectType) {
|
|
@@ -2327,7 +2534,11 @@ export async function createBom(path, options) {
|
|
|
2327
2534
|
console.log(
|
|
2328
2535
|
`OS BOM generation has failed due to problems with exporting the image ${path}`,
|
|
2329
2536
|
);
|
|
2330
|
-
options
|
|
2537
|
+
deferFailOnError(options, {
|
|
2538
|
+
ecosystem: "container",
|
|
2539
|
+
tool: "docker",
|
|
2540
|
+
detail: "exporting the image for the OS BOM failed",
|
|
2541
|
+
});
|
|
2331
2542
|
return {};
|
|
2332
2543
|
}
|
|
2333
2544
|
isContainerMode = true;
|
|
@@ -2367,7 +2578,11 @@ export async function createBom(path, options) {
|
|
|
2367
2578
|
console.log(
|
|
2368
2579
|
`OCI BOM generation has failed due to problems with exporting the image ${path}.`,
|
|
2369
2580
|
);
|
|
2370
|
-
options
|
|
2581
|
+
deferFailOnError(options, {
|
|
2582
|
+
ecosystem: "container",
|
|
2583
|
+
tool: "docker",
|
|
2584
|
+
detail: "exporting the image for the OCI BOM failed",
|
|
2585
|
+
});
|
|
2371
2586
|
return {};
|
|
2372
2587
|
}
|
|
2373
2588
|
if (DEBUG_MODE) {
|
|
@@ -2576,6 +2791,39 @@ export async function createBom(path, options) {
|
|
|
2576
2791
|
if (PROJECT_TYPE_ALIASES["gleam"].includes(projectType[0])) {
|
|
2577
2792
|
return await createGleamBom(path, options);
|
|
2578
2793
|
}
|
|
2794
|
+
if (PROJECT_TYPE_ALIASES["julia"].includes(projectType[0])) {
|
|
2795
|
+
return await createJuliaBom(path, options);
|
|
2796
|
+
}
|
|
2797
|
+
if (PROJECT_TYPE_ALIASES["erlang"].includes(projectType[0])) {
|
|
2798
|
+
return await createErlangBom(path, options);
|
|
2799
|
+
}
|
|
2800
|
+
if (PROJECT_TYPE_ALIASES["ocaml"].includes(projectType[0])) {
|
|
2801
|
+
return await createOCamlBom(path, options);
|
|
2802
|
+
}
|
|
2803
|
+
if (PROJECT_TYPE_ALIASES["elm"].includes(projectType[0])) {
|
|
2804
|
+
return await createElmBom(path, options);
|
|
2805
|
+
}
|
|
2806
|
+
if (PROJECT_TYPE_ALIASES["crystal"].includes(projectType[0])) {
|
|
2807
|
+
return await createCrystalBom(path, options);
|
|
2808
|
+
}
|
|
2809
|
+
if (PROJECT_TYPE_ALIASES["nim"].includes(projectType[0])) {
|
|
2810
|
+
return await createNimBom(path, options);
|
|
2811
|
+
}
|
|
2812
|
+
if (PROJECT_TYPE_ALIASES["lua"].includes(projectType[0])) {
|
|
2813
|
+
return await createLuaBom(path, options);
|
|
2814
|
+
}
|
|
2815
|
+
if (PROJECT_TYPE_ALIASES["spack"].includes(projectType[0])) {
|
|
2816
|
+
return await createSpackBom(path, options);
|
|
2817
|
+
}
|
|
2818
|
+
if (PROJECT_TYPE_ALIASES["r"].includes(projectType[0])) {
|
|
2819
|
+
return createRBom(path, options);
|
|
2820
|
+
}
|
|
2821
|
+
if (PROJECT_TYPE_ALIASES["perl"].includes(projectType[0])) {
|
|
2822
|
+
return createPerlBom(path, options);
|
|
2823
|
+
}
|
|
2824
|
+
if (PROJECT_TYPE_ALIASES["terraform"].includes(projectType[0])) {
|
|
2825
|
+
return createTerraformBom(path, options);
|
|
2826
|
+
}
|
|
2579
2827
|
if (PROJECT_TYPE_ALIASES["caxa"].includes(projectType[0])) {
|
|
2580
2828
|
return await createCaxaBom(path, options);
|
|
2581
2829
|
}
|
|
@@ -2585,6 +2833,9 @@ export async function createBom(path, options) {
|
|
|
2585
2833
|
if (PROJECT_TYPE_ALIASES["vscode-extension"].includes(projectType[0])) {
|
|
2586
2834
|
return await createVscodeExtensionBom(path, options);
|
|
2587
2835
|
}
|
|
2836
|
+
if (PROJECT_TYPE_ALIASES["agentic"].includes(projectType[0])) {
|
|
2837
|
+
return await createAgenticBom(path, options);
|
|
2838
|
+
}
|
|
2588
2839
|
if (PROJECT_TYPE_ALIASES["chrome-extension"].includes(projectType[0])) {
|
|
2589
2840
|
return await createChromeExtensionBom(path, options);
|
|
2590
2841
|
}
|
|
@@ -2660,8 +2911,8 @@ export async function submitBom(args, bomContents) {
|
|
|
2660
2911
|
});
|
|
2661
2912
|
return undefined;
|
|
2662
2913
|
}
|
|
2663
|
-
const
|
|
2664
|
-
if (!
|
|
2914
|
+
const bomRequest = buildDependencyTrackBomRequest(args, bomContents);
|
|
2915
|
+
if (!bomRequest) {
|
|
2665
2916
|
console.log(
|
|
2666
2917
|
"Invalid Dependency-Track submission arguments. Provide projectId or projectName (projectVersion defaults to main) and specify parent project either by UUID or by parent project name + version.",
|
|
2667
2918
|
);
|
|
@@ -2674,21 +2925,21 @@ export async function submitBom(args, bomContents) {
|
|
|
2674
2925
|
serverUrl,
|
|
2675
2926
|
"params",
|
|
2676
2927
|
args.projectName,
|
|
2677
|
-
|
|
2928
|
+
args.projectVersion || "main",
|
|
2678
2929
|
);
|
|
2679
2930
|
}
|
|
2680
2931
|
try {
|
|
2681
2932
|
const requestOptions = {
|
|
2682
|
-
method: "
|
|
2933
|
+
method: "POST",
|
|
2683
2934
|
followRedirect: false,
|
|
2684
2935
|
https: {
|
|
2685
2936
|
rejectUnauthorized: !args.skipDtTlsCheck,
|
|
2686
2937
|
},
|
|
2687
2938
|
headers: {
|
|
2688
2939
|
"X-Api-Key": (args.apiKey || "").replace(/[\r\n]/g, ""),
|
|
2689
|
-
"Content-Type":
|
|
2940
|
+
"Content-Type": bomRequest.contentType,
|
|
2690
2941
|
},
|
|
2691
|
-
|
|
2942
|
+
body: bomRequest.body,
|
|
2692
2943
|
responseType: "json",
|
|
2693
2944
|
context: {
|
|
2694
2945
|
activityIntent: "bom-submit",
|
|
@@ -2711,47 +2962,15 @@ export async function submitBom(args, bomContents) {
|
|
|
2711
2962
|
);
|
|
2712
2963
|
} else if (error.response && error.response.statusCode === 405) {
|
|
2713
2964
|
console.log(
|
|
2714
|
-
|
|
2965
|
+
`The server at ${serverUrl} does not accept a multipart/form-data POST on /api/v1/bom. Check that the URL points to a Dependency-Track 4.x or later API server.`,
|
|
2966
|
+
);
|
|
2967
|
+
} else if (DEBUG_MODE) {
|
|
2968
|
+
console.log(
|
|
2969
|
+
"Unable to submit the SBOM to the Dependency-Track server",
|
|
2970
|
+
error,
|
|
2715
2971
|
);
|
|
2716
|
-
// Method not allowed errors
|
|
2717
|
-
try {
|
|
2718
|
-
return await cdxgenAgent(dependencyTrackApiUrl, {
|
|
2719
|
-
method: "POST",
|
|
2720
|
-
followRedirect: false,
|
|
2721
|
-
https: {
|
|
2722
|
-
rejectUnauthorized: !args.skipDtTlsCheck,
|
|
2723
|
-
},
|
|
2724
|
-
headers: {
|
|
2725
|
-
"X-Api-Key": (args.apiKey || "").replace(/[\r\n]/g, ""),
|
|
2726
|
-
"Content-Type": "application/json",
|
|
2727
|
-
},
|
|
2728
|
-
json: bomPayload,
|
|
2729
|
-
responseType: "json",
|
|
2730
|
-
context: {
|
|
2731
|
-
activityIntent: "bom-submit",
|
|
2732
|
-
},
|
|
2733
|
-
}).json();
|
|
2734
|
-
} catch (error) {
|
|
2735
|
-
if (DEBUG_MODE) {
|
|
2736
|
-
console.log(
|
|
2737
|
-
"Unable to submit the SBOM to the Dependency-Track server using POST method",
|
|
2738
|
-
error,
|
|
2739
|
-
);
|
|
2740
|
-
} else {
|
|
2741
|
-
console.log(
|
|
2742
|
-
"Unable to submit the SBOM to the Dependency-Track server using POST method",
|
|
2743
|
-
);
|
|
2744
|
-
}
|
|
2745
|
-
}
|
|
2746
2972
|
} else {
|
|
2747
|
-
|
|
2748
|
-
console.log(
|
|
2749
|
-
"Unable to submit the SBOM to the Dependency-Track server using POST method",
|
|
2750
|
-
error,
|
|
2751
|
-
);
|
|
2752
|
-
} else {
|
|
2753
|
-
console.log("Unable to submit the SBOM to the Dependency-Track server");
|
|
2754
|
-
}
|
|
2973
|
+
console.log("Unable to submit the SBOM to the Dependency-Track server");
|
|
2755
2974
|
}
|
|
2756
2975
|
// rethrow error as function is async and we should try to catch it in the caller
|
|
2757
2976
|
throw error;
|
package/lib/cli/jsBom.js
CHANGED
|
@@ -11,6 +11,8 @@ import {
|
|
|
11
11
|
readEnvironmentVariable,
|
|
12
12
|
recordSensitiveFileRead,
|
|
13
13
|
} from "../core/activity.js";
|
|
14
|
+
import { recordDegradation } from "../core/buildLedger.js";
|
|
15
|
+
import { deferFailOnError } from "../core/deferredExit.js";
|
|
14
16
|
import { hasAnyProjectType, isPackageManagerAllowed } from "../core/env.js";
|
|
15
17
|
import { getAllFiles, safeExistsSync, safeSpawnSync } from "../core/fs.js";
|
|
16
18
|
import { thoughtLog } from "../core/logger.js";
|
|
@@ -51,6 +53,10 @@ import {
|
|
|
51
53
|
fetchHuggingFaceAssetInventory,
|
|
52
54
|
normalizeHuggingFaceReference,
|
|
53
55
|
} from "../ecosystems/remote/huggingface.js";
|
|
56
|
+
import {
|
|
57
|
+
AGENTIC_TOOL_PURL_TYPE,
|
|
58
|
+
collectAgenticTools,
|
|
59
|
+
} from "../helpers/agenticToolutils.js";
|
|
54
60
|
import {
|
|
55
61
|
cleanupTempDir,
|
|
56
62
|
collectInstalledExtensions,
|
|
@@ -98,6 +104,13 @@ const isWin = _platform() === "win32";
|
|
|
98
104
|
* local Modelfile/`.gguf` file input. Returns the explicit selection from
|
|
99
105
|
* `getExactAiInventoryType` when one is present.
|
|
100
106
|
*
|
|
107
|
+
* Direct HuggingFace interpretation of the source path is opt-in: only
|
|
108
|
+
* unambiguous references (`pkg:huggingface/...` purls and huggingface.co
|
|
109
|
+
* URLs) are recognized on their own. Bare `owner/repo`-shaped values are
|
|
110
|
+
* ordinary relative paths (eg: `repotests/sveltejs-realworld`) unless an AI
|
|
111
|
+
* inventory type such as `-t ai` is explicitly selected, in which case
|
|
112
|
+
* `getExactAiInventoryType` already returned it above.
|
|
113
|
+
*
|
|
101
114
|
* @param {string} path Project or file path
|
|
102
115
|
* @param {object} options CLI options
|
|
103
116
|
* @returns {string|undefined} The detected AI inventory type (`"ai"`) or undefined
|
|
@@ -107,7 +120,7 @@ export function getDirectAiInventoryType(path, options) {
|
|
|
107
120
|
if (exactAiInventoryType) {
|
|
108
121
|
return exactAiInventoryType;
|
|
109
122
|
}
|
|
110
|
-
if (normalizeHuggingFaceReference(path)) {
|
|
123
|
+
if (normalizeHuggingFaceReference(path, { explicitOnly: true })) {
|
|
111
124
|
return "ai";
|
|
112
125
|
}
|
|
113
126
|
try {
|
|
@@ -155,8 +168,10 @@ export async function createNodejsBom(path, options) {
|
|
|
155
168
|
excludedAiInventoryTypes,
|
|
156
169
|
);
|
|
157
170
|
let aiInventory = { components: [], dependencies: [], services: [] };
|
|
171
|
+
// A value that exists on the local filesystem is always a project path -
|
|
172
|
+
// never a remote model id - so existing inputs skip remote resolution.
|
|
158
173
|
const directHuggingFaceSource =
|
|
159
|
-
exactAiInventoryType === "ai"
|
|
174
|
+
exactAiInventoryType === "ai" && !safeExistsSync(path)
|
|
160
175
|
? normalizeHuggingFaceReference(path)
|
|
161
176
|
: undefined;
|
|
162
177
|
if (directHuggingFaceSource?.repoId) {
|
|
@@ -529,6 +544,14 @@ export async function createNodejsBom(path, options) {
|
|
|
529
544
|
isSecureMode &&
|
|
530
545
|
!installArgs.join(" ").includes("--allow-git")
|
|
531
546
|
) {
|
|
547
|
+
recordDegradation("js.git-dependency", {
|
|
548
|
+
ecosystem: "npm",
|
|
549
|
+
tool: pkgMgr,
|
|
550
|
+
impact: "integrity",
|
|
551
|
+
command: `${pkgMgr} ${installArgs.join(" ")}`,
|
|
552
|
+
detail:
|
|
553
|
+
"Secure mode npm install may still fetch and install git dependencies.",
|
|
554
|
+
});
|
|
532
555
|
console.log(
|
|
533
556
|
"Consider passing '--allow-git=none' via the environment variable NPM_INSTALL_ARGS to prevent any git dependencies from being fetched and installed via npm.",
|
|
534
557
|
);
|
|
@@ -580,6 +603,13 @@ export async function createNodejsBom(path, options) {
|
|
|
580
603
|
`**PACKAGE MANAGER**: Let's run the '${pkgMgr}' command with the arguments '${installArgs.join(" ")}' to generate the needed lock files.`,
|
|
581
604
|
);
|
|
582
605
|
}
|
|
606
|
+
recordDegradation("js.no-lockfile", {
|
|
607
|
+
ecosystem: "npm",
|
|
608
|
+
tool: pkgMgr,
|
|
609
|
+
impact: "versions",
|
|
610
|
+
detail:
|
|
611
|
+
"No lockfile was found for this project, so the SBOM is generated without pinned dependency versions.",
|
|
612
|
+
});
|
|
583
613
|
console.warn(
|
|
584
614
|
"\x1b[1;35mNotice: Generating an SBOM without a lockfile is risky and non-deterministic. Consider generating and committing the lockfile to your repository to ensure reproducible builds and SBOMs.\x1b[0m",
|
|
585
615
|
);
|
|
@@ -640,7 +670,11 @@ export async function createNodejsBom(path, options) {
|
|
|
640
670
|
console.log("---------------");
|
|
641
671
|
console.log(result.stderr);
|
|
642
672
|
}
|
|
643
|
-
options
|
|
673
|
+
deferFailOnError(options, {
|
|
674
|
+
ecosystem: "npm",
|
|
675
|
+
tool: "npm",
|
|
676
|
+
detail: "the npm command failed",
|
|
677
|
+
});
|
|
644
678
|
} else {
|
|
645
679
|
anyInstallSuccess = true;
|
|
646
680
|
}
|
|
@@ -936,7 +970,11 @@ export async function createNodejsBom(path, options) {
|
|
|
936
970
|
);
|
|
937
971
|
if (result.status === 1 || result.error) {
|
|
938
972
|
console.error(result.stdout, result.stderr);
|
|
939
|
-
options
|
|
973
|
+
deferFailOnError(options, {
|
|
974
|
+
ecosystem: "npm",
|
|
975
|
+
tool: "npm",
|
|
976
|
+
detail: "the yarn or pnpm command failed",
|
|
977
|
+
});
|
|
940
978
|
}
|
|
941
979
|
}
|
|
942
980
|
// Look for shrinkwrap file
|
|
@@ -1013,7 +1051,11 @@ export async function createNodejsBom(path, options) {
|
|
|
1013
1051
|
pnpmLock,
|
|
1014
1052
|
"was found!",
|
|
1015
1053
|
);
|
|
1016
|
-
options
|
|
1054
|
+
deferFailOnError(options, {
|
|
1055
|
+
ecosystem: "npm",
|
|
1056
|
+
tool: "npm",
|
|
1057
|
+
detail: "no JavaScript dependency evidence could be collected",
|
|
1058
|
+
});
|
|
1017
1059
|
}
|
|
1018
1060
|
if (
|
|
1019
1061
|
yarnLockFiles?.length &&
|
|
@@ -1719,6 +1761,50 @@ export async function createVscodeExtensionBom(path, options) {
|
|
|
1719
1761
|
});
|
|
1720
1762
|
}
|
|
1721
1763
|
|
|
1764
|
+
/**
|
|
1765
|
+
* Create a BOM that catalogs agentic CLI tools installed for the current user
|
|
1766
|
+
* (for example Kiro CLI, zcode, opencode, and Claude Code), along with the
|
|
1767
|
+
* agents, plugins, and providers they define.
|
|
1768
|
+
*
|
|
1769
|
+
* The scan is read-only and value-redacting: it records tool versions where a
|
|
1770
|
+
* declarative source exists, plus structural counts, but never reads
|
|
1771
|
+
* credentials, transcripts, session logs, or telemetry.
|
|
1772
|
+
*
|
|
1773
|
+
* @param {string} path Positional input. A host scan does not read a project
|
|
1774
|
+
* tree, so an explicit path other than the current directory is rejected
|
|
1775
|
+
* rather than silently ignored.
|
|
1776
|
+
* @param {Object} options Parse options from the CLI
|
|
1777
|
+
* @returns {Promise<Object>} Promise resolving to BOM data
|
|
1778
|
+
*/
|
|
1779
|
+
export async function createAgenticBom(path, options) {
|
|
1780
|
+
// Guard against a surprising host-wide scan masquerading as a project scan.
|
|
1781
|
+
// cdxgen always supplies a positional path (defaulting to "."), so only an
|
|
1782
|
+
// explicit path that resolves somewhere other than the current directory is
|
|
1783
|
+
// treated as a mistake.
|
|
1784
|
+
const resolvedPath = path ? resolve(path) : process.cwd();
|
|
1785
|
+
if (resolvedPath !== process.cwd()) {
|
|
1786
|
+
throw new Error(
|
|
1787
|
+
"The 'agentic' project type performs a host-wide scan of installed " +
|
|
1788
|
+
"agentic CLI tool directories and does not accept a path argument. " +
|
|
1789
|
+
`Re-run without the path (received '${path}').`,
|
|
1790
|
+
);
|
|
1791
|
+
}
|
|
1792
|
+
// Must not go to stdout: every entry point keeps stdout reserved for the BOM
|
|
1793
|
+
// payload so `cdxgen -t agentic -o -` stays pipeable.
|
|
1794
|
+
thoughtLog(
|
|
1795
|
+
"Scanning the current user's home directory for installed agentic CLI tools.",
|
|
1796
|
+
);
|
|
1797
|
+
const inventory = collectAgenticTools(options);
|
|
1798
|
+
const pkgList = trimComponents(inventory.components || []);
|
|
1799
|
+
return buildBomNSData(options, pkgList, AGENTIC_TOOL_PURL_TYPE, {
|
|
1800
|
+
src: "~",
|
|
1801
|
+
filename: "agentic-cli-tools",
|
|
1802
|
+
nsMapping: {},
|
|
1803
|
+
dependencies: inventory.dependencies || [],
|
|
1804
|
+
services: inventory.services || [],
|
|
1805
|
+
});
|
|
1806
|
+
}
|
|
1807
|
+
|
|
1722
1808
|
/**
|
|
1723
1809
|
* Function to create BOM for Electron ASAR archives.
|
|
1724
1810
|
*
|