@vyuhlabs/dxkit 2.0.1 → 2.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.
Files changed (103) hide show
  1. package/CHANGELOG.md +223 -0
  2. package/README.md +21 -15
  3. package/dist/analyzers/bom/detailed.d.ts +26 -0
  4. package/dist/analyzers/bom/detailed.d.ts.map +1 -0
  5. package/dist/analyzers/bom/detailed.js +227 -0
  6. package/dist/analyzers/bom/detailed.js.map +1 -0
  7. package/dist/analyzers/bom/gather.d.ts +63 -0
  8. package/dist/analyzers/bom/gather.d.ts.map +1 -0
  9. package/dist/analyzers/bom/gather.js +229 -0
  10. package/dist/analyzers/bom/gather.js.map +1 -0
  11. package/dist/analyzers/bom/index.d.ts +23 -0
  12. package/dist/analyzers/bom/index.d.ts.map +1 -0
  13. package/dist/analyzers/bom/index.js +220 -0
  14. package/dist/analyzers/bom/index.js.map +1 -0
  15. package/dist/analyzers/bom/types.d.ts +91 -0
  16. package/dist/analyzers/bom/types.d.ts.map +1 -0
  17. package/dist/analyzers/bom/types.js +3 -0
  18. package/dist/analyzers/bom/types.js.map +1 -0
  19. package/dist/analyzers/licenses/detailed.d.ts +30 -0
  20. package/dist/analyzers/licenses/detailed.d.ts.map +1 -0
  21. package/dist/analyzers/licenses/detailed.js +194 -0
  22. package/dist/analyzers/licenses/detailed.js.map +1 -0
  23. package/dist/analyzers/licenses/gather.d.ts +15 -0
  24. package/dist/analyzers/licenses/gather.d.ts.map +1 -0
  25. package/dist/analyzers/licenses/gather.js +24 -0
  26. package/dist/analyzers/licenses/gather.js.map +1 -0
  27. package/dist/analyzers/licenses/index.d.ts +21 -0
  28. package/dist/analyzers/licenses/index.d.ts.map +1 -0
  29. package/dist/analyzers/licenses/index.js +146 -0
  30. package/dist/analyzers/licenses/index.js.map +1 -0
  31. package/dist/analyzers/licenses/types.d.ts +30 -0
  32. package/dist/analyzers/licenses/types.d.ts.map +1 -0
  33. package/dist/analyzers/licenses/types.js +13 -0
  34. package/dist/analyzers/licenses/types.js.map +1 -0
  35. package/dist/analyzers/security/detailed.d.ts +0 -3
  36. package/dist/analyzers/security/detailed.d.ts.map +1 -1
  37. package/dist/analyzers/security/detailed.js +37 -6
  38. package/dist/analyzers/security/detailed.js.map +1 -1
  39. package/dist/analyzers/security/gather.d.ts.map +1 -1
  40. package/dist/analyzers/security/gather.js +2 -0
  41. package/dist/analyzers/security/gather.js.map +1 -1
  42. package/dist/analyzers/security/index.d.ts.map +1 -1
  43. package/dist/analyzers/security/index.js +53 -14
  44. package/dist/analyzers/security/index.js.map +1 -1
  45. package/dist/analyzers/security/types.d.ts +5 -0
  46. package/dist/analyzers/security/types.d.ts.map +1 -1
  47. package/dist/analyzers/security/types.js +0 -3
  48. package/dist/analyzers/security/types.js.map +1 -1
  49. package/dist/analyzers/tools/osv.d.ts +49 -5
  50. package/dist/analyzers/tools/osv.d.ts.map +1 -1
  51. package/dist/analyzers/tools/osv.js +99 -17
  52. package/dist/analyzers/tools/osv.js.map +1 -1
  53. package/dist/analyzers/tools/runner.d.ts +11 -0
  54. package/dist/analyzers/tools/runner.d.ts.map +1 -1
  55. package/dist/analyzers/tools/runner.js +54 -0
  56. package/dist/analyzers/tools/runner.js.map +1 -1
  57. package/dist/analyzers/tools/tool-registry.d.ts.map +1 -1
  58. package/dist/analyzers/tools/tool-registry.js +77 -0
  59. package/dist/analyzers/tools/tool-registry.js.map +1 -1
  60. package/dist/analyzers/xlsx/bom.d.ts +27 -0
  61. package/dist/analyzers/xlsx/bom.d.ts.map +1 -0
  62. package/dist/analyzers/xlsx/bom.js +141 -0
  63. package/dist/analyzers/xlsx/bom.js.map +1 -0
  64. package/dist/analyzers/xlsx/index.d.ts +27 -0
  65. package/dist/analyzers/xlsx/index.d.ts.map +1 -0
  66. package/dist/analyzers/xlsx/index.js +92 -0
  67. package/dist/analyzers/xlsx/index.js.map +1 -0
  68. package/dist/analyzers/xlsx/licenses.d.ts +40 -0
  69. package/dist/analyzers/xlsx/licenses.d.ts.map +1 -0
  70. package/dist/analyzers/xlsx/licenses.js +140 -0
  71. package/dist/analyzers/xlsx/licenses.js.map +1 -0
  72. package/dist/cli.d.ts.map +1 -1
  73. package/dist/cli.js +178 -1
  74. package/dist/cli.js.map +1 -1
  75. package/dist/languages/capabilities/descriptors.d.ts +4 -1
  76. package/dist/languages/capabilities/descriptors.d.ts.map +1 -1
  77. package/dist/languages/capabilities/descriptors.js +20 -1
  78. package/dist/languages/capabilities/descriptors.js.map +1 -1
  79. package/dist/languages/capabilities/types.d.ts +60 -3
  80. package/dist/languages/capabilities/types.d.ts.map +1 -1
  81. package/dist/languages/csharp.d.ts +48 -0
  82. package/dist/languages/csharp.d.ts.map +1 -1
  83. package/dist/languages/csharp.js +418 -33
  84. package/dist/languages/csharp.js.map +1 -1
  85. package/dist/languages/go.d.ts +35 -0
  86. package/dist/languages/go.d.ts.map +1 -1
  87. package/dist/languages/go.js +367 -26
  88. package/dist/languages/go.js.map +1 -1
  89. package/dist/languages/python.d.ts +49 -0
  90. package/dist/languages/python.d.ts.map +1 -1
  91. package/dist/languages/python.js +372 -11
  92. package/dist/languages/python.js.map +1 -1
  93. package/dist/languages/rust.d.ts +28 -0
  94. package/dist/languages/rust.d.ts.map +1 -1
  95. package/dist/languages/rust.js +287 -28
  96. package/dist/languages/rust.js.map +1 -1
  97. package/dist/languages/types.d.ts +2 -1
  98. package/dist/languages/types.d.ts.map +1 -1
  99. package/dist/languages/typescript.d.ts +17 -0
  100. package/dist/languages/typescript.d.ts.map +1 -1
  101. package/dist/languages/typescript.js +358 -1
  102. package/dist/languages/typescript.js.map +1 -1
  103. package/package.json +7 -2
