@cyclonedx/cdxgen 12.3.1 → 12.3.3
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 +6 -0
- package/bin/cdxgen.js +1 -2
- package/data/rules/ai-agent-governance.yaml +43 -0
- package/data/rules/ci-permissions.yaml +132 -0
- package/data/rules/dependency-sources.yaml +65 -5
- package/data/rules/mcp-servers.yaml +36 -2
- package/data/rules/package-integrity.yaml +22 -0
- package/lib/cli/index.js +436 -56
- package/lib/cli/index.poku.js +875 -2
- package/lib/helpers/agentFormulationParser.js +10 -3
- package/lib/helpers/agentFormulationParser.poku.js +42 -0
- package/lib/helpers/aiInventory.js +262 -0
- package/lib/helpers/aiInventory.poku.js +111 -0
- package/lib/helpers/analyzer.js +413 -54
- package/lib/helpers/analyzer.poku.js +117 -0
- package/lib/helpers/auditCategories.js +76 -0
- package/lib/helpers/chromextutils.js +25 -3
- package/lib/helpers/chromextutils.poku.js +68 -0
- package/lib/helpers/ciParsers/githubActions.js +79 -0
- package/lib/helpers/ciParsers/githubActions.poku.js +103 -0
- package/lib/helpers/communityAiConfigParser.js +15 -5
- package/lib/helpers/communityAiConfigParser.poku.js +71 -0
- package/lib/helpers/depsUtils.js +5 -0
- package/lib/helpers/depsUtils.poku.js +55 -0
- package/lib/helpers/display.js +50 -24
- package/lib/helpers/display.poku.js +70 -58
- package/lib/helpers/formulationParsers.js +26 -6
- package/lib/helpers/jsonLike.js +21 -20
- package/lib/helpers/jsonLike.poku.js +34 -0
- package/lib/helpers/mcpConfigParser.js +32 -16
- package/lib/helpers/mcpConfigParser.poku.js +104 -0
- package/lib/helpers/mcpDiscovery.js +13 -23
- package/lib/helpers/mcpDiscovery.poku.js +21 -0
- package/lib/helpers/propertySanitizer.js +121 -0
- package/lib/helpers/utils.js +953 -41
- package/lib/helpers/utils.poku.js +901 -1
- package/lib/managers/binary.js +16 -0
- package/lib/managers/binary.poku.js +1 -0
- package/lib/managers/docker.js +240 -16
- package/lib/managers/docker.poku.js +1142 -2
- package/lib/server/server.js +7 -4
- package/lib/server/server.poku.js +36 -1
- package/lib/stages/postgen/annotator.js +2 -1
- package/lib/stages/postgen/annotator.poku.js +15 -0
- package/lib/stages/postgen/auditBom.js +12 -6
- package/lib/stages/postgen/auditBom.poku.js +755 -6
- package/lib/stages/postgen/postgen.js +229 -6
- package/lib/stages/postgen/postgen.poku.js +180 -0
- package/package.json +2 -1
- package/types/lib/cli/index.d.ts +1 -0
- package/types/lib/cli/index.d.ts.map +1 -1
- package/types/lib/helpers/agentFormulationParser.d.ts +19 -0
- package/types/lib/helpers/agentFormulationParser.d.ts.map +1 -0
- package/types/lib/helpers/aiInventory.d.ts +23 -0
- package/types/lib/helpers/aiInventory.d.ts.map +1 -0
- package/types/lib/helpers/analyzer.d.ts +5 -0
- package/types/lib/helpers/analyzer.d.ts.map +1 -1
- package/types/lib/helpers/auditCategories.d.ts +12 -0
- package/types/lib/helpers/auditCategories.d.ts.map +1 -0
- package/types/lib/helpers/chromextutils.d.ts.map +1 -1
- package/types/lib/helpers/ciParsers/githubActions.d.ts.map +1 -1
- package/types/lib/helpers/communityAiConfigParser.d.ts +29 -0
- package/types/lib/helpers/communityAiConfigParser.d.ts.map +1 -0
- package/types/lib/helpers/depsUtils.d.ts.map +1 -1
- package/types/lib/helpers/display.d.ts +1 -0
- package/types/lib/helpers/display.d.ts.map +1 -1
- package/types/lib/helpers/formulationParsers.d.ts.map +1 -1
- package/types/lib/helpers/jsonLike.d.ts +4 -0
- package/types/lib/helpers/jsonLike.d.ts.map +1 -0
- package/types/lib/helpers/mcp.d.ts +29 -0
- package/types/lib/helpers/mcp.d.ts.map +1 -0
- package/types/lib/helpers/mcpConfigParser.d.ts +30 -0
- package/types/lib/helpers/mcpConfigParser.d.ts.map +1 -0
- package/types/lib/helpers/mcpDiscovery.d.ts +5 -0
- package/types/lib/helpers/mcpDiscovery.d.ts.map +1 -0
- package/types/lib/helpers/propertySanitizer.d.ts +3 -0
- package/types/lib/helpers/propertySanitizer.d.ts.map +1 -0
- package/types/lib/helpers/utils.d.ts +31 -0
- package/types/lib/helpers/utils.d.ts.map +1 -1
- package/types/lib/managers/binary.d.ts.map +1 -1
- package/types/lib/managers/docker.d.ts +3 -0
- package/types/lib/managers/docker.d.ts.map +1 -1
- package/types/lib/server/server.d.ts +1 -0
- package/types/lib/server/server.d.ts.map +1 -1
- package/types/lib/stages/postgen/annotator.d.ts.map +1 -1
- package/types/lib/stages/postgen/auditBom.d.ts.map +1 -1
- package/types/lib/stages/postgen/postgen.d.ts.map +1 -1
package/lib/cli/index.js
CHANGED
|
@@ -18,10 +18,24 @@ import { parse } from "ssri";
|
|
|
18
18
|
import { v4 as uuidv4 } from "uuid";
|
|
19
19
|
import { parse as loadYaml } from "yaml";
|
|
20
20
|
|
|
21
|
+
import {
|
|
22
|
+
AI_INSTRUCTION_FILE_KINDS,
|
|
23
|
+
AI_INVENTORY_PROJECT_TYPES,
|
|
24
|
+
AI_SKILL_FILE_KIND,
|
|
25
|
+
collectAiInventory,
|
|
26
|
+
filterInventoryDependencies,
|
|
27
|
+
filterInventorySubjectsByTypes,
|
|
28
|
+
inventoryPropertyValue,
|
|
29
|
+
MCP_CONFIG_FILE_KIND,
|
|
30
|
+
optionIncludesAiInventoryProjectType,
|
|
31
|
+
summarizeAiInventory,
|
|
32
|
+
} from "../helpers/aiInventory.js";
|
|
21
33
|
import {
|
|
22
34
|
detectMcpInventory,
|
|
35
|
+
detectPythonMcpInventory,
|
|
23
36
|
findJSImportsExports,
|
|
24
37
|
} from "../helpers/analyzer.js";
|
|
38
|
+
import { expandBomAuditCategories } from "../helpers/auditCategories.js";
|
|
25
39
|
import { parseCaxaMetadata } from "../helpers/caxa.js";
|
|
26
40
|
import {
|
|
27
41
|
CHROME_EXTENSION_PURL_TYPE,
|
|
@@ -50,6 +64,7 @@ import {
|
|
|
50
64
|
addEvidenceForDotnet,
|
|
51
65
|
addEvidenceForImports,
|
|
52
66
|
addPlugin,
|
|
67
|
+
attachIdentityTools,
|
|
53
68
|
buildGradleCommandArguments,
|
|
54
69
|
buildObjectForCocoaPod,
|
|
55
70
|
buildObjectForGradleModule,
|
|
@@ -74,6 +89,7 @@ import {
|
|
|
74
89
|
executeParallelGradleProperties,
|
|
75
90
|
executePodCommand,
|
|
76
91
|
extractJarArchive,
|
|
92
|
+
extractToolRefs,
|
|
77
93
|
frameworksList,
|
|
78
94
|
generatePixiLockFile,
|
|
79
95
|
getAllFiles,
|
|
@@ -120,6 +136,7 @@ import {
|
|
|
120
136
|
parseCloudBuildData,
|
|
121
137
|
parseCmakeLikeFile,
|
|
122
138
|
parseCocoaDependency,
|
|
139
|
+
parseColliderLockData,
|
|
123
140
|
parseComposerJson,
|
|
124
141
|
parseComposerLock,
|
|
125
142
|
parseConanData,
|
|
@@ -197,6 +214,9 @@ import {
|
|
|
197
214
|
shouldFetchLicense,
|
|
198
215
|
splitOutputByGradleProjects,
|
|
199
216
|
} from "../helpers/utils.js";
|
|
217
|
+
|
|
218
|
+
export { summarizeAiInventory } from "../helpers/aiInventory.js";
|
|
219
|
+
|
|
200
220
|
import {
|
|
201
221
|
cleanupTempDir,
|
|
202
222
|
collectInstalledExtensions,
|
|
@@ -312,7 +332,10 @@ const createDefaultParentComponent = (
|
|
|
312
332
|
group: options.projectGroup || "",
|
|
313
333
|
name: compName,
|
|
314
334
|
version: `${options.projectVersion}` || "latest",
|
|
315
|
-
type:
|
|
335
|
+
type:
|
|
336
|
+
type === "container" || compName.endsWith(".tar")
|
|
337
|
+
? "container"
|
|
338
|
+
: "application",
|
|
316
339
|
};
|
|
317
340
|
const ppurl = new PackageURL(
|
|
318
341
|
type,
|
|
@@ -327,6 +350,25 @@ const createDefaultParentComponent = (
|
|
|
327
350
|
return parentComponent;
|
|
328
351
|
};
|
|
329
352
|
|
|
353
|
+
const shouldIncludeNodeModulesDir = (options = {}, baseProjectTypes = []) => {
|
|
354
|
+
if (options.deep) {
|
|
355
|
+
return true;
|
|
356
|
+
}
|
|
357
|
+
const projectTypes = Array.isArray(options.projectType)
|
|
358
|
+
? options.projectType
|
|
359
|
+
: options.projectType
|
|
360
|
+
? [options.projectType]
|
|
361
|
+
: [];
|
|
362
|
+
if (!projectTypes.length) {
|
|
363
|
+
return true;
|
|
364
|
+
}
|
|
365
|
+
return baseProjectTypes.some((projectType) =>
|
|
366
|
+
projectTypes.every((selectedProjectType) =>
|
|
367
|
+
PROJECT_TYPE_ALIASES[projectType]?.includes(selectedProjectType),
|
|
368
|
+
),
|
|
369
|
+
);
|
|
370
|
+
};
|
|
371
|
+
|
|
330
372
|
const determineParentComponent = (options) => {
|
|
331
373
|
let parentComponent;
|
|
332
374
|
if (options.parentComponent && Object.keys(options.parentComponent).length) {
|
|
@@ -1351,17 +1393,21 @@ export async function createJarBom(path, options) {
|
|
|
1351
1393
|
let pkgList = [];
|
|
1352
1394
|
let jarFiles;
|
|
1353
1395
|
let nsMapping = {};
|
|
1354
|
-
|
|
1355
|
-
options
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
if (typeof
|
|
1359
|
-
|
|
1396
|
+
const searchOptions = {
|
|
1397
|
+
...options,
|
|
1398
|
+
exclude: [...(options.exclude || [])],
|
|
1399
|
+
};
|
|
1400
|
+
if (typeof searchOptions.includeNodeModulesDir === "undefined") {
|
|
1401
|
+
searchOptions.includeNodeModulesDir = shouldIncludeNodeModulesDir(options, [
|
|
1402
|
+
"jar",
|
|
1403
|
+
"war",
|
|
1404
|
+
"ear",
|
|
1405
|
+
]);
|
|
1360
1406
|
}
|
|
1361
1407
|
// Exclude certain directories during oci sbom generation
|
|
1362
1408
|
if (hasAnyProjectType(["oci"], options, false)) {
|
|
1363
|
-
|
|
1364
|
-
|
|
1409
|
+
searchOptions.exclude.push("**/android-sdk*/**");
|
|
1410
|
+
searchOptions.exclude.push("**/.sdkman/**");
|
|
1365
1411
|
}
|
|
1366
1412
|
const parentComponent = createDefaultParentComponent(path, "maven", options);
|
|
1367
1413
|
if (options.useGradleCache) {
|
|
@@ -1385,14 +1431,14 @@ export async function createJarBom(path, options) {
|
|
|
1385
1431
|
jarFiles = getAllFiles(
|
|
1386
1432
|
path,
|
|
1387
1433
|
`${options.multiProject ? "**/" : ""}*.[jw]ar`,
|
|
1388
|
-
|
|
1434
|
+
searchOptions,
|
|
1389
1435
|
);
|
|
1390
1436
|
}
|
|
1391
1437
|
// Jenkins plugins
|
|
1392
1438
|
const hpiFiles = getAllFiles(
|
|
1393
1439
|
path,
|
|
1394
1440
|
`${options.multiProject ? "**/" : ""}*.hpi`,
|
|
1395
|
-
|
|
1441
|
+
searchOptions,
|
|
1396
1442
|
);
|
|
1397
1443
|
if (hpiFiles.length) {
|
|
1398
1444
|
jarFiles = jarFiles.concat(hpiFiles);
|
|
@@ -1447,6 +1493,13 @@ export function createBinaryBom(path, options) {
|
|
|
1447
1493
|
const binaryBom = JSON.parse(
|
|
1448
1494
|
readFileSync(binaryBomFile, { encoding: "utf-8" }),
|
|
1449
1495
|
);
|
|
1496
|
+
attachIdentityTools(
|
|
1497
|
+
binaryBom?.components,
|
|
1498
|
+
extractToolRefs(
|
|
1499
|
+
binaryBom?.metadata?.tools,
|
|
1500
|
+
(tool) => tool?.name !== "cdxgen",
|
|
1501
|
+
),
|
|
1502
|
+
);
|
|
1450
1503
|
return {
|
|
1451
1504
|
bomJson: binaryBom,
|
|
1452
1505
|
dependencies: binaryBom.dependencies,
|
|
@@ -1874,6 +1927,10 @@ export async function createJavaBom(path, options) {
|
|
|
1874
1927
|
) {
|
|
1875
1928
|
tools = bomJsonObj.metadata.tools;
|
|
1876
1929
|
}
|
|
1930
|
+
const toolRefs = extractToolRefs(
|
|
1931
|
+
bomJsonObj?.metadata?.tools,
|
|
1932
|
+
(tool) => tool?.name !== "cdxgen",
|
|
1933
|
+
);
|
|
1877
1934
|
if (
|
|
1878
1935
|
bomJsonObj.metadata?.component &&
|
|
1879
1936
|
!Object.keys(parentComponent).length
|
|
@@ -1910,6 +1967,7 @@ export async function createJavaBom(path, options) {
|
|
|
1910
1967
|
name: "SrcFile",
|
|
1911
1968
|
value: srcPomFile,
|
|
1912
1969
|
});
|
|
1970
|
+
attachIdentityTools(acomp, toolRefs);
|
|
1913
1971
|
}
|
|
1914
1972
|
}
|
|
1915
1973
|
pkgList = pkgList.concat(bomJsonObj.components);
|
|
@@ -2717,16 +2775,32 @@ export async function createJavaBom(path, options) {
|
|
|
2717
2775
|
* @param {Object} options Parse options from the cli
|
|
2718
2776
|
* @returns {Promise<Object>} Promise resolving to BOM object
|
|
2719
2777
|
*/
|
|
2778
|
+
function getRequestedAiInventoryTypes(options) {
|
|
2779
|
+
return AI_INVENTORY_PROJECT_TYPES.filter((type) =>
|
|
2780
|
+
optionIncludesAiInventoryProjectType(options?.projectType, type),
|
|
2781
|
+
);
|
|
2782
|
+
}
|
|
2783
|
+
|
|
2784
|
+
function getExcludedAiInventoryTypes(options) {
|
|
2785
|
+
return AI_INVENTORY_PROJECT_TYPES.filter((type) =>
|
|
2786
|
+
optionIncludesAiInventoryProjectType(options?.excludeType, type),
|
|
2787
|
+
);
|
|
2788
|
+
}
|
|
2789
|
+
|
|
2790
|
+
function getExactAiInventoryType(options) {
|
|
2791
|
+
const requestedAiInventoryTypes = getRequestedAiInventoryTypes(options);
|
|
2792
|
+
return requestedAiInventoryTypes.length === 1 &&
|
|
2793
|
+
Array.isArray(options?.projectType) &&
|
|
2794
|
+
options.projectType.length === 1
|
|
2795
|
+
? requestedAiInventoryTypes[0]
|
|
2796
|
+
: undefined;
|
|
2797
|
+
}
|
|
2798
|
+
|
|
2720
2799
|
function shouldDetectMcpInventory(options, allImports = {}) {
|
|
2721
2800
|
if (hasAnyProjectType(["mcp"], options, false)) {
|
|
2722
2801
|
return true;
|
|
2723
2802
|
}
|
|
2724
|
-
const auditCategories =
|
|
2725
|
-
? options.bomAuditCategories
|
|
2726
|
-
: String(options?.bomAuditCategories || "")
|
|
2727
|
-
.split(",")
|
|
2728
|
-
.map((category) => category.trim())
|
|
2729
|
-
.filter(Boolean);
|
|
2803
|
+
const auditCategories = expandBomAuditCategories(options?.bomAuditCategories);
|
|
2730
2804
|
if (
|
|
2731
2805
|
auditCategories.some((category) =>
|
|
2732
2806
|
["mcp-server", "ai-agent"].includes(category),
|
|
@@ -2740,6 +2814,91 @@ function shouldDetectMcpInventory(options, allImports = {}) {
|
|
|
2740
2814
|
});
|
|
2741
2815
|
}
|
|
2742
2816
|
|
|
2817
|
+
function summarizeAiInventoryNames(subjects, discoveryPath, kindSet) {
|
|
2818
|
+
return [
|
|
2819
|
+
...new Set(
|
|
2820
|
+
(subjects || [])
|
|
2821
|
+
.filter((subject) =>
|
|
2822
|
+
kindSet.has(inventoryPropertyValue(subject, "cdx:file:kind")),
|
|
2823
|
+
)
|
|
2824
|
+
.map((subject) => inventoryPropertyValue(subject, "SrcFile"))
|
|
2825
|
+
.filter(Boolean)
|
|
2826
|
+
.map(
|
|
2827
|
+
(filePath) => relative(discoveryPath, filePath) || basename(filePath),
|
|
2828
|
+
),
|
|
2829
|
+
),
|
|
2830
|
+
].sort();
|
|
2831
|
+
}
|
|
2832
|
+
|
|
2833
|
+
function summarizeAiInventoryServiceNames(services) {
|
|
2834
|
+
return [
|
|
2835
|
+
...new Set(
|
|
2836
|
+
(services || []).map((service) => service?.name).filter(Boolean),
|
|
2837
|
+
),
|
|
2838
|
+
].sort();
|
|
2839
|
+
}
|
|
2840
|
+
|
|
2841
|
+
function formatAiInventorySummaryLine(label, count, nameList) {
|
|
2842
|
+
return ` ${label.padEnd(20)} ${count}${nameList.length ? ` (${nameList.join(", ")})` : ""}`;
|
|
2843
|
+
}
|
|
2844
|
+
|
|
2845
|
+
function emitAiInventorySummary(aiInventory, discoveryPath) {
|
|
2846
|
+
const summary = summarizeAiInventory(aiInventory);
|
|
2847
|
+
const totalInventory =
|
|
2848
|
+
summary.instructionCount +
|
|
2849
|
+
summary.skillCount +
|
|
2850
|
+
summary.mcpConfigCount +
|
|
2851
|
+
summary.mcpServiceCount;
|
|
2852
|
+
if (!totalInventory) {
|
|
2853
|
+
return;
|
|
2854
|
+
}
|
|
2855
|
+
const instructionNames = summarizeAiInventoryNames(
|
|
2856
|
+
aiInventory.components,
|
|
2857
|
+
discoveryPath,
|
|
2858
|
+
AI_INSTRUCTION_FILE_KINDS,
|
|
2859
|
+
);
|
|
2860
|
+
const skillNames = summarizeAiInventoryNames(
|
|
2861
|
+
aiInventory.components,
|
|
2862
|
+
discoveryPath,
|
|
2863
|
+
new Set([AI_SKILL_FILE_KIND]),
|
|
2864
|
+
);
|
|
2865
|
+
const mcpConfigNames = summarizeAiInventoryNames(
|
|
2866
|
+
aiInventory.components,
|
|
2867
|
+
discoveryPath,
|
|
2868
|
+
new Set([MCP_CONFIG_FILE_KIND]),
|
|
2869
|
+
);
|
|
2870
|
+
const mcpServiceNames = summarizeAiInventoryServiceNames(
|
|
2871
|
+
aiInventory.services,
|
|
2872
|
+
);
|
|
2873
|
+
console.warn(
|
|
2874
|
+
[
|
|
2875
|
+
"AI Inventory Summary:",
|
|
2876
|
+
formatAiInventorySummaryLine(
|
|
2877
|
+
"AI instruction files:",
|
|
2878
|
+
summary.instructionCount,
|
|
2879
|
+
instructionNames,
|
|
2880
|
+
),
|
|
2881
|
+
formatAiInventorySummaryLine(
|
|
2882
|
+
"Skill files:",
|
|
2883
|
+
summary.skillCount,
|
|
2884
|
+
skillNames,
|
|
2885
|
+
),
|
|
2886
|
+
formatAiInventorySummaryLine(
|
|
2887
|
+
"MCP configs:",
|
|
2888
|
+
summary.mcpConfigCount,
|
|
2889
|
+
mcpConfigNames,
|
|
2890
|
+
),
|
|
2891
|
+
formatAiInventorySummaryLine(
|
|
2892
|
+
"MCP services:",
|
|
2893
|
+
summary.mcpServiceCount,
|
|
2894
|
+
mcpServiceNames,
|
|
2895
|
+
),
|
|
2896
|
+
"",
|
|
2897
|
+
"Run --bom-audit --bom-audit-categories ai-inventory to audit these surfaces.",
|
|
2898
|
+
].join("\n"),
|
|
2899
|
+
);
|
|
2900
|
+
}
|
|
2901
|
+
|
|
2743
2902
|
export async function createNodejsBom(path, options) {
|
|
2744
2903
|
let pkgList = [];
|
|
2745
2904
|
let manifestFiles = [];
|
|
@@ -2747,6 +2906,15 @@ export async function createNodejsBom(path, options) {
|
|
|
2747
2906
|
let parentComponent = {};
|
|
2748
2907
|
const parentSubComponents = [];
|
|
2749
2908
|
let ppurl = "";
|
|
2909
|
+
const requestedAiInventoryTypes = getRequestedAiInventoryTypes(options);
|
|
2910
|
+
const excludedAiInventoryTypes = getExcludedAiInventoryTypes(options);
|
|
2911
|
+
const exactAiInventoryType = getExactAiInventoryType(options);
|
|
2912
|
+
const includedAiInventoryTypes = exactAiInventoryType
|
|
2913
|
+
? requestedAiInventoryTypes
|
|
2914
|
+
: AI_INVENTORY_PROJECT_TYPES.filter(
|
|
2915
|
+
(type) => !excludedAiInventoryTypes.includes(type),
|
|
2916
|
+
);
|
|
2917
|
+
let aiInventory = { components: [], dependencies: [], services: [] };
|
|
2750
2918
|
// Docker mode requires special handling
|
|
2751
2919
|
if (hasAnyProjectType(["docker", "oci", "container", "os"], options, false)) {
|
|
2752
2920
|
const pkgJsonFiles = getAllFiles(path, "**/package.json", options);
|
|
@@ -2758,11 +2926,27 @@ export async function createNodejsBom(path, options) {
|
|
|
2758
2926
|
pkgList = pkgList.concat(dlist);
|
|
2759
2927
|
}
|
|
2760
2928
|
}
|
|
2929
|
+
if (includedAiInventoryTypes.length) {
|
|
2930
|
+
aiInventory = collectAiInventory(
|
|
2931
|
+
path,
|
|
2932
|
+
options,
|
|
2933
|
+
includedAiInventoryTypes,
|
|
2934
|
+
);
|
|
2935
|
+
}
|
|
2936
|
+
if (aiInventory.components?.length) {
|
|
2937
|
+
pkgList = trimComponents(pkgList.concat(aiInventory.components));
|
|
2938
|
+
}
|
|
2761
2939
|
return buildBomNSData(options, pkgList, "npm", {
|
|
2762
2940
|
allImports: {},
|
|
2763
2941
|
src: path,
|
|
2764
2942
|
filename: "package.json",
|
|
2943
|
+
dependencies: mergeDependencies(
|
|
2944
|
+
[],
|
|
2945
|
+
aiInventory.dependencies,
|
|
2946
|
+
parentComponent,
|
|
2947
|
+
),
|
|
2765
2948
|
parentComponent,
|
|
2949
|
+
services: aiInventory.services,
|
|
2766
2950
|
});
|
|
2767
2951
|
}
|
|
2768
2952
|
}
|
|
@@ -2785,6 +2969,40 @@ export async function createNodejsBom(path, options) {
|
|
|
2785
2969
|
mcpInventory = detectMcpInventory(path, options.deep);
|
|
2786
2970
|
}
|
|
2787
2971
|
}
|
|
2972
|
+
if (includedAiInventoryTypes.length) {
|
|
2973
|
+
aiInventory = collectAiInventory(path, options, includedAiInventoryTypes);
|
|
2974
|
+
}
|
|
2975
|
+
if (excludedAiInventoryTypes.includes("mcp")) {
|
|
2976
|
+
mcpInventory = { components: [], dependencies: [], services: [] };
|
|
2977
|
+
}
|
|
2978
|
+
const aiInventorySummary = summarizeAiInventory(aiInventory);
|
|
2979
|
+
if (!exactAiInventoryType) {
|
|
2980
|
+
if (aiInventorySummary.instructionCount || aiInventorySummary.skillCount) {
|
|
2981
|
+
thoughtLog(
|
|
2982
|
+
`I found ${aiInventorySummary.instructionCount + aiInventorySummary.skillCount} AI skill/instruction file component(s). Use '--exclude-type ai-skill' for a package-only BOM, or '--bom-audit --bom-audit-categories ai-inventory' for review-friendly reporting.`,
|
|
2983
|
+
);
|
|
2984
|
+
}
|
|
2985
|
+
if (aiInventorySummary.mcpConfigCount) {
|
|
2986
|
+
thoughtLog(
|
|
2987
|
+
`I found ${aiInventorySummary.mcpConfigCount} MCP config component(s). Use '--exclude-type mcp' to drop them, or '--bom-audit --bom-audit-categories ai-inventory --tlp-classification AMBER' to keep and flag them.`,
|
|
2988
|
+
);
|
|
2989
|
+
}
|
|
2990
|
+
emitAiInventorySummary(aiInventory, path);
|
|
2991
|
+
}
|
|
2992
|
+
if (exactAiInventoryType === "ai-skill") {
|
|
2993
|
+
const exactComponents = trimComponents([...(aiInventory.components || [])]);
|
|
2994
|
+
const exactDependencies = mergeDependencies([], aiInventory.dependencies);
|
|
2995
|
+
const exactServices = mergeServices([], aiInventory.services);
|
|
2996
|
+
parentComponent = createDefaultParentComponent(path, "generic", options);
|
|
2997
|
+
return buildBomNSData(options, exactComponents, "generic", {
|
|
2998
|
+
dependencies: exactDependencies,
|
|
2999
|
+
filename: path,
|
|
3000
|
+
parentComponent,
|
|
3001
|
+
projectType: exactAiInventoryType,
|
|
3002
|
+
services: exactServices,
|
|
3003
|
+
src: path,
|
|
3004
|
+
});
|
|
3005
|
+
}
|
|
2788
3006
|
let yarnLockFiles = getAllFiles(
|
|
2789
3007
|
path,
|
|
2790
3008
|
`${options.multiProject ? "**/" : ""}yarn.lock`,
|
|
@@ -3675,12 +3893,37 @@ export async function createNodejsBom(path, options) {
|
|
|
3675
3893
|
parentComponent,
|
|
3676
3894
|
);
|
|
3677
3895
|
}
|
|
3896
|
+
if (aiInventory.components?.length) {
|
|
3897
|
+
pkgList = trimComponents(pkgList.concat(aiInventory.components));
|
|
3898
|
+
}
|
|
3899
|
+
if (aiInventory.dependencies?.length) {
|
|
3900
|
+
dependencies = mergeDependencies(
|
|
3901
|
+
dependencies,
|
|
3902
|
+
aiInventory.dependencies,
|
|
3903
|
+
parentComponent,
|
|
3904
|
+
);
|
|
3905
|
+
}
|
|
3906
|
+
const inventoryServices = mergeServices(
|
|
3907
|
+
mergeServices([], mcpInventory.services || []),
|
|
3908
|
+
aiInventory.services || [],
|
|
3909
|
+
);
|
|
3910
|
+
if (exactAiInventoryType === "mcp") {
|
|
3911
|
+
pkgList = trimComponents(filterInventorySubjectsByTypes(pkgList, ["mcp"]));
|
|
3912
|
+
dependencies = filterInventoryDependencies(
|
|
3913
|
+
dependencies,
|
|
3914
|
+
pkgList,
|
|
3915
|
+
inventoryServices,
|
|
3916
|
+
);
|
|
3917
|
+
if (!parentComponent || !Object.keys(parentComponent).length) {
|
|
3918
|
+
parentComponent = createDefaultParentComponent(path, "generic", options);
|
|
3919
|
+
}
|
|
3920
|
+
}
|
|
3678
3921
|
return buildBomNSData(options, pkgList, "npm", {
|
|
3679
3922
|
src: path,
|
|
3680
3923
|
filename: manifestFiles.join(", "),
|
|
3681
3924
|
dependencies,
|
|
3682
3925
|
parentComponent,
|
|
3683
|
-
services:
|
|
3926
|
+
services: inventoryServices,
|
|
3684
3927
|
});
|
|
3685
3928
|
}
|
|
3686
3929
|
|
|
@@ -3859,6 +4102,16 @@ export async function createPythonBom(path, options) {
|
|
|
3859
4102
|
let dependencies = [];
|
|
3860
4103
|
let pkgList = [];
|
|
3861
4104
|
let formulationList = [];
|
|
4105
|
+
const requestedAiInventoryTypes = getRequestedAiInventoryTypes(options);
|
|
4106
|
+
const excludedAiInventoryTypes = getExcludedAiInventoryTypes(options);
|
|
4107
|
+
const includedAiInventoryTypes = AI_INVENTORY_PROJECT_TYPES.filter(
|
|
4108
|
+
(type) =>
|
|
4109
|
+
(!requestedAiInventoryTypes.length ||
|
|
4110
|
+
requestedAiInventoryTypes.includes(type)) &&
|
|
4111
|
+
!excludedAiInventoryTypes.includes(type),
|
|
4112
|
+
);
|
|
4113
|
+
let aiInventory = { components: [], dependencies: [], services: [] };
|
|
4114
|
+
let mcpInventory = { components: [], dependencies: [], services: [] };
|
|
3862
4115
|
const tempDir = safeMkdtempSync(join(getTmpDir(), "cdxgen-venv-"));
|
|
3863
4116
|
let parentComponent = createDefaultParentComponent(path, "pypi", options);
|
|
3864
4117
|
// We are checking only the root here for pipenv
|
|
@@ -4350,6 +4603,24 @@ export async function createPythonBom(path, options) {
|
|
|
4350
4603
|
pkgList = pkgList.concat(dlist);
|
|
4351
4604
|
}
|
|
4352
4605
|
}
|
|
4606
|
+
if (includedAiInventoryTypes.length) {
|
|
4607
|
+
aiInventory = collectAiInventory(path, options, includedAiInventoryTypes);
|
|
4608
|
+
if (includedAiInventoryTypes.includes("mcp")) {
|
|
4609
|
+
mcpInventory = detectPythonMcpInventory(path, options.deep);
|
|
4610
|
+
}
|
|
4611
|
+
}
|
|
4612
|
+
const aiInventorySummary = summarizeAiInventory(aiInventory);
|
|
4613
|
+
if (aiInventorySummary.instructionCount || aiInventorySummary.skillCount) {
|
|
4614
|
+
thoughtLog(
|
|
4615
|
+
`I found ${aiInventorySummary.instructionCount + aiInventorySummary.skillCount} AI skill/instruction file component(s). Use '--exclude-type ai-skill' for a package-only BOM, or '--bom-audit --bom-audit-categories ai-inventory' for review-friendly reporting.`,
|
|
4616
|
+
);
|
|
4617
|
+
}
|
|
4618
|
+
if (aiInventorySummary.mcpConfigCount) {
|
|
4619
|
+
thoughtLog(
|
|
4620
|
+
`I found ${aiInventorySummary.mcpConfigCount} MCP config component(s). Use '--exclude-type mcp' to drop them, or '--bom-audit --bom-audit-categories ai-inventory --tlp-classification AMBER' to keep and flag them.`,
|
|
4621
|
+
);
|
|
4622
|
+
}
|
|
4623
|
+
emitAiInventorySummary(aiInventory, path);
|
|
4353
4624
|
// Check and complete the dependency tree
|
|
4354
4625
|
if (
|
|
4355
4626
|
isFeatureEnabled(options, "safe-pip-install") &&
|
|
@@ -4398,6 +4669,30 @@ export async function createPythonBom(path, options) {
|
|
|
4398
4669
|
if (shouldFetchLicense()) {
|
|
4399
4670
|
pkgList = await getPyMetadata(pkgList, false);
|
|
4400
4671
|
}
|
|
4672
|
+
if (mcpInventory.components?.length) {
|
|
4673
|
+
pkgList = trimComponents(pkgList.concat(mcpInventory.components));
|
|
4674
|
+
}
|
|
4675
|
+
if (mcpInventory.dependencies?.length) {
|
|
4676
|
+
dependencies = mergeDependencies(
|
|
4677
|
+
dependencies,
|
|
4678
|
+
mcpInventory.dependencies,
|
|
4679
|
+
parentComponent,
|
|
4680
|
+
);
|
|
4681
|
+
}
|
|
4682
|
+
if (aiInventory.components?.length) {
|
|
4683
|
+
pkgList = trimComponents(pkgList.concat(aiInventory.components));
|
|
4684
|
+
}
|
|
4685
|
+
if (aiInventory.dependencies?.length) {
|
|
4686
|
+
dependencies = mergeDependencies(
|
|
4687
|
+
dependencies,
|
|
4688
|
+
aiInventory.dependencies,
|
|
4689
|
+
parentComponent,
|
|
4690
|
+
);
|
|
4691
|
+
}
|
|
4692
|
+
const inventoryServices = mergeServices(
|
|
4693
|
+
mergeServices([], mcpInventory.services || []),
|
|
4694
|
+
aiInventory.services || [],
|
|
4695
|
+
);
|
|
4401
4696
|
return buildBomNSData(options, pkgList, "pypi", {
|
|
4402
4697
|
allImports,
|
|
4403
4698
|
src: path,
|
|
@@ -4405,6 +4700,7 @@ export async function createPythonBom(path, options) {
|
|
|
4405
4700
|
dependencies,
|
|
4406
4701
|
parentComponent,
|
|
4407
4702
|
formulationList,
|
|
4703
|
+
services: inventoryServices,
|
|
4408
4704
|
});
|
|
4409
4705
|
}
|
|
4410
4706
|
|
|
@@ -5161,6 +5457,11 @@ export function createCppBom(path, options) {
|
|
|
5161
5457
|
let parentComponent;
|
|
5162
5458
|
let dependencies = [];
|
|
5163
5459
|
const addedParentComponentsMap = {};
|
|
5460
|
+
const colliderLockFiles = getAllFiles(
|
|
5461
|
+
path,
|
|
5462
|
+
`${options.multiProject ? "**/" : ""}collider.lock`,
|
|
5463
|
+
options,
|
|
5464
|
+
);
|
|
5164
5465
|
const conanLockFiles = getAllFiles(
|
|
5165
5466
|
path,
|
|
5166
5467
|
`${options.multiProject ? "**/" : ""}conan.lock`,
|
|
@@ -5237,6 +5538,39 @@ export function createCppBom(path, options) {
|
|
|
5237
5538
|
}
|
|
5238
5539
|
}
|
|
5239
5540
|
}
|
|
5541
|
+
if (colliderLockFiles.length) {
|
|
5542
|
+
for (const f of colliderLockFiles) {
|
|
5543
|
+
if (DEBUG_MODE) {
|
|
5544
|
+
console.log(`Parsing ${f}`);
|
|
5545
|
+
}
|
|
5546
|
+
const colliderLockData = readFileSync(f, { encoding: "utf-8" });
|
|
5547
|
+
const {
|
|
5548
|
+
pkgList: colliderPkgList,
|
|
5549
|
+
dependencies: colliderDependencies,
|
|
5550
|
+
parentComponentDependencies: parentCompDeps,
|
|
5551
|
+
} = parseColliderLockData(colliderLockData, f);
|
|
5552
|
+
|
|
5553
|
+
if (colliderPkgList.length) {
|
|
5554
|
+
pkgList = pkgList.concat(colliderPkgList);
|
|
5555
|
+
}
|
|
5556
|
+
|
|
5557
|
+
if (Object.keys(colliderDependencies).length) {
|
|
5558
|
+
dependencies = mergeDependencies(
|
|
5559
|
+
dependencies,
|
|
5560
|
+
Object.keys(colliderDependencies).map((dependentBomRef) => ({
|
|
5561
|
+
ref: dependentBomRef,
|
|
5562
|
+
dependsOn: colliderDependencies[dependentBomRef],
|
|
5563
|
+
})),
|
|
5564
|
+
);
|
|
5565
|
+
}
|
|
5566
|
+
|
|
5567
|
+
if (parentCompDeps.length) {
|
|
5568
|
+
parentComponentDependencies = [
|
|
5569
|
+
...new Set(parentComponentDependencies.concat(parentCompDeps)),
|
|
5570
|
+
];
|
|
5571
|
+
}
|
|
5572
|
+
}
|
|
5573
|
+
}
|
|
5240
5574
|
if (cmakeLikeFiles.length) {
|
|
5241
5575
|
for (const f of cmakeLikeFiles) {
|
|
5242
5576
|
if (DEBUG_MODE) {
|
|
@@ -6575,24 +6909,26 @@ export async function createContainerSpecLikeBom(path, options) {
|
|
|
6575
6909
|
export function createPHPBom(path, options) {
|
|
6576
6910
|
let dependencies = [];
|
|
6577
6911
|
let parentComponent = {};
|
|
6578
|
-
|
|
6579
|
-
|
|
6580
|
-
|
|
6581
|
-
|
|
6912
|
+
const searchOptions = {
|
|
6913
|
+
...options,
|
|
6914
|
+
includeNodeModulesDir:
|
|
6915
|
+
typeof options.includeNodeModulesDir === "undefined"
|
|
6916
|
+
? shouldIncludeNodeModulesDir(options, ["php"])
|
|
6917
|
+
: options.includeNodeModulesDir,
|
|
6918
|
+
};
|
|
6919
|
+
const composerLockSearchOptions = {
|
|
6920
|
+
...searchOptions,
|
|
6921
|
+
exclude: [...(options.exclude || []), "**/vendor/**"],
|
|
6922
|
+
};
|
|
6582
6923
|
const composerJsonFiles = getAllFiles(
|
|
6583
6924
|
path,
|
|
6584
6925
|
`${options.multiProject ? "**/" : ""}composer.json`,
|
|
6585
|
-
|
|
6926
|
+
searchOptions,
|
|
6586
6927
|
);
|
|
6587
|
-
if (!options.exclude) {
|
|
6588
|
-
options.exclude = [];
|
|
6589
|
-
}
|
|
6590
|
-
// Ignore vendor directories for lock files
|
|
6591
|
-
options.exclude.push("**/vendor/**");
|
|
6592
6928
|
let composerLockFiles = getAllFiles(
|
|
6593
6929
|
path,
|
|
6594
6930
|
`${options.multiProject ? "**/" : ""}composer.lock`,
|
|
6595
|
-
|
|
6931
|
+
composerLockSearchOptions,
|
|
6596
6932
|
);
|
|
6597
6933
|
let pkgList = [];
|
|
6598
6934
|
const composerJsonMode = composerJsonFiles.length;
|
|
@@ -6655,7 +6991,7 @@ export function createPHPBom(path, options) {
|
|
|
6655
6991
|
composerLockFiles = getAllFiles(
|
|
6656
6992
|
path,
|
|
6657
6993
|
`${options.multiProject ? "**/" : ""}composer.lock`,
|
|
6658
|
-
|
|
6994
|
+
composerLockSearchOptions,
|
|
6659
6995
|
);
|
|
6660
6996
|
if (composerLockFiles.length) {
|
|
6661
6997
|
// Look for any root composer.json to capture the parentComponent
|
|
@@ -7803,6 +8139,7 @@ export async function createMultiXBom(pathList, options) {
|
|
|
7803
8139
|
binPaths,
|
|
7804
8140
|
executables,
|
|
7805
8141
|
sharedLibs,
|
|
8142
|
+
tools,
|
|
7806
8143
|
} = await getOSPackages(
|
|
7807
8144
|
options.allLayersExplodedDir,
|
|
7808
8145
|
options.exportData?.inspectData?.Config,
|
|
@@ -7833,6 +8170,13 @@ export async function createMultiXBom(pathList, options) {
|
|
|
7833
8170
|
if (allTypes?.length) {
|
|
7834
8171
|
options.allOSComponentTypes = allTypes;
|
|
7835
8172
|
}
|
|
8173
|
+
if (tools?.length) {
|
|
8174
|
+
options.tools = (
|
|
8175
|
+
Array.isArray(options.tools)
|
|
8176
|
+
? options.tools
|
|
8177
|
+
: options.tools?.components || []
|
|
8178
|
+
).concat(tools);
|
|
8179
|
+
}
|
|
7836
8180
|
components = components.concat(osPackages);
|
|
7837
8181
|
components = components.concat(executables);
|
|
7838
8182
|
components = components.concat(sharedLibs);
|
|
@@ -7882,22 +8226,39 @@ export async function createMultiXBom(pathList, options) {
|
|
|
7882
8226
|
if (pathList.length > 2) {
|
|
7883
8227
|
thoughtLog(`Let's thoroughly check the path ${path}.`);
|
|
7884
8228
|
}
|
|
7885
|
-
// Node.js
|
|
7886
|
-
if (hasAnyProjectType(["oci", "js"], options)) {
|
|
8229
|
+
// Node.js and AI inventory
|
|
8230
|
+
if (hasAnyProjectType(["oci", "js", "mcp", "ai-skill"], options)) {
|
|
8231
|
+
const exactAiInventoryType = getExactAiInventoryType(options);
|
|
7887
8232
|
if (!hasAnyProjectType(["oci"], options, false)) {
|
|
7888
|
-
|
|
7889
|
-
|
|
7890
|
-
|
|
8233
|
+
if (exactAiInventoryType === "mcp") {
|
|
8234
|
+
thoughtLog(
|
|
8235
|
+
"**MCP**: Looking for MCP services, MCP configs, and related AI control-plane artifacts.",
|
|
8236
|
+
);
|
|
8237
|
+
} else if (exactAiInventoryType === "ai-skill") {
|
|
8238
|
+
thoughtLog(
|
|
8239
|
+
"**AI-SKILL**: Looking for AI instruction, skill, and agent-definition files that can influence build or release flows.",
|
|
8240
|
+
);
|
|
8241
|
+
} else {
|
|
8242
|
+
thoughtLog(
|
|
8243
|
+
"**JS**: Now looking for JavaScript projects (npm, yarn, pnpm) and files.",
|
|
8244
|
+
);
|
|
8245
|
+
}
|
|
7891
8246
|
}
|
|
7892
|
-
setProjectTypeActivityContext("js", path);
|
|
8247
|
+
setProjectTypeActivityContext(exactAiInventoryType || "js", path);
|
|
7893
8248
|
bomData = await createNodejsBom(path, options);
|
|
7894
8249
|
if (bomData?.bomJson?.components?.length) {
|
|
7895
|
-
|
|
7896
|
-
|
|
7897
|
-
|
|
8250
|
+
if (exactAiInventoryType) {
|
|
8251
|
+
thoughtLog(
|
|
8252
|
+
`I found ${bomData.bomJson.components.length} ${exactAiInventoryType} component(s). Let's keep looking.`,
|
|
8253
|
+
);
|
|
8254
|
+
} else {
|
|
8255
|
+
thoughtLog(
|
|
8256
|
+
`I found ${bomData.bomJson.components.length} npm packages. Let's keep looking.`,
|
|
8257
|
+
);
|
|
8258
|
+
}
|
|
7898
8259
|
if (DEBUG_MODE) {
|
|
7899
8260
|
console.log(
|
|
7900
|
-
`Found ${bomData.bomJson.components.length} npm
|
|
8261
|
+
`Found ${bomData.bomJson.components.length} ${exactAiInventoryType || "npm"} components at ${path}`,
|
|
7901
8262
|
);
|
|
7902
8263
|
}
|
|
7903
8264
|
components = components.concat(bomData.bomJson.components);
|
|
@@ -8890,6 +9251,11 @@ export async function createXBom(path, options) {
|
|
|
8890
9251
|
`${options.multiProject ? "**/" : ""}conan.lock`,
|
|
8891
9252
|
options,
|
|
8892
9253
|
);
|
|
9254
|
+
const colliderLockFiles = getAllFiles(
|
|
9255
|
+
path,
|
|
9256
|
+
`${options.multiProject ? "**/" : ""}collider.lock`,
|
|
9257
|
+
options,
|
|
9258
|
+
);
|
|
8893
9259
|
const conanFiles = getAllFiles(
|
|
8894
9260
|
path,
|
|
8895
9261
|
`${options.multiProject ? "**/" : ""}conanfile.txt`,
|
|
@@ -8906,6 +9272,7 @@ export async function createXBom(path, options) {
|
|
|
8906
9272
|
options,
|
|
8907
9273
|
);
|
|
8908
9274
|
if (
|
|
9275
|
+
colliderLockFiles.length ||
|
|
8909
9276
|
conanLockFiles.length ||
|
|
8910
9277
|
conanFiles.length ||
|
|
8911
9278
|
cmakeListFiles.length ||
|
|
@@ -9075,6 +9442,10 @@ export async function createBom(path, options) {
|
|
|
9075
9442
|
}
|
|
9076
9443
|
let exportData;
|
|
9077
9444
|
let isContainerMode = false;
|
|
9445
|
+
const isLocalDirectoryInput =
|
|
9446
|
+
!options.projectType?.includes("universal") &&
|
|
9447
|
+
safeExistsSync(path) &&
|
|
9448
|
+
lstatSync(path).isDirectory();
|
|
9078
9449
|
// Docker and image archive support
|
|
9079
9450
|
// TODO: Support any source archive
|
|
9080
9451
|
if (path.endsWith(".tar") || path.endsWith(".tar.gz")) {
|
|
@@ -9087,6 +9458,22 @@ export async function createBom(path, options) {
|
|
|
9087
9458
|
return {};
|
|
9088
9459
|
}
|
|
9089
9460
|
isContainerMode = true;
|
|
9461
|
+
} else if (
|
|
9462
|
+
isLocalDirectoryInput &&
|
|
9463
|
+
(hasAnyProjectType(["oci-dir"], options, false) ||
|
|
9464
|
+
hasAnyProjectType(["oci"], options, false))
|
|
9465
|
+
) {
|
|
9466
|
+
isContainerMode = true;
|
|
9467
|
+
exportData = {
|
|
9468
|
+
inspectData: undefined,
|
|
9469
|
+
lastWorkingDir: "",
|
|
9470
|
+
allLayersDir: path,
|
|
9471
|
+
allLayersExplodedDir: path,
|
|
9472
|
+
};
|
|
9473
|
+
if (safeExistsSync(join(path, "all-layers"))) {
|
|
9474
|
+
exportData.allLayersExplodedDir = join(path, "all-layers");
|
|
9475
|
+
}
|
|
9476
|
+
exportData.pkgPathList = getPkgPathList(exportData, undefined);
|
|
9090
9477
|
} else if (
|
|
9091
9478
|
(options.projectType &&
|
|
9092
9479
|
!options.projectType?.includes("universal") &&
|
|
@@ -9114,21 +9501,6 @@ export async function createBom(path, options) {
|
|
|
9114
9501
|
console.log(path, "doesn't appear to be a valid container image.");
|
|
9115
9502
|
}
|
|
9116
9503
|
}
|
|
9117
|
-
} else if (
|
|
9118
|
-
!options.projectType?.includes("universal") &&
|
|
9119
|
-
hasAnyProjectType(["oci-dir"], options, false)
|
|
9120
|
-
) {
|
|
9121
|
-
isContainerMode = true;
|
|
9122
|
-
exportData = {
|
|
9123
|
-
inspectData: undefined,
|
|
9124
|
-
lastWorkingDir: "",
|
|
9125
|
-
allLayersDir: path,
|
|
9126
|
-
allLayersExplodedDir: path,
|
|
9127
|
-
};
|
|
9128
|
-
if (safeExistsSync(join(path, "all-layers"))) {
|
|
9129
|
-
exportData.allLayersDir = join(path, "all-layers");
|
|
9130
|
-
}
|
|
9131
|
-
exportData.pkgPathList = getPkgPathList(exportData, undefined);
|
|
9132
9504
|
}
|
|
9133
9505
|
if (isContainerMode) {
|
|
9134
9506
|
options.multiProject = true;
|
|
@@ -9238,6 +9610,12 @@ export async function createBom(path, options) {
|
|
|
9238
9610
|
) {
|
|
9239
9611
|
return await createNodejsBom(path, options);
|
|
9240
9612
|
}
|
|
9613
|
+
if (PROJECT_TYPE_ALIASES["mcp"].includes(projectType[0])) {
|
|
9614
|
+
return await createNodejsBom(path, options);
|
|
9615
|
+
}
|
|
9616
|
+
if (PROJECT_TYPE_ALIASES["ai-skill"].includes(projectType[0])) {
|
|
9617
|
+
return await createNodejsBom(path, options);
|
|
9618
|
+
}
|
|
9241
9619
|
if (
|
|
9242
9620
|
PROJECT_TYPE_ALIASES["py"].includes(projectType[0]) ||
|
|
9243
9621
|
projectType?.[0]?.startsWith("python")
|
|
@@ -9402,6 +9780,7 @@ export async function submitBom(args, bomContents) {
|
|
|
9402
9780
|
// See issue #1963 regarding CRLF hardening
|
|
9403
9781
|
return await got(serverUrl, {
|
|
9404
9782
|
method: "PUT",
|
|
9783
|
+
followRedirect: false,
|
|
9405
9784
|
https: {
|
|
9406
9785
|
rejectUnauthorized: !args.skipDtTlsCheck,
|
|
9407
9786
|
},
|
|
@@ -9427,11 +9806,12 @@ export async function submitBom(args, bomContents) {
|
|
|
9427
9806
|
try {
|
|
9428
9807
|
return await got(serverUrl, {
|
|
9429
9808
|
method: "POST",
|
|
9809
|
+
followRedirect: false,
|
|
9430
9810
|
https: {
|
|
9431
9811
|
rejectUnauthorized: !args.skipDtTlsCheck,
|
|
9432
9812
|
},
|
|
9433
9813
|
headers: {
|
|
9434
|
-
"X-Api-Key": args.apiKey,
|
|
9814
|
+
"X-Api-Key": (args.apiKey || "").replace(/[\r\n]/g, ""),
|
|
9435
9815
|
"Content-Type": "application/json",
|
|
9436
9816
|
"user-agent": `@CycloneDX/cdxgen ${CDXGEN_VERSION}`,
|
|
9437
9817
|
},
|