@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.
- package/README.md +17 -10
- package/bin/audit.js +7 -4
- package/bin/cdxgen.js +260 -37
- package/bin/convert.js +146 -22
- package/bin/evinse.js +28 -3
- package/bin/repl.js +47 -3
- package/bin/sign.js +211 -34
- package/bin/tracebom.js +18 -6
- package/bin/validate.js +24 -3
- package/bin/verify.js +113 -5
- package/data/behavior-taxonomy.schema.json +1491 -0
- package/data/cyclonedx-2.0-bundled.schema.json +18606 -5528
- package/data/cyclonedx-2.0-cryptography-defs.schema.json +857 -0
- package/data/license-aliases.json +24 -2
- package/data/pqc-migration.json +239 -0
- package/data/remediations.json +176 -0
- package/data/rules/ai-bom.yaml +1 -1
- package/data/rules/brotli-decoder.yaml +107 -0
- package/data/rules/cbom-security.yaml +4 -3
- package/data/rules/package-integrity.yaml +28 -0
- package/data/rules/vscode-extensions.yaml +75 -0
- package/data/spdx-license-list.json +121 -7
- package/data/spdx-licenses.json +69 -0
- package/data/spdx.schema.json +845 -2
- package/lib/audit/index.js +25 -3
- package/lib/cli/bomAssembly.js +172 -4
- package/lib/cli/cliOptions.js +121 -17
- package/lib/cli/index.js +720 -902
- package/lib/cli/jsBom.js +156 -64
- package/lib/cli/jvmBom.js +602 -86
- package/lib/cli/managedBom.js +161 -19
- package/lib/cli/nativeBom.js +52 -5
- package/lib/core/boundedFile.js +344 -0
- package/lib/core/brotliProbe.js +182 -0
- package/lib/core/env.js +34 -0
- package/lib/core/fs.js +138 -3
- package/lib/core/globPatterns.js +218 -0
- package/lib/core/httpClient.js +98 -1
- package/lib/core/lockPaths.js +38 -0
- package/lib/core/paths.js +24 -1
- package/lib/core/processTree.js +100 -8
- package/lib/core/projectConfig.js +332 -25
- package/lib/core/toolRegistry.js +184 -0
- package/lib/ecosystems/cppEvidence.js +263 -106
- package/lib/ecosystems/cppIncludeResolver.js +16 -5
- package/lib/ecosystems/denoutils.js +2 -2
- package/lib/ecosystems/ecosystems.js +25 -10
- package/lib/ecosystems/gemHostProbe.js +301 -0
- package/lib/ecosystems/golem.js +3 -8
- package/lib/ecosystems/gradleutils.js +1909 -229
- package/lib/ecosystems/jsEvidence.js +90 -38
- package/lib/ecosystems/kosi.js +3 -5
- package/lib/ecosystems/npmVersionResolution.js +376 -0
- package/lib/ecosystems/parsers-bazel.js +107 -6
- package/lib/ecosystems/parsers-js.js +505 -22
- package/lib/ecosystems/parsers-misc.js +209 -20
- package/lib/ecosystems/parsers-python.js +178 -30
- package/lib/ecosystems/parsers-rust.js +117 -15
- package/lib/ecosystems/pythonutils.js +128 -2
- package/lib/ecosystems/remote/huggingface.js +22 -0
- package/lib/ecosystems/rubyutils.js +538 -31
- package/lib/ecosystems/rusi.js +2 -4
- package/lib/ecosystems/scalacliutils.js +2 -0
- package/lib/ecosystems/scalasem.js +798 -152
- package/lib/ecosystems/vendoredCode.js +237 -3
- package/lib/ecosystems/venvProbe.js +360 -0
- package/lib/evinser/evinser.js +536 -71
- package/lib/evinser/scalasem.js +5 -1
- package/lib/helpers/agenticToolutils.js +525 -94
- package/lib/helpers/bomSigner.js +43 -9
- package/lib/helpers/jssSigner.js +1276 -0
- package/lib/helpers/vsixutils.js +1574 -315
- package/lib/inventory/agentBlueprint.js +193 -0
- package/lib/inventory/agentToolNames.js +145 -0
- package/lib/inventory/aiCollector.js +153 -7
- package/lib/inventory/aiInventory.js +44 -8
- package/lib/inventory/aiProviders.js +324 -0
- package/lib/inventory/atomUtils.js +77 -0
- package/lib/inventory/bomUtils.js +8 -1
- package/lib/inventory/brotliDecoder.js +142 -0
- package/lib/inventory/buildToolRateLimit.js +1 -1
- package/lib/inventory/cbomutils.js +56 -7
- package/lib/inventory/ciParsers/githubActionsLock.js +821 -0
- package/lib/inventory/citations.js +31 -2
- package/lib/inventory/communityAiConfigParser.js +978 -80
- package/lib/inventory/cyclonedx20.js +152 -0
- package/lib/inventory/cyclonedx20Common.js +286 -0
- package/lib/inventory/cyclonedx20Derived.js +159 -0
- package/lib/inventory/cyclonedx20Parties.js +552 -0
- package/lib/inventory/cyclonedx20Read.js +768 -0
- package/lib/inventory/cyclonedx20ReadCommon.js +374 -0
- package/lib/inventory/cyclonedx20ReadComponents.js +692 -0
- package/lib/inventory/cyclonedx20ReadContext.js +380 -0
- package/lib/inventory/cyclonedx20ReadEvidence.js +466 -0
- package/lib/inventory/cyclonedx20ReadSections.js +599 -0
- package/lib/inventory/cyclonedx20Render.js +766 -0
- package/lib/inventory/cyclonedx20RenderComponents.js +716 -0
- package/lib/inventory/cyclonedx20RenderDefinitions.js +405 -0
- package/lib/inventory/cyclonedx20RenderEvidence.js +726 -0
- package/lib/inventory/cyclonedx20RenderHardware.js +203 -0
- package/lib/inventory/cyclonedx20RenderPatents.js +174 -0
- package/lib/inventory/cyclonedx20RenderRefIds.js +314 -0
- package/lib/inventory/cyclonedx20RenderSections.js +499 -0
- package/lib/inventory/cyclonedx20Tables.js +594 -0
- package/lib/inventory/deps.js +141 -13
- package/lib/inventory/dosai.js +375 -6
- package/lib/inventory/dosaiParsers.js +3 -6
- package/lib/inventory/dotnetRuntime.js +367 -0
- package/lib/inventory/ecosystemFormulationParsers.js +979 -0
- package/lib/inventory/envcontext.js +436 -48
- package/lib/inventory/evidenceUtils.js +13 -1
- package/lib/inventory/fetchBatch.js +1 -1
- package/lib/inventory/formulationParsers.js +124 -14
- package/lib/inventory/gtfobins.js +13 -0
- package/lib/inventory/hbom.js +45 -6
- package/lib/inventory/hbomLoader.js +166 -0
- package/lib/inventory/hostRuntimeProbe.js +686 -0
- package/lib/inventory/jvmLocalRepos.js +9 -2
- package/lib/inventory/jvmToolEnv.js +29 -0
- package/lib/inventory/licenseEnhancer.js +12 -0
- package/lib/inventory/mavenCentralMirror.js +534 -0
- package/lib/inventory/mcpConfigParser.js +5 -0
- package/lib/inventory/nodeBuildInfo.js +218 -0
- package/lib/inventory/nodeHostProbe.js +202 -0
- package/lib/inventory/occurrenceKey.js +90 -0
- package/lib/inventory/osPackageResolver.js +182 -0
- package/lib/inventory/phpBuildInfo.js +10 -59
- package/lib/inventory/phpHostProbe.js +32 -488
- package/lib/inventory/pqcMigration.js +426 -0
- package/lib/inventory/rubyBuildInfo.js +972 -0
- package/lib/inventory/rubyHostProbe.js +218 -0
- package/lib/inventory/rustFormulationParser.js +21 -10
- package/lib/inventory/scalaCoords.js +4 -3
- package/lib/inventory/scalaDedupe.js +440 -0
- package/lib/inventory/source.js +114 -8
- package/lib/managers/binary.js +337 -3
- package/lib/managers/docker.js +79 -0
- package/lib/parsers/huggingfaceManifest.js +9 -1
- package/lib/parsers/huggingfaceUtils.js +18 -0
- package/lib/parsers/kiroPermissions.js +166 -0
- package/lib/parsers/largeJson.js +28 -11
- package/lib/parsers/vscodeExtensionId.js +183 -0
- package/lib/server/server.js +48 -35
- package/lib/stages/postgen/postgen.js +41 -1
- package/lib/stages/postgen/ruleEngine.js +13 -5
- package/lib/stages/postgen/specVersionCompat.js +76 -0
- package/lib/stages/pregen/envAudit.js +1 -0
- package/lib/stages/pregen/pregen.js +114 -57
- package/lib/validator/bomValidator.js +14 -2
- package/lib/validator/complianceEngine.js +30 -3
- package/lib/validator/complianceRules.js +1416 -4
- package/lib/validator/generated/validate-1.6.mjs +1 -1
- package/lib/validator/generated/validate-1.7.mjs +1 -1
- package/lib/validator/generated/validate-2.0.mjs +57554 -13851
- package/lib/validator/index.js +49 -8
- package/lib/validator/reporters/json.js +6 -0
- package/package.json +11 -10
- package/types/bin/repl.d.ts.map +1 -1
- package/types/lib/audit/index.d.ts +6 -2
- package/types/lib/audit/index.d.ts.map +1 -1
- package/types/lib/cli/bomAssembly.d.ts +29 -1
- package/types/lib/cli/bomAssembly.d.ts.map +1 -1
- package/types/lib/cli/cliOptions.d.ts +6 -0
- package/types/lib/cli/cliOptions.d.ts.map +1 -1
- package/types/lib/cli/index.d.ts.map +1 -1
- package/types/lib/cli/jsBom.d.ts +3 -18
- package/types/lib/cli/jsBom.d.ts.map +1 -1
- package/types/lib/cli/jvmBom.d.ts +15 -0
- package/types/lib/cli/jvmBom.d.ts.map +1 -1
- package/types/lib/cli/managedBom.d.ts.map +1 -1
- package/types/lib/cli/nativeBom.d.ts.map +1 -1
- package/types/lib/core/boundedFile.d.ts +100 -0
- package/types/lib/core/boundedFile.d.ts.map +1 -0
- package/types/lib/core/brotliProbe.d.ts +37 -0
- package/types/lib/core/brotliProbe.d.ts.map +1 -0
- package/types/lib/core/env.d.ts +14 -0
- package/types/lib/core/env.d.ts.map +1 -1
- package/types/lib/core/fs.d.ts +4 -0
- package/types/lib/core/fs.d.ts.map +1 -1
- package/types/lib/core/globPatterns.d.ts +70 -0
- package/types/lib/core/globPatterns.d.ts.map +1 -0
- package/types/lib/core/httpClient.d.ts +24 -0
- package/types/lib/core/httpClient.d.ts.map +1 -1
- package/types/lib/core/lockPaths.d.ts +19 -0
- package/types/lib/core/lockPaths.d.ts.map +1 -0
- package/types/lib/core/paths.d.ts +9 -0
- package/types/lib/core/paths.d.ts.map +1 -1
- package/types/lib/core/processTree.d.ts +17 -4
- package/types/lib/core/processTree.d.ts.map +1 -1
- package/types/lib/core/projectConfig.d.ts +47 -8
- package/types/lib/core/projectConfig.d.ts.map +1 -1
- package/types/lib/core/toolRegistry.d.ts +36 -0
- package/types/lib/core/toolRegistry.d.ts.map +1 -0
- package/types/lib/ecosystems/cppEvidence.d.ts +40 -13
- package/types/lib/ecosystems/cppEvidence.d.ts.map +1 -1
- package/types/lib/ecosystems/cppIncludeResolver.d.ts +2 -1
- package/types/lib/ecosystems/cppIncludeResolver.d.ts.map +1 -1
- package/types/lib/ecosystems/ecosystems.d.ts.map +1 -1
- package/types/lib/ecosystems/gemHostProbe.d.ts +28 -0
- package/types/lib/ecosystems/gemHostProbe.d.ts.map +1 -0
- package/types/lib/ecosystems/golem.d.ts.map +1 -1
- package/types/lib/ecosystems/gradleutils.d.ts +294 -20
- package/types/lib/ecosystems/gradleutils.d.ts.map +1 -1
- package/types/lib/ecosystems/jsEvidence.d.ts +14 -1
- package/types/lib/ecosystems/jsEvidence.d.ts.map +1 -1
- package/types/lib/ecosystems/kosi.d.ts.map +1 -1
- package/types/lib/ecosystems/npmVersionResolution.d.ts +119 -0
- package/types/lib/ecosystems/npmVersionResolution.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-bazel.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-js.d.ts +17 -20
- package/types/lib/ecosystems/parsers-js.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-misc.d.ts +19 -0
- package/types/lib/ecosystems/parsers-misc.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-python.d.ts +10 -0
- package/types/lib/ecosystems/parsers-python.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-rust.d.ts.map +1 -1
- package/types/lib/ecosystems/pythonutils.d.ts +19 -1
- package/types/lib/ecosystems/pythonutils.d.ts.map +1 -1
- package/types/lib/ecosystems/remote/huggingface.d.ts.map +1 -1
- package/types/lib/ecosystems/rubyutils.d.ts +144 -12
- package/types/lib/ecosystems/rubyutils.d.ts.map +1 -1
- package/types/lib/ecosystems/rusi.d.ts.map +1 -1
- package/types/lib/ecosystems/scalacliutils.d.ts.map +1 -1
- package/types/lib/ecosystems/scalasem.d.ts +58 -16
- package/types/lib/ecosystems/scalasem.d.ts.map +1 -1
- package/types/lib/ecosystems/vendoredCode.d.ts +26 -0
- package/types/lib/ecosystems/vendoredCode.d.ts.map +1 -1
- package/types/lib/ecosystems/venvProbe.d.ts +40 -0
- package/types/lib/ecosystems/venvProbe.d.ts.map +1 -0
- package/types/lib/evinser/evinser.d.ts +120 -13
- package/types/lib/evinser/evinser.d.ts.map +1 -1
- package/types/lib/evinser/scalasem.d.ts.map +1 -1
- package/types/lib/helpers/agenticToolutils.d.ts +53 -19
- package/types/lib/helpers/agenticToolutils.d.ts.map +1 -1
- package/types/lib/helpers/bomSigner.d.ts +20 -3
- package/types/lib/helpers/bomSigner.d.ts.map +1 -1
- package/types/lib/helpers/jssSigner.d.ts +288 -0
- package/types/lib/helpers/jssSigner.d.ts.map +1 -0
- package/types/lib/helpers/vsixutils.d.ts +303 -19
- package/types/lib/helpers/vsixutils.d.ts.map +1 -1
- package/types/lib/inventory/agentBlueprint.d.ts +70 -0
- package/types/lib/inventory/agentBlueprint.d.ts.map +1 -0
- package/types/lib/inventory/agentToolNames.d.ts +51 -0
- package/types/lib/inventory/agentToolNames.d.ts.map +1 -0
- package/types/lib/inventory/aiCollector.d.ts.map +1 -1
- package/types/lib/inventory/aiInventory.d.ts.map +1 -1
- package/types/lib/inventory/aiProviders.d.ts +85 -0
- package/types/lib/inventory/aiProviders.d.ts.map +1 -0
- package/types/lib/inventory/atomUtils.d.ts +19 -0
- package/types/lib/inventory/atomUtils.d.ts.map +1 -1
- package/types/lib/inventory/bomUtils.d.ts.map +1 -1
- package/types/lib/inventory/brotliDecoder.d.ts +58 -0
- package/types/lib/inventory/brotliDecoder.d.ts.map +1 -0
- package/types/lib/inventory/cbomutils.d.ts +17 -0
- package/types/lib/inventory/cbomutils.d.ts.map +1 -1
- package/types/lib/inventory/ciParsers/githubActionsLock.d.ts +101 -0
- package/types/lib/inventory/ciParsers/githubActionsLock.d.ts.map +1 -0
- package/types/lib/inventory/citations.d.ts +5 -0
- package/types/lib/inventory/citations.d.ts.map +1 -1
- package/types/lib/inventory/communityAiConfigParser.d.ts.map +1 -1
- package/types/lib/inventory/cyclonedx20.d.ts +99 -0
- package/types/lib/inventory/cyclonedx20.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20Common.d.ts +102 -0
- package/types/lib/inventory/cyclonedx20Common.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20Derived.d.ts +74 -0
- package/types/lib/inventory/cyclonedx20Derived.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20Parties.d.ts +91 -0
- package/types/lib/inventory/cyclonedx20Parties.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20Read.d.ts +51 -0
- package/types/lib/inventory/cyclonedx20Read.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20ReadCommon.d.ts +69 -0
- package/types/lib/inventory/cyclonedx20ReadCommon.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20ReadComponents.d.ts +77 -0
- package/types/lib/inventory/cyclonedx20ReadComponents.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20ReadContext.d.ts +118 -0
- package/types/lib/inventory/cyclonedx20ReadContext.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20ReadEvidence.d.ts +40 -0
- package/types/lib/inventory/cyclonedx20ReadEvidence.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20ReadSections.d.ts +45 -0
- package/types/lib/inventory/cyclonedx20ReadSections.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20Render.d.ts +53 -0
- package/types/lib/inventory/cyclonedx20Render.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20RenderComponents.d.ts +73 -0
- package/types/lib/inventory/cyclonedx20RenderComponents.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20RenderDefinitions.d.ts +29 -0
- package/types/lib/inventory/cyclonedx20RenderDefinitions.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20RenderEvidence.d.ts +110 -0
- package/types/lib/inventory/cyclonedx20RenderEvidence.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20RenderHardware.d.ts +42 -0
- package/types/lib/inventory/cyclonedx20RenderHardware.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20RenderPatents.d.ts +26 -0
- package/types/lib/inventory/cyclonedx20RenderPatents.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20RenderRefIds.d.ts +55 -0
- package/types/lib/inventory/cyclonedx20RenderRefIds.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20RenderSections.d.ts +45 -0
- package/types/lib/inventory/cyclonedx20RenderSections.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20Tables.d.ts +134 -0
- package/types/lib/inventory/cyclonedx20Tables.d.ts.map +1 -0
- package/types/lib/inventory/deps.d.ts +35 -2
- package/types/lib/inventory/deps.d.ts.map +1 -1
- package/types/lib/inventory/dosai.d.ts +36 -1
- package/types/lib/inventory/dosai.d.ts.map +1 -1
- package/types/lib/inventory/dosaiParsers.d.ts.map +1 -1
- package/types/lib/inventory/dotnetRuntime.d.ts +91 -0
- package/types/lib/inventory/dotnetRuntime.d.ts.map +1 -0
- package/types/lib/inventory/ecosystemFormulationParsers.d.ts +73 -0
- package/types/lib/inventory/ecosystemFormulationParsers.d.ts.map +1 -0
- package/types/lib/inventory/envcontext.d.ts +74 -12
- package/types/lib/inventory/envcontext.d.ts.map +1 -1
- package/types/lib/inventory/evidenceUtils.d.ts.map +1 -1
- package/types/lib/inventory/formulationParsers.d.ts.map +1 -1
- package/types/lib/inventory/gtfobins.d.ts.map +1 -1
- package/types/lib/inventory/hbom.d.ts +11 -0
- package/types/lib/inventory/hbom.d.ts.map +1 -1
- package/types/lib/inventory/hbomLoader.d.ts +54 -0
- package/types/lib/inventory/hbomLoader.d.ts.map +1 -1
- package/types/lib/inventory/hostRuntimeProbe.d.ts +44 -0
- package/types/lib/inventory/hostRuntimeProbe.d.ts.map +1 -0
- package/types/lib/inventory/jvmLocalRepos.d.ts +5 -1
- package/types/lib/inventory/jvmLocalRepos.d.ts.map +1 -1
- package/types/lib/inventory/jvmToolEnv.d.ts +12 -0
- package/types/lib/inventory/jvmToolEnv.d.ts.map +1 -1
- package/types/lib/inventory/licenseEnhancer.d.ts.map +1 -1
- package/types/lib/inventory/mavenCentralMirror.d.ts +170 -0
- package/types/lib/inventory/mavenCentralMirror.d.ts.map +1 -0
- package/types/lib/inventory/mcpConfigParser.d.ts.map +1 -1
- package/types/lib/inventory/nodeBuildInfo.d.ts +95 -0
- package/types/lib/inventory/nodeBuildInfo.d.ts.map +1 -0
- package/types/lib/inventory/nodeHostProbe.d.ts +15 -0
- package/types/lib/inventory/nodeHostProbe.d.ts.map +1 -0
- package/types/lib/inventory/occurrenceKey.d.ts +52 -0
- package/types/lib/inventory/occurrenceKey.d.ts.map +1 -0
- package/types/lib/inventory/osPackageResolver.d.ts +38 -0
- package/types/lib/inventory/osPackageResolver.d.ts.map +1 -1
- package/types/lib/inventory/phpBuildInfo.d.ts.map +1 -1
- package/types/lib/inventory/phpHostProbe.d.ts.map +1 -1
- package/types/lib/inventory/pqcMigration.d.ts +84 -0
- package/types/lib/inventory/pqcMigration.d.ts.map +1 -0
- package/types/lib/inventory/rubyBuildInfo.d.ts +271 -0
- package/types/lib/inventory/rubyBuildInfo.d.ts.map +1 -0
- package/types/lib/inventory/rubyHostProbe.d.ts +47 -0
- package/types/lib/inventory/rubyHostProbe.d.ts.map +1 -0
- package/types/lib/inventory/rustFormulationParser.d.ts +7 -2
- package/types/lib/inventory/rustFormulationParser.d.ts.map +1 -1
- package/types/lib/inventory/scalaCoords.d.ts.map +1 -1
- package/types/lib/inventory/scalaDedupe.d.ts +43 -0
- package/types/lib/inventory/scalaDedupe.d.ts.map +1 -0
- package/types/lib/inventory/source.d.ts +25 -0
- package/types/lib/inventory/source.d.ts.map +1 -1
- package/types/lib/managers/binary.d.ts.map +1 -1
- package/types/lib/managers/docker.d.ts +12 -0
- package/types/lib/managers/docker.d.ts.map +1 -1
- package/types/lib/parsers/huggingfaceManifest.d.ts +10 -1
- package/types/lib/parsers/huggingfaceManifest.d.ts.map +1 -1
- package/types/lib/parsers/huggingfaceUtils.d.ts +12 -0
- package/types/lib/parsers/huggingfaceUtils.d.ts.map +1 -1
- package/types/lib/parsers/kiroPermissions.d.ts +62 -0
- package/types/lib/parsers/kiroPermissions.d.ts.map +1 -0
- package/types/lib/parsers/largeJson.d.ts +4 -3
- package/types/lib/parsers/largeJson.d.ts.map +1 -1
- package/types/lib/parsers/vscodeExtensionId.d.ts +48 -0
- package/types/lib/parsers/vscodeExtensionId.d.ts.map +1 -0
- package/types/lib/server/server.d.ts.map +1 -1
- package/types/lib/stages/postgen/postgen.d.ts +7 -0
- 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/postgen/specVersionCompat.d.ts +25 -0
- package/types/lib/stages/postgen/specVersionCompat.d.ts.map +1 -1
- package/types/lib/stages/pregen/envAudit.d.ts.map +1 -1
- package/types/lib/stages/pregen/pregen.d.ts +12 -8
- package/types/lib/stages/pregen/pregen.d.ts.map +1 -1
- package/types/lib/validator/bomValidator.d.ts +5 -1
- package/types/lib/validator/bomValidator.d.ts.map +1 -1
- package/types/lib/validator/complianceEngine.d.ts +4 -4
- package/types/lib/validator/complianceEngine.d.ts.map +1 -1
- package/types/lib/validator/complianceRules.d.ts +14 -2
- package/types/lib/validator/complianceRules.d.ts.map +1 -1
- package/types/lib/validator/index.d.ts +10 -0
- package/types/lib/validator/index.d.ts.map +1 -1
- package/types/lib/validator/reporters/json.d.ts.map +1 -1
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Declared coding-agent behaviour at CycloneDX 2.0 (cdxgen/cdxgen#4593).
|
|
3
|
+
*
|
|
4
|
+
* The source is the AI inventory the 1.x parsers already produce
|
|
5
|
+
* (communityAiConfigParser: Kiro agents, Claude subagents and agent
|
|
6
|
+
* definitions). Only real agent definitions count: a component with a
|
|
7
|
+
* `cdx:agent:role`, or whose `cdx:file:kind` is `agent-definition` or
|
|
8
|
+
* `claude-subagent`. Instruction files, specs, steering documents, agent
|
|
9
|
+
* configs and plugins describe or configure agents but are not agents.
|
|
10
|
+
* At 2.0 this module derives:
|
|
11
|
+
*
|
|
12
|
+
* - one party per agent component with a bom-ref
|
|
13
|
+
* (#/$defs/cyclonedx-party-2.0/$defs/party, role `agent`) whose `system`
|
|
14
|
+
* (#/$defs/cyclonedx-party-2.0/$defs/system) has kind `agent`, `ref` the
|
|
15
|
+
* agent component's refId, `label` its name and `permissions` the tool
|
|
16
|
+
* names its config allows. The allow list is split on the commas outside
|
|
17
|
+
* parentheses, and each entry is reduced to the tool name before any "("
|
|
18
|
+
* (`Bash(git status:*)` is `Bash`), so arguments, paths and commands
|
|
19
|
+
* never reach the BOM. Names that are not safe tool names are dropped
|
|
20
|
+
* (see lib/inventory/agentToolNames.js). The list is unique and sorted.
|
|
21
|
+
*
|
|
22
|
+
* - one blueprint (#/$defs/cyclonedx-blueprint-2.0/$defs/blueprint,
|
|
23
|
+
* modelTypes `behavioral`) whose actors reference the agent parties and
|
|
24
|
+
* whose behaviors.instances carry `acknowledgment: ["declared"]` and a
|
|
25
|
+
* `behavior` from data/behavior-taxonomy.schema.json:
|
|
26
|
+
* `ai:agent:invokesTool` when the agent declares tools or MCP servers, and
|
|
27
|
+
* `ai:agent:requestsUserApproval` when its permission policy has ask rules.
|
|
28
|
+
* The inventory records only how many MCP servers an agent's own config
|
|
29
|
+
* names, not which, so instances carry no `targets`: naming the project's
|
|
30
|
+
* MCP services would claim a binding no config makes.
|
|
31
|
+
*
|
|
32
|
+
* No free text from instruction, skill or MCP files is emitted. Business
|
|
33
|
+
* objectives and use cases are free text, so they are out of scope, and so
|
|
34
|
+
* is observed behaviour.
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
import { readFileSync } from "node:fs";
|
|
38
|
+
import { join } from "node:path";
|
|
39
|
+
|
|
40
|
+
import { dirNameStr } from "../core/paths.js";
|
|
41
|
+
import { agentToolName, splitAllowList } from "./agentToolNames.js";
|
|
42
|
+
|
|
43
|
+
/** refId of the derived blueprint. */
|
|
44
|
+
export const AGENT_BLUEPRINT_REF_ID = "blueprint-declared-agents";
|
|
45
|
+
/** Prefix of every derived agent party refId. */
|
|
46
|
+
export const AGENT_PARTY_REF_ID_PREFIX = "party-agent-";
|
|
47
|
+
|
|
48
|
+
const AGENT_ROLE_PROPERTY = "cdx:agent:role";
|
|
49
|
+
const AGENT_DEFINITION_FILE_KINDS = new Set([
|
|
50
|
+
"agent-definition",
|
|
51
|
+
"claude-subagent",
|
|
52
|
+
]);
|
|
53
|
+
const BEHAVIOR_TAXONOMY = new Set(
|
|
54
|
+
JSON.parse(
|
|
55
|
+
readFileSync(
|
|
56
|
+
join(dirNameStr, "data", "behavior-taxonomy.schema.json"),
|
|
57
|
+
"utf-8",
|
|
58
|
+
),
|
|
59
|
+
).enum,
|
|
60
|
+
);
|
|
61
|
+
const propertyValue = (subject, name) =>
|
|
62
|
+
(subject?.properties || []).find((entry) => entry?.name === name)?.value;
|
|
63
|
+
|
|
64
|
+
const propertyCount = (subject, name) => {
|
|
65
|
+
const parsed = Number(propertyValue(subject, name));
|
|
66
|
+
return Number.isFinite(parsed) ? parsed : 0;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Is this internal-model component a real coding-agent definition?
|
|
71
|
+
*
|
|
72
|
+
* @param {object} component Internal-model component
|
|
73
|
+
* @returns {boolean} True for a `cdx:agent:role` component or an
|
|
74
|
+
* agent-definition / claude-subagent file
|
|
75
|
+
*/
|
|
76
|
+
export function isDeclaredAgentComponent(component) {
|
|
77
|
+
if (
|
|
78
|
+
(component?.properties || []).some(
|
|
79
|
+
(entry) => entry?.name === AGENT_ROLE_PROPERTY,
|
|
80
|
+
)
|
|
81
|
+
) {
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
return AGENT_DEFINITION_FILE_KINDS.has(
|
|
85
|
+
propertyValue(component, "cdx:file:kind"),
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* The permissions of an agent: the tool names of `cdx:agent:tools` and the
|
|
91
|
+
* scopes of `cdx:agent:permissionCapabilities`, each reduced to the name
|
|
92
|
+
* before any "(", unique and sorted.
|
|
93
|
+
*
|
|
94
|
+
* @param {object} component Internal-model agent component
|
|
95
|
+
* @returns {string[]} Permission names
|
|
96
|
+
*/
|
|
97
|
+
export function declaredAgentPermissions(component) {
|
|
98
|
+
const names = [
|
|
99
|
+
...splitAllowList(propertyValue(component, "cdx:agent:tools")),
|
|
100
|
+
...splitAllowList(
|
|
101
|
+
propertyValue(component, "cdx:agent:permissionCapabilities"),
|
|
102
|
+
),
|
|
103
|
+
]
|
|
104
|
+
.map(agentToolName)
|
|
105
|
+
.filter(Boolean);
|
|
106
|
+
return [...new Set(names)].sort();
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function agentInstances(agent, partyRefId) {
|
|
110
|
+
const instances = [];
|
|
111
|
+
const declaresTools =
|
|
112
|
+
propertyCount(agent, "cdx:agent:toolCount") > 0 ||
|
|
113
|
+
splitAllowList(propertyValue(agent, "cdx:agent:tools")).length > 0 ||
|
|
114
|
+
propertyCount(agent, "cdx:agent:mcpServerCount") > 0;
|
|
115
|
+
if (declaresTools) {
|
|
116
|
+
instances.push({
|
|
117
|
+
refId: `behavior-${partyRefId}-invokes-tool`,
|
|
118
|
+
acknowledgment: ["declared"],
|
|
119
|
+
behavior: "ai:agent:invokesTool",
|
|
120
|
+
actors: [partyRefId],
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
if (propertyCount(agent, "cdx:agent:permissionAskRuleCount") > 0) {
|
|
124
|
+
instances.push({
|
|
125
|
+
refId: `behavior-${partyRefId}-requests-approval`,
|
|
126
|
+
acknowledgment: ["declared"],
|
|
127
|
+
behavior: "ai:agent:requestsUserApproval",
|
|
128
|
+
actors: [partyRefId],
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
return instances.filter((instance) =>
|
|
132
|
+
BEHAVIOR_TAXONOMY.has(instance.behavior),
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function agentParty(agent, partyRefId) {
|
|
137
|
+
const system = { kind: "agent", ref: agent["bom-ref"] };
|
|
138
|
+
if (typeof agent.name === "string" && agent.name.length) {
|
|
139
|
+
system.label = agent.name;
|
|
140
|
+
}
|
|
141
|
+
const permissions = declaredAgentPermissions(agent);
|
|
142
|
+
if (permissions.length) {
|
|
143
|
+
system.permissions = permissions;
|
|
144
|
+
}
|
|
145
|
+
return { refId: partyRefId, roles: [{ role: "agent" }], system };
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Collect the 2.0 agent parties and the behavioral blueprint for the
|
|
150
|
+
* declared agents of an internal-model BOM. Agents without a bom-ref are
|
|
151
|
+
* skipped (their party could not point at them); parties are unique by
|
|
152
|
+
* refId.
|
|
153
|
+
*
|
|
154
|
+
* @param {object} internalBom The 1.x-shaped internal model
|
|
155
|
+
* @returns {{parties: object[], blueprint: object|undefined}}
|
|
156
|
+
*/
|
|
157
|
+
export function collectAgentBehaviour(internalBom) {
|
|
158
|
+
const parties = [];
|
|
159
|
+
const actors = [];
|
|
160
|
+
const instances = [];
|
|
161
|
+
const seen = new Set();
|
|
162
|
+
for (const agent of internalBom?.components || []) {
|
|
163
|
+
const bomRef = agent?.["bom-ref"];
|
|
164
|
+
if (
|
|
165
|
+
typeof bomRef !== "string" ||
|
|
166
|
+
!bomRef.length ||
|
|
167
|
+
!isDeclaredAgentComponent(agent)
|
|
168
|
+
) {
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
const partyRefId = `${AGENT_PARTY_REF_ID_PREFIX}${bomRef}`;
|
|
172
|
+
if (seen.has(partyRefId)) {
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
seen.add(partyRefId);
|
|
176
|
+
parties.push(agentParty(agent, partyRefId));
|
|
177
|
+
actors.push({ refId: `actor-${partyRefId}`, party: { ref: partyRefId } });
|
|
178
|
+
instances.push(...agentInstances(agent, partyRefId));
|
|
179
|
+
}
|
|
180
|
+
if (!instances.length) {
|
|
181
|
+
return { parties, blueprint: undefined };
|
|
182
|
+
}
|
|
183
|
+
return {
|
|
184
|
+
parties,
|
|
185
|
+
blueprint: {
|
|
186
|
+
refId: AGENT_BLUEPRINT_REF_ID,
|
|
187
|
+
name: "Declared coding-agent behaviour",
|
|
188
|
+
modelTypes: ["behavioral"],
|
|
189
|
+
actors,
|
|
190
|
+
behaviors: { instances },
|
|
191
|
+
},
|
|
192
|
+
};
|
|
193
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool allow lists of coding-agent configurations, reduced to tool names.
|
|
3
|
+
*
|
|
4
|
+
* An allow list such as `Read, Bash(git status:*), Bash(curl -u user,secret)`
|
|
5
|
+
* carries commands, paths and sometimes credentials inside its parentheses.
|
|
6
|
+
* Only the tool name before any "(" is kept, so nothing an entry scopes its
|
|
7
|
+
* tool to reaches a BOM. The list is split on the commas outside parentheses,
|
|
8
|
+
* so the arguments of one entry never become entries of their own.
|
|
9
|
+
*
|
|
10
|
+
* A tool name is at most 64 characters of letters, digits and `_ - . : *`
|
|
11
|
+
* (`Read`, `mcp__github__*`, `fs_write`), optionally in the `@server/tool`
|
|
12
|
+
* form Kiro uses. A name that looks like a credential (a known token prefix
|
|
13
|
+
* such as `ghp_` or `AKIA`, or a long run of letters and digits with no
|
|
14
|
+
* separator) is dropped.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
const NAME_CHARACTERS = new Set(
|
|
18
|
+
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._:*-",
|
|
19
|
+
);
|
|
20
|
+
const NAME_SEPARATORS = new Set("._:*-/@");
|
|
21
|
+
const MAX_NAME_LENGTH = 64;
|
|
22
|
+
// Prefixes of GitHub, OpenAI and Anthropic, Slack and AWS access key ids.
|
|
23
|
+
const CREDENTIAL_PREFIXES = Object.freeze([
|
|
24
|
+
"ghp_",
|
|
25
|
+
"gho_",
|
|
26
|
+
"ghu_",
|
|
27
|
+
"ghs_",
|
|
28
|
+
"ghr_",
|
|
29
|
+
"github_pat_",
|
|
30
|
+
"sk-",
|
|
31
|
+
"xoxa-",
|
|
32
|
+
"xoxb-",
|
|
33
|
+
"xoxp-",
|
|
34
|
+
"AKIA",
|
|
35
|
+
]);
|
|
36
|
+
// A tool name is a word or words joined by separators; a longer unbroken run
|
|
37
|
+
// of letters and digits that mixes both is treated as a token.
|
|
38
|
+
const MAX_UNSEPARATED_TOKEN_LENGTH = 24;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Split an allow list on the commas outside parentheses. An array is taken
|
|
42
|
+
* as already split.
|
|
43
|
+
*
|
|
44
|
+
* @param {string|string[]|undefined} value Allow list
|
|
45
|
+
* @returns {string[]} Trimmed, non-empty entries
|
|
46
|
+
*/
|
|
47
|
+
export function splitAllowList(value) {
|
|
48
|
+
if (Array.isArray(value)) {
|
|
49
|
+
return value
|
|
50
|
+
.filter((entry) => typeof entry === "string")
|
|
51
|
+
.flatMap((entry) => splitAllowList(entry));
|
|
52
|
+
}
|
|
53
|
+
const entries = [];
|
|
54
|
+
let depth = 0;
|
|
55
|
+
let current = "";
|
|
56
|
+
for (const ch of `${value ?? ""}`) {
|
|
57
|
+
if (ch === "(") {
|
|
58
|
+
depth++;
|
|
59
|
+
} else if (ch === ")" && depth > 0) {
|
|
60
|
+
depth--;
|
|
61
|
+
} else if (ch === "," && depth === 0) {
|
|
62
|
+
entries.push(current);
|
|
63
|
+
current = "";
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
current += ch;
|
|
67
|
+
}
|
|
68
|
+
entries.push(current);
|
|
69
|
+
return entries.map((entry) => entry.trim()).filter(Boolean);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function looksLikeCredential(name) {
|
|
73
|
+
if (CREDENTIAL_PREFIXES.some((prefix) => name.startsWith(prefix))) {
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
const chars = [...name];
|
|
77
|
+
return (
|
|
78
|
+
name.length >= MAX_UNSEPARATED_TOKEN_LENGTH &&
|
|
79
|
+
!chars.some((ch) => NAME_SEPARATORS.has(ch)) &&
|
|
80
|
+
chars.some((ch) => ch >= "0" && ch <= "9") &&
|
|
81
|
+
chars.some((ch) => ch.toLowerCase() !== ch.toUpperCase())
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function isNamePart(part) {
|
|
86
|
+
return part.length > 0 && [...part].every((ch) => NAME_CHARACTERS.has(ch));
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* The tool name of one allow-list entry, or undefined when it is not a safe
|
|
91
|
+
* tool name.
|
|
92
|
+
*
|
|
93
|
+
* @param {string} entry Allow-list entry
|
|
94
|
+
* @returns {string|undefined} Tool name
|
|
95
|
+
*/
|
|
96
|
+
export function agentToolName(entry) {
|
|
97
|
+
const text = `${entry ?? ""}`;
|
|
98
|
+
const parenthesis = text.indexOf("(");
|
|
99
|
+
const name = (parenthesis >= 0 ? text.slice(0, parenthesis) : text).trim();
|
|
100
|
+
if (!name.length || name.length > MAX_NAME_LENGTH) {
|
|
101
|
+
return undefined;
|
|
102
|
+
}
|
|
103
|
+
const scoped = name.startsWith("@") ? name.slice(1).split("/") : [name];
|
|
104
|
+
const shapeOk = name.startsWith("@")
|
|
105
|
+
? scoped.length === 2 && scoped.every(isNamePart)
|
|
106
|
+
: isNamePart(name);
|
|
107
|
+
if (!shapeOk || looksLikeCredential(name)) {
|
|
108
|
+
return undefined;
|
|
109
|
+
}
|
|
110
|
+
return name;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* The unique, sorted tool names of an allow list.
|
|
115
|
+
*
|
|
116
|
+
* @param {string|string[]|undefined} value Allow list
|
|
117
|
+
* @returns {string[]} Tool names
|
|
118
|
+
*/
|
|
119
|
+
export function agentToolNames(value) {
|
|
120
|
+
return [
|
|
121
|
+
...new Set(splitAllowList(value).map(agentToolName).filter(Boolean)),
|
|
122
|
+
].sort();
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* An allow list as cdxgen records it in `cdx:agent:tools` and
|
|
127
|
+
* `cdx:agent:disallowedTools`: each entry reduced to its tool name, written
|
|
128
|
+
* `Name(...)` when the entry scoped the tool with arguments, so a scoped
|
|
129
|
+
* `Bash(git status:*)` stays distinguishable from an unrestricted `Bash`
|
|
130
|
+
* without copying the scope. Unique, in the order the config lists them,
|
|
131
|
+
* comma separated.
|
|
132
|
+
*
|
|
133
|
+
* @param {string|string[]|undefined} value Allow list
|
|
134
|
+
* @returns {string|undefined} Summary, or undefined when nothing is left
|
|
135
|
+
*/
|
|
136
|
+
export function summarizeAgentToolList(value) {
|
|
137
|
+
const summary = new Set();
|
|
138
|
+
for (const entry of splitAllowList(value)) {
|
|
139
|
+
const name = agentToolName(entry);
|
|
140
|
+
if (name) {
|
|
141
|
+
summary.add(entry.includes("(") ? `${name}(...)` : name);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return summary.size ? [...summary].join(",") : undefined;
|
|
145
|
+
}
|
|
@@ -29,6 +29,7 @@ import {
|
|
|
29
29
|
repositoryUrlForHuggingFaceAssetType,
|
|
30
30
|
toHuggingFaceAssetUrl,
|
|
31
31
|
toHuggingFacePurl,
|
|
32
|
+
toHuggingFaceSupplier,
|
|
32
33
|
} from "../parsers/huggingfaceUtils.js";
|
|
33
34
|
import { parseOllamaModelfile } from "../parsers/ollama.js";
|
|
34
35
|
import { readOnnxHeader } from "../parsers/onnx.js";
|
|
@@ -37,6 +38,12 @@ import {
|
|
|
37
38
|
detectAiModelVariants,
|
|
38
39
|
normalizeDetectedVariants,
|
|
39
40
|
} from "./aiModelVariants.js";
|
|
41
|
+
import {
|
|
42
|
+
modelCreatorEntity,
|
|
43
|
+
modelCreatorFromOrganization,
|
|
44
|
+
resolveModelCreator,
|
|
45
|
+
splitModelReference,
|
|
46
|
+
} from "./aiProviders.js";
|
|
40
47
|
import { getLicenses } from "./spdx.js";
|
|
41
48
|
|
|
42
49
|
// -----------------------------------------------------------------------------
|
|
@@ -98,7 +105,8 @@ const IGNORE_SOURCE_FILE_PATTERN =
|
|
|
98
105
|
const HOST_PROVIDER_PATTERNS = [
|
|
99
106
|
["openai", /(?:^|\.)openai\.com$/iu],
|
|
100
107
|
["anthropic", /(?:^|\.)anthropic\.com$/iu],
|
|
101
|
-
|
|
108
|
+
// Only the Gemini API host. Other googleapis.com hosts serve Cloud Storage,
|
|
109
|
+
// Vertex AI (matched below) and unrelated Google APIs.
|
|
102
110
|
["google", /(?:^|\.)generativelanguage\.googleapis\.com$/iu],
|
|
103
111
|
["azure-openai", /(?:^|\.)openai\.azure\.com$/iu],
|
|
104
112
|
["huggingface", /(?:^|\.)huggingface\.co$/iu],
|
|
@@ -110,7 +118,9 @@ const HOST_PROVIDER_PATTERNS = [
|
|
|
110
118
|
["together", /(?:^|\.)together\.xyz$/iu],
|
|
111
119
|
["replicate", /(?:^|\.)replicate\.com$/iu],
|
|
112
120
|
["perplexity", /(?:^|\.)perplexity\.ai$/iu],
|
|
113
|
-
|
|
121
|
+
// Regional Vertex AI endpoints join the region with a hyphen, as in
|
|
122
|
+
// us-central1-aiplatform.googleapis.com.
|
|
123
|
+
["vertex-ai", /(?:^|[.-])aiplatform\.googleapis\.com$/iu],
|
|
114
124
|
["xai", /(?:^|\.)x\.ai$/iu],
|
|
115
125
|
[
|
|
116
126
|
"aws-bedrock",
|
|
@@ -1326,9 +1336,62 @@ const createAiFileComponent = (
|
|
|
1326
1336
|
return componentsByKey.get(key);
|
|
1327
1337
|
};
|
|
1328
1338
|
|
|
1339
|
+
// Longest producer name a model file may declare about itself.
|
|
1340
|
+
const MAX_DECLARED_PRODUCER_LENGTH = 128;
|
|
1341
|
+
|
|
1342
|
+
/**
|
|
1343
|
+
* Trim and bound a producer name a model file declares about itself, such as
|
|
1344
|
+
* the GGUF general.organization field. The value is file-controlled free text.
|
|
1345
|
+
*
|
|
1346
|
+
* @param {unknown} value Declared producer
|
|
1347
|
+
* @returns {string|undefined} Usable producer name
|
|
1348
|
+
*/
|
|
1349
|
+
const declaredProducerName = (value) => {
|
|
1350
|
+
if (typeof value !== "string") {
|
|
1351
|
+
return undefined;
|
|
1352
|
+
}
|
|
1353
|
+
const name = value.trim();
|
|
1354
|
+
if (!name || name.length > MAX_DECLARED_PRODUCER_LENGTH) {
|
|
1355
|
+
return undefined;
|
|
1356
|
+
}
|
|
1357
|
+
return name;
|
|
1358
|
+
};
|
|
1359
|
+
|
|
1360
|
+
/**
|
|
1361
|
+
* Build the manufacturer of a model, the organisation that created it.
|
|
1362
|
+
*
|
|
1363
|
+
* A producer the model file declares about itself wins, written with the
|
|
1364
|
+
* creator's full name when it is a known creator and as declared otherwise.
|
|
1365
|
+
* A Hub repository credits its namespace only when the namespace is the
|
|
1366
|
+
* creator's own organisation (meta-llama, mistralai, Qwen), because
|
|
1367
|
+
* re-packagers such as TheBloke, unsloth or mlx-community publish models
|
|
1368
|
+
* other organisations made. A model that source code calls by name uses the
|
|
1369
|
+
* creator id the caller resolved.
|
|
1370
|
+
*
|
|
1371
|
+
* @param {{ hubNamespace?: string, modelCreator?: string, producer?: unknown }} sources
|
|
1372
|
+
* Creator evidence for the model
|
|
1373
|
+
* @returns {{ name: string }|undefined} Manufacturer entity
|
|
1374
|
+
*/
|
|
1375
|
+
const modelManufacturer = ({ hubNamespace, modelCreator, producer }) => {
|
|
1376
|
+
const declared = declaredProducerName(producer);
|
|
1377
|
+
if (declared) {
|
|
1378
|
+
return (
|
|
1379
|
+
modelCreatorEntity(modelCreatorFromOrganization(declared)) || {
|
|
1380
|
+
name: declared,
|
|
1381
|
+
}
|
|
1382
|
+
);
|
|
1383
|
+
}
|
|
1384
|
+
if (hubNamespace) {
|
|
1385
|
+
return modelCreatorEntity(modelCreatorFromOrganization(hubNamespace));
|
|
1386
|
+
}
|
|
1387
|
+
return modelCreatorEntity(modelCreator);
|
|
1388
|
+
};
|
|
1389
|
+
|
|
1329
1390
|
const normalizeComponentIdentity = ({
|
|
1330
1391
|
assetType,
|
|
1392
|
+
modelCreator,
|
|
1331
1393
|
modelId,
|
|
1394
|
+
producer,
|
|
1332
1395
|
provider,
|
|
1333
1396
|
version,
|
|
1334
1397
|
}) => {
|
|
@@ -1343,7 +1406,14 @@ const normalizeComponentIdentity = ({
|
|
|
1343
1406
|
: normalizedAssetType === "space"
|
|
1344
1407
|
? `spaces/${normalizedModelId.replace(/^spaces\//u, "")}`
|
|
1345
1408
|
: normalizedModelId;
|
|
1346
|
-
|
|
1409
|
+
// A litellm route such as groq/llama3-8b or a Google resource name such as
|
|
1410
|
+
// models/gemini-1.5-flash has the shape of a Hub repository id but is not
|
|
1411
|
+
// one, so its first segment is never taken as a Hub namespace.
|
|
1412
|
+
const repoId =
|
|
1413
|
+
normalizedAssetType === "model" &&
|
|
1414
|
+
splitModelReference(normalizedModelId).nonHub
|
|
1415
|
+
? undefined
|
|
1416
|
+
: normalizeHuggingFaceReference(typedModelId);
|
|
1347
1417
|
if (
|
|
1348
1418
|
repoId?.assetType === normalizedAssetType &&
|
|
1349
1419
|
repoId?.repoId?.includes("/")
|
|
@@ -1354,11 +1424,24 @@ const normalizeComponentIdentity = ({
|
|
|
1354
1424
|
repoId.version || version,
|
|
1355
1425
|
repositoryUrlForHuggingFaceAssetType(normalizedAssetType),
|
|
1356
1426
|
);
|
|
1427
|
+
// The Hub namespace is the account that published the repository, so it
|
|
1428
|
+
// is the supplier. Its Hub page is the supplier url only when the model
|
|
1429
|
+
// came from the Hub; a routed id such as meta-llama/Llama-3-70b on
|
|
1430
|
+
// together keeps the name.
|
|
1431
|
+
const hubSupplier = toHuggingFaceSupplier(group);
|
|
1357
1432
|
return {
|
|
1358
1433
|
bomRef: purl,
|
|
1359
1434
|
group,
|
|
1435
|
+
manufacturer:
|
|
1436
|
+
normalizedAssetType === "model"
|
|
1437
|
+
? modelManufacturer({ hubNamespace: group, producer })
|
|
1438
|
+
: undefined,
|
|
1360
1439
|
name,
|
|
1361
1440
|
purl,
|
|
1441
|
+
supplier:
|
|
1442
|
+
hubSupplier && normalizedProvider.toLowerCase() !== "huggingface"
|
|
1443
|
+
? { name: hubSupplier.name }
|
|
1444
|
+
: hubSupplier,
|
|
1362
1445
|
};
|
|
1363
1446
|
}
|
|
1364
1447
|
return {
|
|
@@ -1368,6 +1451,12 @@ const normalizeComponentIdentity = ({
|
|
|
1368
1451
|
normalizedModelId,
|
|
1369
1452
|
),
|
|
1370
1453
|
group: normalizedProvider,
|
|
1454
|
+
// Hosting, routing and local providers stay in group and
|
|
1455
|
+
// cdx:ai:provider; only the creator is the manufacturer.
|
|
1456
|
+
manufacturer:
|
|
1457
|
+
normalizedAssetType === "model"
|
|
1458
|
+
? modelManufacturer({ modelCreator, producer })
|
|
1459
|
+
: undefined,
|
|
1371
1460
|
name: normalizedModelId,
|
|
1372
1461
|
};
|
|
1373
1462
|
};
|
|
@@ -1390,6 +1479,11 @@ const ensureModelComponent = (componentsByKey, key, seed) => {
|
|
|
1390
1479
|
description: seed.description,
|
|
1391
1480
|
version: seed.version,
|
|
1392
1481
|
licenses: seed.licenses,
|
|
1482
|
+
// The organisation that created the model is the manufacturer. The
|
|
1483
|
+
// Hugging Face namespace that published the repository is the
|
|
1484
|
+
// supplier.
|
|
1485
|
+
manufacturer: identity.manufacturer,
|
|
1486
|
+
supplier: identity.supplier,
|
|
1393
1487
|
externalReferences: seed.externalReferences || [],
|
|
1394
1488
|
evidence: { occurrences: [] },
|
|
1395
1489
|
modelCard: seed.modelCard
|
|
@@ -1691,6 +1785,25 @@ const scanUrlMatches = (
|
|
|
1691
1785
|
}
|
|
1692
1786
|
};
|
|
1693
1787
|
|
|
1788
|
+
// A plausible model id: 2-160 characters with no whitespace, starting with an
|
|
1789
|
+
// alphanumeric (or the `@` of a scoped id such as Cloudflare's `@cf/...`) and
|
|
1790
|
+
// otherwise limited to name, scope, version, and registry punctuation.
|
|
1791
|
+
// Markdown prose around an inline `` `model:` `` label fails these checks, so
|
|
1792
|
+
// documentation such as "editing the `model:` field. Run `kiro-cli chat
|
|
1793
|
+
// --list-models`" does not become a model.
|
|
1794
|
+
const MODEL_ID_CHARS_PATTERN = /^@?[A-Za-z0-9][A-Za-z0-9._:/@+-]*$/u;
|
|
1795
|
+
const MODEL_ID_MIN_LENGTH = 2;
|
|
1796
|
+
const MODEL_ID_MAX_LENGTH = 160;
|
|
1797
|
+
|
|
1798
|
+
const isPlausibleModelId = (value) => {
|
|
1799
|
+
const normalized = String(value || "").trim();
|
|
1800
|
+
return (
|
|
1801
|
+
normalized.length >= MODEL_ID_MIN_LENGTH &&
|
|
1802
|
+
normalized.length <= MODEL_ID_MAX_LENGTH &&
|
|
1803
|
+
MODEL_ID_CHARS_PATTERN.test(normalized)
|
|
1804
|
+
);
|
|
1805
|
+
};
|
|
1806
|
+
|
|
1694
1807
|
const extractModelAssignments = (raw) => {
|
|
1695
1808
|
const values = [];
|
|
1696
1809
|
const patterns = [
|
|
@@ -1708,9 +1821,10 @@ const extractModelAssignments = (raw) => {
|
|
|
1708
1821
|
}
|
|
1709
1822
|
return values.filter((entry) => {
|
|
1710
1823
|
const normalized = String(entry.value || "").trim();
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1824
|
+
if (!normalized || normalized.startsWith("http") || normalized === "auto") {
|
|
1825
|
+
return false;
|
|
1826
|
+
}
|
|
1827
|
+
return isPlausibleModelId(normalized);
|
|
1714
1828
|
});
|
|
1715
1829
|
};
|
|
1716
1830
|
|
|
@@ -1732,6 +1846,15 @@ const extractHuggingFaceReferences = (raw) => {
|
|
|
1732
1846
|
}
|
|
1733
1847
|
}
|
|
1734
1848
|
return refs
|
|
1849
|
+
.filter(
|
|
1850
|
+
(entry) =>
|
|
1851
|
+
// URL-derived references are already anchored to a real host, while
|
|
1852
|
+
// quoted `repo_id`/`model` captures suffer the same backtick-as-quote
|
|
1853
|
+
// ambiguity as model assignments, so they must look like an id too.
|
|
1854
|
+
entry.sourceUrl ||
|
|
1855
|
+
(isPlausibleModelId(entry.value) &&
|
|
1856
|
+
!splitModelReference(entry.value).nonHub),
|
|
1857
|
+
)
|
|
1735
1858
|
.map((entry) => {
|
|
1736
1859
|
const reference = normalizeHuggingFaceReference(entry.value);
|
|
1737
1860
|
return {
|
|
@@ -1770,7 +1893,16 @@ const createModelComponent = (componentsByKey, seed, occurrenceLocation) => {
|
|
|
1770
1893
|
? seed.assetType
|
|
1771
1894
|
: "model";
|
|
1772
1895
|
const key = `${normalizedAssetType}:${seed.provider || "ai"}:${seed.modelId}`;
|
|
1896
|
+
const isKnownComponent = componentsByKey.has(key);
|
|
1773
1897
|
const component = ensureModelComponent(componentsByKey, key, seed);
|
|
1898
|
+
// The same model can be seen first in a file that names no creator and
|
|
1899
|
+
// later in one that does, so a later seed fills a missing manufacturer.
|
|
1900
|
+
if (isKnownComponent && !component.manufacturer) {
|
|
1901
|
+
const { manufacturer } = normalizeComponentIdentity(seed);
|
|
1902
|
+
if (manufacturer) {
|
|
1903
|
+
component.manufacturer = manufacturer;
|
|
1904
|
+
}
|
|
1905
|
+
}
|
|
1774
1906
|
syncComponentProperties(component, {
|
|
1775
1907
|
artifactFormat: seed.artifactFormat,
|
|
1776
1908
|
confidence: seed.confidence,
|
|
@@ -1900,14 +2032,25 @@ const collectTextAiInventory = (discoveryPath, options = {}, config = {}) => {
|
|
|
1900
2032
|
}
|
|
1901
2033
|
for (const match of extractModelAssignments(raw)) {
|
|
1902
2034
|
const modelId = String(match.value || "").trim();
|
|
2035
|
+
// Only a provider the file declares through an SDK import or AI host
|
|
2036
|
+
// may agree with the creator. The fallback guessed from the model name
|
|
2037
|
+
// stays in group and cdx:ai:provider.
|
|
2038
|
+
const declaredProvider = Array.from(fileSignals.providers)[0];
|
|
1903
2039
|
const provider =
|
|
1904
|
-
|
|
2040
|
+
declaredProvider ||
|
|
2041
|
+
splitModelReference(modelId).routeProvider ||
|
|
2042
|
+
providerFromModelName(modelId);
|
|
1905
2043
|
const component = createModelComponent(
|
|
1906
2044
|
componentsByKey,
|
|
1907
2045
|
{
|
|
1908
2046
|
assetType: "model",
|
|
1909
2047
|
confidence: "medium",
|
|
1910
2048
|
kind: "model",
|
|
2049
|
+
modelCreator: resolveModelCreator(modelId, {
|
|
2050
|
+
fileProviders: fileSignals.providers,
|
|
2051
|
+
provider: declaredProvider,
|
|
2052
|
+
runtimes: fileSignals.runtimes,
|
|
2053
|
+
}),
|
|
1911
2054
|
modelFamily: modelFamilyFromName(modelId),
|
|
1912
2055
|
modelId,
|
|
1913
2056
|
provider,
|
|
@@ -2102,6 +2245,9 @@ export function collectJsAiInventory(discoveryPath, options = {}) {
|
|
|
2102
2245
|
ggufModelIdFromFilename(parsedFileName, filePath),
|
|
2103
2246
|
parameterCount: metadata["general.parameter_count"],
|
|
2104
2247
|
pedigree: createGgufPedigree(metadata),
|
|
2248
|
+
// general.organization is the creator the file declares, so it is
|
|
2249
|
+
// the manufacturer even when it is not a known creator.
|
|
2250
|
+
producer: metadata["general.organization"],
|
|
2105
2251
|
provider: metadata["general.organization"] || "local",
|
|
2106
2252
|
quantization,
|
|
2107
2253
|
reviewNeeded: true,
|