@@ -0,0 +1,229 @@
1
+ "use strict";
2
+ /**
3
+ * BOM analyzer data-gather. Joins LICENSES + DEP_VULNS via the
4
+ * existing capability gather functions — no new tool invocation logic
5
+ * (CLAUDE.md rule 2). The gather just calls each, then walks both
6
+ * result sets to build a per-package join keyed by `package@version`.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.compareSemver = compareSemver;
10
+ exports.maxSemver = maxSemver;
11
+ exports.deriveTier1Resolution = deriveTier1Resolution;
12
+ exports.buildByTopLevelDep = buildByTopLevelDep;
13
+ exports.gatherBomEntries = gatherBomEntries;
14
+ const gather_1 = require("../licenses/gather");
15
+ const gather_2 = require("../security/gather");
16
+ const SEV_RANK = { critical: 0, high: 1, medium: 2, low: 3 };
17
+ /**
18
+ * Compare two version strings as semver triples. Strips a leading
19
+ * 'v' (Go-pack convention) and compares dot-separated numeric
20
+ * components. Falls back to lexicographic comparison when either
21
+ * input isn't a parseable triple — preserves a deterministic
22
+ * ordering for non-semver versions (e.g. cargo's "0.10.55+echo.1").
23
+ */
24
+ function compareSemver(a, b) {
25
+ const norm = (v) => v.replace(/^v/, '');
26
+ const pa = norm(a)
27
+ .split('.')
28
+ .map((p) => parseInt(p, 10));
29
+ const pb = norm(b)
30
+ .split('.')
31
+ .map((p) => parseInt(p, 10));
32
+ if (pa.some(isNaN) || pb.some(isNaN))
33
+ return norm(a).localeCompare(norm(b));
34
+ const len = Math.max(pa.length, pb.length);
35
+ for (let i = 0; i < len; i++) {
36
+ const xa = pa[i] ?? 0;
37
+ const xb = pb[i] ?? 0;
38
+ if (xa !== xb)
39
+ return xa - xb;
40
+ }
41
+ return 0;
42
+ }
43
+ /** Highest version in `versions` per compareSemver. Returns the input
44
+ * unchanged when only one version is supplied. */
45
+ function maxSemver(versions) {
46
+ if (versions.length === 0)
47
+ return '';
48
+ return versions.reduce((acc, v) => (compareSemver(v, acc) > 0 ? v : acc));
49
+ }
50
+ /**
51
+ * Tier-1 resolution proposal derived purely from `fixedVersion`
52
+ * data shipped by each pack's depVulns provider. Per checkpoint §9:
53
+ * - no vulns → empty
54
+ * - every vuln has fixedVersion → "PROPOSAL: Upgrade to <maxFix> (resolves N)"
55
+ * - some vuln lacks fixedVersion → "No fix available — evaluate replacement"
56
+ *
57
+ * Higher tiers (10h.4 Snyk, 10h.6 osv-scanner fix) populate
58
+ * `upgradeAdvice` directly on each finding; the bom render layer
59
+ * picks the richest available value per package.
60
+ */
61
+ function deriveTier1Resolution(vulns) {
62
+ if (vulns.length === 0)
63
+ return '';
64
+ const fixes = vulns.map((v) => v.fixedVersion).filter((v) => !!v);
65
+ if (fixes.length !== vulns.length) {
66
+ return 'No fix available — evaluate replacement';
67
+ }
68
+ const target = maxSemver(fixes);
69
+ return `PROPOSAL: Upgrade to ${target} (resolves ${vulns.length} vuln${vulns.length === 1 ? '' : 's'})`;
70
+ }
71
+ /** Highest severity across the supplied vulns. */
72
+ function maxSeverityOf(vulns) {
73
+ if (vulns.length === 0)
74
+ return null;
75
+ let best = 'low';
76
+ for (const v of vulns) {
77
+ if (SEV_RANK[v.severity] < SEV_RANK[best])
78
+ best = v.severity;
79
+ }
80
+ return best;
81
+ }
82
+ /**
83
+ * Build the per-top-level-dep rollup from a flat list of entries.
84
+ * Walks every advisory under every entry; increments the counter for
85
+ * each top-level the advisory lists (a vuln reachable from two
86
+ * top-levels increments both, matching Snyk's grouping semantics).
87
+ *
88
+ * Entries with no topLevelDep attribution contribute nothing — the
89
+ * rollup is best-effort based on what each pack populates. Pure
90
+ * function; unit-testable.
91
+ */
92
+ function buildByTopLevelDep(entries) {
93
+ const accum = new Map();
94
+ for (const e of entries) {
95
+ for (const v of e.vulns) {
96
+ const tops = v.topLevelDep;
97
+ if (!tops || tops.length === 0)
98
+ continue;
99
+ for (const top of tops) {
100
+ const cur = accum.get(top);
101
+ if (!cur) {
102
+ accum.set(top, {
103
+ advisoryCount: 1,
104
+ maxSeverity: v.severity,
105
+ packages: new Set([e.package]),
106
+ });
107
+ }
108
+ else {
109
+ cur.advisoryCount++;
110
+ if (SEV_RANK[v.severity] < SEV_RANK[cur.maxSeverity])
111
+ cur.maxSeverity = v.severity;
112
+ cur.packages.add(e.package);
113
+ }
114
+ }
115
+ }
116
+ }
117
+ const out = {};
118
+ for (const [top, data] of accum) {
119
+ out[top] = {
120
+ advisoryCount: data.advisoryCount,
121
+ maxSeverity: data.maxSeverity,
122
+ packages: [...data.packages].sort(),
123
+ };
124
+ }
125
+ return out;
126
+ }
127
+ async function gatherBomEntries(cwd) {
128
+ const [licensesEnv, depVulns] = await Promise.all([
129
+ (0, gather_1.gatherLicensesResult)(cwd),
130
+ (0, gather_2.gatherDepVulns)(cwd),
131
+ ]);
132
+ const licenseFindings = licensesEnv?.findings ?? [];
133
+ const vulnFindings = depVulns.findings;
134
+ // Index vulns by package@version (primary) and package (fallback).
135
+ const vulnByPkgVer = new Map();
136
+ const vulnByPkg = new Map();
137
+ for (const v of vulnFindings) {
138
+ if (v.installedVersion) {
139
+ const key = `${v.package}@${v.installedVersion}`;
140
+ const arr = vulnByPkgVer.get(key) ?? [];
141
+ arr.push(v);
142
+ vulnByPkgVer.set(key, arr);
143
+ }
144
+ const arr = vulnByPkg.get(v.package) ?? [];
145
+ arr.push(v);
146
+ vulnByPkg.set(v.package, arr);
147
+ }
148
+ const entries = [];
149
+ const matchedVulnKeys = new Set();
150
+ for (const lic of licenseFindings) {
151
+ const exactKey = `${lic.package}@${lic.version}`;
152
+ let attached = vulnByPkgVer.get(exactKey);
153
+ if (attached) {
154
+ matchedVulnKeys.add(exactKey);
155
+ }
156
+ else {
157
+ // Version-less vuln entries fall back to package-name match.
158
+ // Filter to only those that lacked installedVersion to avoid
159
+ // double-counting against other version rows.
160
+ const byPkg = vulnByPkg.get(lic.package) ?? [];
161
+ const versionless = byPkg.filter((v) => !v.installedVersion);
162
+ attached = versionless.length > 0 ? versionless : [];
163
+ }
164
+ entries.push(buildEntry(lic, attached, true));
165
+ }
166
+ // Vuln-only entries: vulns whose package@version did not match a
167
+ // license row AND whose package is absent from every license entry
168
+ // (versionless fallback is consumed above).
169
+ const licensePackages = new Set(licenseFindings.map((l) => l.package));
170
+ const vulnOnlyByPkgVer = new Map();
171
+ for (const [key, vulns] of vulnByPkgVer) {
172
+ if (matchedVulnKeys.has(key))
173
+ continue;
174
+ const pkg = vulns[0].package;
175
+ if (licensePackages.has(pkg))
176
+ continue; // already attached via versionless or other version
177
+ const arr = vulnOnlyByPkgVer.get(key) ?? [];
178
+ arr.push(...vulns);
179
+ vulnOnlyByPkgVer.set(key, arr);
180
+ }
181
+ for (const [, vulns] of vulnOnlyByPkgVer) {
182
+ const v0 = vulns[0];
183
+ const synthLicense = {
184
+ package: v0.package,
185
+ version: v0.installedVersion ?? 'unknown',
186
+ licenseType: 'UNKNOWN',
187
+ };
188
+ entries.push(buildEntry(synthLicense, vulns, false));
189
+ }
190
+ // Stable sort: package alphabetical, then version.
191
+ entries.sort((a, b) => a.package.localeCompare(b.package) || compareSemver(a.version, b.version));
192
+ const toolsUsed = new Set();
193
+ if (licensesEnv?.tool) {
194
+ for (const t of licensesEnv.tool.split(', '))
195
+ if (t)
196
+ toolsUsed.add(t);
197
+ }
198
+ if (depVulns.tool) {
199
+ for (const t of depVulns.tool.split(', '))
200
+ if (t)
201
+ toolsUsed.add(t);
202
+ }
203
+ return {
204
+ entries,
205
+ toolsUsed: [...toolsUsed],
206
+ toolsUnavailable: [],
207
+ };
208
+ }
209
+ function buildEntry(lic, vulns, joinedFromBoth) {
210
+ // Tier 2/4 fields on individual findings outrank Tier-1 derivation.
211
+ // Pick the first non-empty `upgradeAdvice` from any finding; fall
212
+ // back to derived advice when all vulns are Tier-1 only.
213
+ const tieredAdvice = vulns.map((v) => v.upgradeAdvice).find((a) => a && a.length > 0);
214
+ return {
215
+ package: lic.package,
216
+ version: lic.version,
217
+ licenseType: lic.licenseType,
218
+ licenseText: lic.licenseText,
219
+ sourceUrl: lic.sourceUrl,
220
+ description: lic.description,
221
+ supplier: lic.supplier,
222
+ releaseDate: lic.releaseDate,
223
+ vulns,
224
+ maxSeverity: maxSeverityOf(vulns),
225
+ upgradeAdvice: tieredAdvice ?? deriveTier1Resolution(vulns),
226
+ joinedFromBoth,
227
+ };
228
+ }
229
+ //# sourceMappingURL=gather.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gather.js","sourceRoot":"","sources":["../../../src/analyzers/bom/gather.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * BOM (Bill of Materials) analyzer — public API.
3
+ *
4
+ * Joins the LICENSES and DEP_VULNS capabilities by `package@version`
5
+ * to produce one row per installed package with both license inventory
6
+ * data (cols 1-9, 15) and per-package vulnerability rollup
7
+ * (cols 11-13). Output formats:
8
+ *
9
+ * - `formatBomReport(report)` — markdown summary for
10
+ * `.ai/reports/bom-<date>.md` and PR comments.
11
+ * - JSON via the CLI's `--json` flag (10h.3.9) — schema-versioned
12
+ * pass-through with the added summary + repo metadata.
13
+ * - XLSX via the shared converter (10h.3.9) — drop-in replacement
14
+ * for the customer's spreadsheet workflow with cols 11-13 filled.
15
+ */
16
+ import type { BomReport } from './types';
17
+ export type { BomReport, BomEntry } from './types';
18
+ export interface AnalyzeBomOptions {
19
+ verbose?: boolean;
20
+ }
21
+ export declare function analyzeBom(repoPath: string, _options?: AnalyzeBomOptions): Promise<BomReport>;
22
+ export declare function formatBomReport(report: BomReport, elapsed: string): string;
23
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/analyzers/bom/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAMH,OAAO,KAAK,EAAY,SAAS,EAAe,MAAM,SAAS,CAAC;AAEhE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnD,MAAM,WAAW,iBAAiB;IAChC,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,wBAAsB,UAAU,CAC9B,QAAQ,EAAE,MAAM,EAChB,QAAQ,GAAE,iBAAsB,GAC/B,OAAO,CAAC,SAAS,CAAC,CAsCpB;AASD,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CA8I1E"}
@@ -0,0 +1,220 @@
1
+ "use strict";
2
+ /**
3
+ * BOM (Bill of Materials) analyzer — public API.
4
+ *
5
+ * Joins the LICENSES and DEP_VULNS capabilities by `package@version`
6
+ * to produce one row per installed package with both license inventory
7
+ * data (cols 1-9, 15) and per-package vulnerability rollup
8
+ * (cols 11-13). Output formats:
9
+ *
10
+ * - `formatBomReport(report)` — markdown summary for
11
+ * `.ai/reports/bom-<date>.md` and PR comments.
12
+ * - JSON via the CLI's `--json` flag (10h.3.9) — schema-versioned
13
+ * pass-through with the added summary + repo metadata.
14
+ * - XLSX via the shared converter (10h.3.9) — drop-in replacement
15
+ * for the customer's spreadsheet workflow with cols 11-13 filled.
16
+ */
17
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ var desc = Object.getOwnPropertyDescriptor(m, k);
20
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
21
+ desc = { enumerable: true, get: function() { return m[k]; } };
22
+ }
23
+ Object.defineProperty(o, k2, desc);
24
+ }) : (function(o, m, k, k2) {
25
+ if (k2 === undefined) k2 = k;
26
+ o[k2] = m[k];
27
+ }));
28
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
29
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
30
+ }) : function(o, v) {
31
+ o["default"] = v;
32
+ });
33
+ var __importStar = (this && this.__importStar) || (function () {
34
+ var ownKeys = function(o) {
35
+ ownKeys = Object.getOwnPropertyNames || function (o) {
36
+ var ar = [];
37
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
38
+ return ar;
39
+ };
40
+ return ownKeys(o);
41
+ };
42
+ return function (mod) {
43
+ if (mod && mod.__esModule) return mod;
44
+ var result = {};
45
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
46
+ __setModuleDefault(result, mod);
47
+ return result;
48
+ };
49
+ })();
50
+ Object.defineProperty(exports, "__esModule", { value: true });
51
+ exports.analyzeBom = analyzeBom;
52
+ exports.formatBomReport = formatBomReport;
53
+ const path = __importStar(require("path"));
54
+ const detect_1 = require("../../detect");
55
+ const runner_1 = require("../tools/runner");
56
+ const gather_1 = require("./gather");
57
+ async function analyzeBom(repoPath, _options = {}) {
58
+ const stack = (0, detect_1.detect)(repoPath);
59
+ const { entries, toolsUsed, toolsUnavailable } = await (0, gather_1.gatherBomEntries)(repoPath);
60
+ const bySeverity = { critical: 0, high: 0, medium: 0, low: 0 };
61
+ let vulnerablePackages = 0;
62
+ let actionableVulns = 0;
63
+ let totalAdvisories = 0;
64
+ let vulnOnlyPackages = 0;
65
+ for (const e of entries) {
66
+ if (e.maxSeverity) {
67
+ bySeverity[e.maxSeverity]++;
68
+ vulnerablePackages++;
69
+ if (e.upgradeAdvice.startsWith('PROPOSAL:'))
70
+ actionableVulns++;
71
+ }
72
+ totalAdvisories += e.vulns.length;
73
+ if (!e.joinedFromBoth)
74
+ vulnOnlyPackages++;
75
+ }
76
+ return {
77
+ repo: stack.projectName || path.basename(repoPath),
78
+ analyzedAt: new Date().toISOString(),
79
+ commitSha: (0, runner_1.run)('git rev-parse --short HEAD 2>/dev/null', repoPath),
80
+ branch: (0, runner_1.run)('git rev-parse --abbrev-ref HEAD 2>/dev/null', repoPath),
81
+ schemaVersion: '1',
82
+ summary: {
83
+ totalPackages: entries.length,
84
+ bySeverity,
85
+ vulnerablePackages,
86
+ actionableVulns,
87
+ totalAdvisories,
88
+ vulnOnlyPackages,
89
+ byTopLevelDep: (0, gather_1.buildByTopLevelDep)(entries),
90
+ },
91
+ entries,
92
+ toolsUsed,
93
+ toolsUnavailable,
94
+ };
95
+ }
96
+ const SEV_BADGE = {
97
+ critical: 'CRITICAL',
98
+ high: 'HIGH',
99
+ medium: 'MEDIUM',
100
+ low: 'LOW',
101
+ };
102
+ function formatBomReport(report, elapsed) {
103
+ const L = [];
104
+ L.push('# Bill of Materials (BOM) Report');
105
+ L.push('');
106
+ L.push(`**Date:** ${report.analyzedAt.slice(0, 10)}`);
107
+ L.push(`**Repository:** ${report.repo}`);
108
+ L.push(`**Branch:** ${report.branch} (${report.commitSha})`);
109
+ L.push('');
110
+ L.push('---');
111
+ L.push('');
112
+ // Summary
113
+ const s = report.summary;
114
+ L.push('## Summary');
115
+ L.push('');
116
+ L.push(`**${s.totalPackages} packages** indexed across the active language pack(s).`);
117
+ L.push('');
118
+ if (s.vulnerablePackages > 0) {
119
+ L.push(`**${s.vulnerablePackages} packages** carry known vulnerabilities — ` +
120
+ `**${s.totalAdvisories} advisories** in total ` +
121
+ `(one package can have many advisories, e.g. multiple CVEs against ` +
122
+ `the same installed version). ` +
123
+ `**${s.actionableVulns}** of those packages have a Tier-1 upgrade proposal.`);
124
+ L.push('');
125
+ L.push(`> The numbers reconcile with \`vyuh-dxkit vulnerabilities\`: ` +
126
+ `that command reports per-advisory (${s.totalAdvisories}); bom collapses ` +
127
+ `them per-package (${s.vulnerablePackages}) so each row of the ` +
128
+ `xlsx is one upgrade decision.`);
129
+ L.push('');
130
+ L.push('| Severity (worst-of-package) | Vulnerable Packages |');
131
+ L.push('|-----------------------------|--------------------:|');
132
+ L.push(`| CRITICAL | ${s.bySeverity.critical} |`);
133
+ L.push(`| HIGH | ${s.bySeverity.high} |`);
134
+ L.push(`| MEDIUM | ${s.bySeverity.medium} |`);
135
+ L.push(`| LOW | ${s.bySeverity.low} |`);
136
+ L.push('');
137
+ }
138
+ if (s.vulnOnlyPackages > 0) {
139
+ L.push(`> ⚠️ ${s.vulnOnlyPackages} package(s) reported only by the vulnerability scanner — ` +
140
+ `the license scanner missed them (likely a workspace / sub-package). ` +
141
+ `These rows show "UNKNOWN" license; verify manually before shipping.`);
142
+ L.push('');
143
+ }
144
+ L.push('---');
145
+ L.push('');
146
+ // Snyk-style top-level dep rollup — upgrade-oriented view answering
147
+ // "which single `npm install X` / `go get Y` resolves the most
148
+ // advisories". Only rendered when at least one finding carried
149
+ // topLevelDep attribution (packs that can't parse a lockfile/graph
150
+ // simply don't populate it).
151
+ const topLevelEntries = Object.entries(s.byTopLevelDep);
152
+ if (topLevelEntries.length > 0) {
153
+ L.push('## Top-Level Dep Groups');
154
+ L.push('');
155
+ L.push('Grouped by direct manifest dep so each row is one upgrade decision. ' +
156
+ 'Sorted by severity, then advisory count — the top row is the single ' +
157
+ 'upgrade that resolves the most critical/highest-volume issues.');
158
+ L.push('');
159
+ const SEV_RANK = { critical: 0, high: 1, medium: 2, low: 3 };
160
+ const sorted = topLevelEntries.sort((a, b) => SEV_RANK[a[1].maxSeverity] - SEV_RANK[b[1].maxSeverity] ||
161
+ b[1].advisoryCount - a[1].advisoryCount ||
162
+ a[0].localeCompare(b[0]));
163
+ const cap = 30;
164
+ const shown = sorted.slice(0, cap);
165
+ L.push('| Worst Severity | Top-Level Dep | Advisories | Vulnerable Packages |');
166
+ L.push('|----------------|---------------|-----------:|---------------------|');
167
+ for (const [top, r] of shown) {
168
+ const pkgCap = 8;
169
+ const pkgList = r.packages.length > pkgCap
170
+ ? `${r.packages.slice(0, pkgCap).join(', ')}, +${r.packages.length - pkgCap} more`
171
+ : r.packages.join(', ');
172
+ L.push(`| ${SEV_BADGE[r.maxSeverity]} | \`${top}\` | ${r.advisoryCount} | ${pkgList} |`);
173
+ }
174
+ if (sorted.length > cap) {
175
+ L.push('');
176
+ L.push(`_Showing ${cap} of ${sorted.length} top-level deps with rolled-up advisories._`);
177
+ }
178
+ L.push('');
179
+ L.push('---');
180
+ L.push('');
181
+ }
182
+ // Vulnerable packages section — worst-first, one row per package
183
+ if (s.vulnerablePackages > 0) {
184
+ L.push('## Vulnerable Packages');
185
+ L.push('');
186
+ L.push('Sorted by severity (worst-first), then alphabetical. ');
187
+ L.push('Resolution column shows the Tier-1 derived upgrade target ');
188
+ L.push('(or "No fix available" when an advisory has no published patch).');
189
+ L.push('');
190
+ const SEV_RANK = { critical: 0, high: 1, medium: 2, low: 3 };
191
+ const vuln = report.entries
192
+ .filter((e) => e.maxSeverity)
193
+ .sort((a, b) => SEV_RANK[a.maxSeverity] - SEV_RANK[b.maxSeverity] || a.package.localeCompare(b.package));
194
+ const cap = 50;
195
+ const shown = vuln.slice(0, cap);
196
+ L.push('| Severity | Package@Version | License | # Vulns | Resolution |');
197
+ L.push('|----------|-----------------|---------|--------:|------------|');
198
+ for (const e of shown) {
199
+ const advice = e.upgradeAdvice.replace(/\|/g, '\\|');
200
+ L.push(`| ${SEV_BADGE[e.maxSeverity]} | \`${e.package}@${e.version}\` | ${e.licenseType} | ${e.vulns.length} | ${advice} |`);
201
+ }
202
+ if (vuln.length > cap) {
203
+ L.push('');
204
+ L.push(`_Showing ${cap} of ${vuln.length} vulnerable packages. Run with \`--detailed\` for the full inventory + per-advisory CVE list._`);
205
+ }
206
+ L.push('');
207
+ L.push('---');
208
+ L.push('');
209
+ }
210
+ // Footer
211
+ L.push(`**Tools used:** ${report.toolsUsed.join(', ') || '(none)'}`);
212
+ if (report.toolsUnavailable.length > 0) {
213
+ L.push(`**Tools unavailable:** ${report.toolsUnavailable.join(', ')}`);
214
+ }
215
+ L.push(`**Analysis time:** ${elapsed}s`);
216
+ L.push('');
217
+ L.push('*Generated by [VyuhLabs DXKit](https://www.npmjs.com/package/@vyuhlabs/dxkit)*');
218
+ return L.join('\n');
219
+ }
220
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/analyzers/bom/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * BOM (Bill of Materials) analyzer report shape.
3
+ *
4
+ * Joins the LICENSES and DEP_VULNS capabilities on (package, version)
5
+ * to produce one row per installed package with both the license
6
+ * inventory data the customer's spreadsheet needs (cols 1-9, 15) and
7
+ * the per-package vulnerability rollup (cols 11-13). Per-advisory
8
+ * detail stays attached to each row so the xlsx writer (10h.3.9)
9
+ * can render col 12 (Vulnerability Issues) as an enumerated list.
10
+ */
11
+ import type { DepVulnFinding } from '../../languages/capabilities/types';
12
+ export type BomSeverity = 'critical' | 'high' | 'medium' | 'low';
13
+ export interface BomEntry {
14
+ package: string;
15
+ version: string;
16
+ licenseType: string;
17
+ licenseText?: string;
18
+ sourceUrl?: string;
19
+ description?: string;
20
+ supplier?: string;
21
+ releaseDate?: string;
22
+ vulns: DepVulnFinding[];
23
+ /** Highest severity across `vulns`; null when the package has no
24
+ * known vulnerabilities. Drives col 11 "Criticality of usage". */
25
+ maxSeverity: BomSeverity | null;
26
+ /** Tier-1 resolution proposal derived from `vulns[].fixedVersion`
27
+ * at gather time. Empty string when no vulns. Drives col 13
28
+ * "Resolution". Higher tiers (10h.4 snyk, 10h.6 osv-scanner fix)
29
+ * may overwrite this in future commits. */
30
+ upgradeAdvice: string;
31
+ /** Whether the package was reported by both the licenses scanner
32
+ * AND a dep-vuln scanner. False = vuln-only entry (license scanner
33
+ * didn't see it), which usually indicates a workspace/sub-package
34
+ * the license tool missed; surfaced in the detailed report so the
35
+ * user can decide whether to trust the license=UNKNOWN row. */
36
+ joinedFromBoth: boolean;
37
+ }
38
+ /**
39
+ * Per-top-level-dep aggregation. A single advisory may roll up under
40
+ * multiple top-levels (e.g. lodash reachable from 20 loopback packages),
41
+ * in which case each top-level's `advisoryCount` increments by one.
42
+ * Matches Snyk's UI rollup: "@loopback/cli has 49 advisories".
43
+ */
44
+ export interface BomTopLevelRollup {
45
+ /** Total advisories rolled up under this top-level. */
46
+ advisoryCount: number;
47
+ /** Highest severity across all rolled-up advisories. */
48
+ maxSeverity: BomSeverity;
49
+ /** Distinct vulnerable package names reachable under this top-level.
50
+ * Rendered in markdown as a comma-joined list; cap in renderer. */
51
+ packages: string[];
52
+ }
53
+ export interface BomReport {
54
+ repo: string;
55
+ analyzedAt: string;
56
+ commitSha: string;
57
+ branch: string;
58
+ /** Bumps when the report shape changes incompatibly. */
59
+ schemaVersion: '1';
60
+ summary: {
61
+ totalPackages: number;
62
+ /** Per-severity package count (one increment per package's
63
+ * maxSeverity, not per advisory). Matches what bom xlsx
64
+ * col 11 will summarize. */
65
+ bySeverity: Record<BomSeverity, number>;
66
+ /** Number of packages with at least one known vulnerability.
67
+ * Note: a single package may carry many advisories — see
68
+ * totalAdvisories for the per-vuln count. */
69
+ vulnerablePackages: number;
70
+ /** Number of vulnerable packages where every vuln has a
71
+ * fixedVersion (Tier-1 upgrade proposal is actionable). */
72
+ actionableVulns: number;
73
+ /** Total advisories across every vulnerable package (each row's
74
+ * vulns.length, summed). Reconciles with the count surfaced by
75
+ * `vyuh-dxkit vulnerabilities` — that command shows one tick
76
+ * per advisory; bom shows one row per package. */
77
+ totalAdvisories: number;
78
+ /** Packages found only by a vuln scanner — license scanner
79
+ * missed them. See BomEntry.joinedFromBoth. */
80
+ vulnOnlyPackages: number;
81
+ /** Snyk-style upgrade-oriented grouping: per-top-level-dep rollup
82
+ * built from `vulns[].topLevelDep`. Empty when no findings carry
83
+ * topLevelDep attribution (e.g. pre-10h.4 packs or projects
84
+ * without a parseable dep graph). */
85
+ byTopLevelDep: Record<string, BomTopLevelRollup>;
86
+ };
87
+ entries: ReadonlyArray<BomEntry>;
88
+ toolsUsed: string[];
89
+ toolsUnavailable: string[];
90
+ }
91
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/analyzers/bom/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAEzE,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;AAEjE,MAAM,WAAW,QAAQ;IAEvB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAGhB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IAKrB,KAAK,EAAE,cAAc,EAAE,CAAC;IAExB;uEACmE;IACnE,WAAW,EAAE,WAAW,GAAG,IAAI,CAAC;IAEhC;;;gDAG4C;IAC5C,aAAa,EAAE,MAAM,CAAC;IAEtB;;;;oEAIgE;IAChE,cAAc,EAAE,OAAO,CAAC;CACzB;AAED;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,uDAAuD;IACvD,aAAa,EAAE,MAAM,CAAC;IACtB,wDAAwD;IACxD,WAAW,EAAE,WAAW,CAAC;IACzB;wEACoE;IACpE,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,aAAa,EAAE,GAAG,CAAC;IACnB,OAAO,EAAE;QACP,aAAa,EAAE,MAAM,CAAC;QACtB;;qCAE6B;QAC7B,UAAU,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QACxC;;sDAE8C;QAC9C,kBAAkB,EAAE,MAAM,CAAC;QAC3B;oEAC4D;QAC5D,eAAe,EAAE,MAAM,CAAC;QACxB;;;2DAGmD;QACnD,eAAe,EAAE,MAAM,CAAC;QACxB;wDACgD;QAChD,gBAAgB,EAAE,MAAM,CAAC;QACzB;;;8CAGsC;QACtC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;KAClD,CAAC;IACF,OAAO,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;IACjC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,gBAAgB,EAAE,MAAM,EAAE,CAAC;CAC5B"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/analyzers/bom/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Licenses analyzer — detailed report.
3
+ *
4
+ * Extends the base LicensesReport with risk-categorized findings and a
5
+ * ranked action list. Unlike security/test-gaps, licenses aren't
6
+ * graded — there's no "license score" — so actions are prioritized by
7
+ * legal risk tier (unknown → strong-copyleft → weak-copyleft →
8
+ * missing-attribution) rather than by projected score delta.
9
+ *
10
+ * Both the markdown formatter and the XLSX converter (Phase 10h.2.3)
11
+ * can consume this same `LicensesDetailedReport` shape.
12
+ */
13
+ import type { LicenseFinding } from '../../languages/capabilities/types';
14
+ import type { LicensesReport } from './types';
15
+ export interface LicenseRiskCategory {
16
+ /** Severity tier for ordering and display. */
17
+ readonly priority: 'critical' | 'high' | 'medium' | 'low';
18
+ /** Short category key — stable across runs for programmatic filtering. */
19
+ readonly id: 'unknown-license' | 'strong-copyleft' | 'weak-copyleft' | 'missing-license-text' | 'missing-supplier';
20
+ readonly title: string;
21
+ readonly rationale: string;
22
+ readonly recommendation: string;
23
+ readonly affected: ReadonlyArray<LicenseFinding>;
24
+ }
25
+ export interface LicensesDetailedReport extends LicensesReport {
26
+ riskCategories: ReadonlyArray<LicenseRiskCategory>;
27
+ }
28
+ export declare function buildLicensesDetailed(report: LicensesReport): LicensesDetailedReport;
29
+ export declare function formatLicensesDetailedMarkdown(detailed: LicensesDetailedReport, elapsed: string): string;
30
+ //# sourceMappingURL=detailed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detailed.d.ts","sourceRoot":"","sources":["../../../src/analyzers/licenses/detailed.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AA6B9C,MAAM,WAAW,mBAAmB;IAClC,8CAA8C;IAC9C,QAAQ,CAAC,QAAQ,EAAE,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IAC1D,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,EACP,iBAAiB,GACjB,iBAAiB,GACjB,eAAe,GACf,sBAAsB,GACtB,kBAAkB,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC,cAAc,CAAC,CAAC;CAClD;AAED,MAAM,WAAW,sBAAuB,SAAQ,cAAc;IAC5D,cAAc,EAAE,aAAa,CAAC,mBAAmB,CAAC,CAAC;CACpD;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,cAAc,GAAG,sBAAsB,CAwFpF;AASD,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE,sBAAsB,EAChC,OAAO,EAAE,MAAM,GACd,MAAM,CA4FR"}