@vyuhlabs/dxkit 2.1.0 → 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 (82) hide show
  1. package/CHANGELOG.md +92 -0
  2. package/README.md +9 -9
  3. package/dist/agents/extract.d.ts +25 -0
  4. package/dist/agents/extract.d.ts.map +1 -0
  5. package/dist/agents/extract.js +186 -0
  6. package/dist/agents/extract.js.map +1 -0
  7. package/dist/agents/schemas.d.ts +106 -0
  8. package/dist/agents/schemas.d.ts.map +1 -0
  9. package/dist/agents/schemas.js +86 -0
  10. package/dist/agents/schemas.js.map +1 -0
  11. package/dist/agents/session.d.ts +28 -0
  12. package/dist/agents/session.d.ts.map +1 -0
  13. package/dist/agents/session.js +223 -0
  14. package/dist/agents/session.js.map +1 -0
  15. package/dist/analyzers/bom/gather.d.ts +12 -1
  16. package/dist/analyzers/bom/gather.d.ts.map +1 -1
  17. package/dist/analyzers/bom/gather.js +46 -0
  18. package/dist/analyzers/bom/gather.js.map +1 -1
  19. package/dist/analyzers/bom/index.d.ts.map +1 -1
  20. package/dist/analyzers/bom/index.js +37 -0
  21. package/dist/analyzers/bom/index.js.map +1 -1
  22. package/dist/analyzers/bom/types.d.ts +20 -0
  23. package/dist/analyzers/bom/types.d.ts.map +1 -1
  24. package/dist/analyzers/index.d.ts +3 -0
  25. package/dist/analyzers/index.d.ts.map +1 -0
  26. package/dist/analyzers/index.js +6 -0
  27. package/dist/analyzers/index.js.map +1 -0
  28. package/dist/analyzers/security/report.d.ts +6 -0
  29. package/dist/analyzers/security/report.d.ts.map +1 -0
  30. package/dist/analyzers/security/report.js +118 -0
  31. package/dist/analyzers/security/report.js.map +1 -0
  32. package/dist/analyzers/tools/dotnet.d.ts +8 -0
  33. package/dist/analyzers/tools/dotnet.d.ts.map +1 -0
  34. package/dist/analyzers/tools/dotnet.js +81 -0
  35. package/dist/analyzers/tools/dotnet.js.map +1 -0
  36. package/dist/analyzers/tools/gather-cache.d.ts +16 -0
  37. package/dist/analyzers/tools/gather-cache.d.ts.map +1 -0
  38. package/dist/analyzers/tools/gather-cache.js +126 -0
  39. package/dist/analyzers/tools/gather-cache.js.map +1 -0
  40. package/dist/analyzers/tools/go.d.ts +8 -0
  41. package/dist/analyzers/tools/go.d.ts.map +1 -0
  42. package/dist/analyzers/tools/go.js +84 -0
  43. package/dist/analyzers/tools/go.js.map +1 -0
  44. package/dist/analyzers/tools/node.d.ts +8 -0
  45. package/dist/analyzers/tools/node.d.ts.map +1 -0
  46. package/dist/analyzers/tools/node.js +160 -0
  47. package/dist/analyzers/tools/node.js.map +1 -0
  48. package/dist/analyzers/tools/python.d.ts +8 -0
  49. package/dist/analyzers/tools/python.d.ts.map +1 -0
  50. package/dist/analyzers/tools/python.js +81 -0
  51. package/dist/analyzers/tools/python.js.map +1 -0
  52. package/dist/analyzers/tools/rust.d.ts +8 -0
  53. package/dist/analyzers/tools/rust.d.ts.map +1 -0
  54. package/dist/analyzers/tools/rust.js +86 -0
  55. package/dist/analyzers/tools/rust.js.map +1 -0
  56. package/dist/analyzers/xlsx/bom.d.ts.map +1 -1
  57. package/dist/analyzers/xlsx/bom.js +11 -1
  58. package/dist/analyzers/xlsx/bom.js.map +1 -1
  59. package/dist/languages/capabilities/types.d.ts +1 -0
  60. package/dist/languages/capabilities/types.d.ts.map +1 -1
  61. package/dist/languages/csharp.d.ts +41 -6
  62. package/dist/languages/csharp.d.ts.map +1 -1
  63. package/dist/languages/csharp.js +225 -35
  64. package/dist/languages/csharp.js.map +1 -1
  65. package/dist/languages/go.d.ts +35 -0
  66. package/dist/languages/go.d.ts.map +1 -1
  67. package/dist/languages/go.js +156 -0
  68. package/dist/languages/go.js.map +1 -1
  69. package/dist/languages/python.d.ts +49 -0
  70. package/dist/languages/python.d.ts.map +1 -1
  71. package/dist/languages/python.js +202 -17
  72. package/dist/languages/python.js.map +1 -1
  73. package/dist/languages/rust.d.ts +15 -0
  74. package/dist/languages/rust.d.ts.map +1 -1
  75. package/dist/languages/rust.js +93 -0
  76. package/dist/languages/rust.js.map +1 -1
  77. package/dist/languages/typescript.d.ts +17 -0
  78. package/dist/languages/typescript.d.ts.map +1 -1
  79. package/dist/languages/typescript.js +106 -0
  80. package/dist/languages/typescript.js.map +1 -1
  81. package/package.json +1 -1
  82. package/templates/.ai/templates/session-checkpoint-template.md +97 -0
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.gatherPythonMetrics = gatherPythonMetrics;
4
+ const runner_1 = require("./runner");
5
+ const tool_registry_1 = require("./tool-registry");
6
+ /** Gather Python-specific metrics. */
7
+ function gatherPythonMetrics(cwd) {
8
+ const metrics = {
9
+ toolsUsed: [],
10
+ toolsUnavailable: [],
11
+ };
12
+ // ruff (lint)
13
+ const ruff = (0, tool_registry_1.findTool)(tool_registry_1.TOOL_DEFS.ruff, cwd);
14
+ if (ruff.available && ruff.path) {
15
+ const raw = (0, runner_1.run)(`${ruff.path} check . --output-format json 2>/dev/null`, cwd, 60000);
16
+ if (raw) {
17
+ try {
18
+ const results = JSON.parse(raw);
19
+ if (Array.isArray(results)) {
20
+ // ruff doesn't distinguish error/warning by default — all are errors
21
+ metrics.lintErrors = results.length;
22
+ metrics.lintWarnings = 0;
23
+ metrics.lintTool = 'ruff';
24
+ metrics.toolsUsed.push('ruff');
25
+ }
26
+ }
27
+ catch {
28
+ metrics.toolsUnavailable.push('ruff (parse error)');
29
+ }
30
+ }
31
+ else {
32
+ // Empty output = no errors
33
+ metrics.lintErrors = 0;
34
+ metrics.lintWarnings = 0;
35
+ metrics.lintTool = 'ruff';
36
+ metrics.toolsUsed.push('ruff');
37
+ }
38
+ }
39
+ else {
40
+ metrics.toolsUnavailable.push('ruff');
41
+ }
42
+ // pip-audit (dependency vulnerabilities)
43
+ const pipAudit = (0, tool_registry_1.findTool)(tool_registry_1.TOOL_DEFS['pip-audit'], cwd);
44
+ if (pipAudit.available && pipAudit.path) {
45
+ const raw = (0, runner_1.run)(`${pipAudit.path} --format json 2>/dev/null`, cwd, 120000);
46
+ if (raw) {
47
+ try {
48
+ const data = JSON.parse(raw);
49
+ let medium = 0;
50
+ for (const dep of data.dependencies || []) {
51
+ // pip-audit doesn't provide severity — count all as medium
52
+ medium += (dep.vulns || []).length;
53
+ }
54
+ const critical = 0;
55
+ const high = 0;
56
+ const low = 0;
57
+ metrics.depVulnCritical = critical;
58
+ metrics.depVulnHigh = high;
59
+ metrics.depVulnMedium = medium;
60
+ metrics.depVulnLow = low;
61
+ metrics.depAuditTool = 'pip-audit';
62
+ metrics.toolsUsed.push('pip-audit');
63
+ }
64
+ catch {
65
+ metrics.toolsUnavailable.push('pip-audit (parse error)');
66
+ }
67
+ }
68
+ }
69
+ else {
70
+ metrics.toolsUnavailable.push('pip-audit');
71
+ }
72
+ // Test framework detection (don't run tests — just detect)
73
+ if ((0, runner_1.fileExists)(cwd, 'pytest.ini', 'conftest.py') || (0, runner_1.fileExists)(cwd, 'pyproject.toml')) {
74
+ const pyproject = (0, runner_1.run)('cat pyproject.toml 2>/dev/null', cwd);
75
+ if (pyproject?.includes('[tool.pytest') || (0, runner_1.fileExists)(cwd, 'pytest.ini', 'conftest.py')) {
76
+ metrics.testFramework = 'pytest';
77
+ }
78
+ }
79
+ return metrics;
80
+ }
81
+ //# sourceMappingURL=python.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"python.js","sourceRoot":"","sources":["../../../src/analyzers/tools/python.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Rust tool runner — clippy, cargo-audit.
3
+ * Layer 1: language-specific tools for Rust projects.
4
+ */
5
+ import { HealthMetrics } from '../types';
6
+ /** Gather Rust-specific metrics. */
7
+ export declare function gatherRustMetrics(cwd: string): Partial<HealthMetrics>;
8
+ //# sourceMappingURL=rust.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rust.d.ts","sourceRoot":"","sources":["../../../src/analyzers/tools/rust.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAoBzC,oCAAoC;AACpC,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CA0ErE"}
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.gatherRustMetrics = gatherRustMetrics;
4
+ const runner_1 = require("./runner");
5
+ const tool_registry_1 = require("./tool-registry");
6
+ /** Gather Rust-specific metrics. */
7
+ function gatherRustMetrics(cwd) {
8
+ const metrics = {
9
+ toolsUsed: [],
10
+ toolsUnavailable: [],
11
+ };
12
+ // clippy
13
+ const clippy = (0, tool_registry_1.findTool)(tool_registry_1.TOOL_DEFS.clippy, cwd);
14
+ if (clippy.available) {
15
+ const raw = (0, runner_1.run)('cargo clippy --message-format json 2>/dev/null', cwd, 120000);
16
+ if (raw) {
17
+ let errors = 0;
18
+ let warnings = 0;
19
+ for (const line of raw.split('\n')) {
20
+ if (!line.trim())
21
+ continue;
22
+ try {
23
+ const msg = JSON.parse(line);
24
+ if (msg.reason === 'compiler-message' && msg.message) {
25
+ if (msg.message.level === 'error')
26
+ errors++;
27
+ else if (msg.message.level === 'warning')
28
+ warnings++;
29
+ }
30
+ }
31
+ catch {
32
+ /* skip non-JSON lines */
33
+ }
34
+ }
35
+ metrics.lintErrors = errors;
36
+ metrics.lintWarnings = warnings;
37
+ metrics.lintTool = 'clippy';
38
+ metrics.toolsUsed.push('clippy');
39
+ }
40
+ }
41
+ else {
42
+ metrics.toolsUnavailable.push('clippy');
43
+ }
44
+ // cargo-audit
45
+ const audit = (0, tool_registry_1.findTool)(tool_registry_1.TOOL_DEFS['cargo-audit'], cwd);
46
+ if (audit.available && audit.path) {
47
+ const raw = (0, runner_1.run)(`${audit.path} audit --json 2>/dev/null`, cwd, 60000);
48
+ if (raw) {
49
+ try {
50
+ const data = JSON.parse(raw);
51
+ if (data.vulnerabilities) {
52
+ let critical = 0, high = 0, medium = 0, low = 0;
53
+ for (const v of data.vulnerabilities.list || []) {
54
+ const sev = v.advisory?.severity?.toLowerCase();
55
+ if (sev === 'critical')
56
+ critical++;
57
+ else if (sev === 'high')
58
+ high++;
59
+ else if (sev === 'medium')
60
+ medium++;
61
+ else
62
+ low++;
63
+ }
64
+ metrics.depVulnCritical = critical;
65
+ metrics.depVulnHigh = high;
66
+ metrics.depVulnMedium = medium;
67
+ metrics.depVulnLow = low;
68
+ metrics.depAuditTool = 'cargo-audit';
69
+ metrics.toolsUsed.push('cargo-audit');
70
+ }
71
+ }
72
+ catch {
73
+ metrics.toolsUnavailable.push('cargo-audit (parse error)');
74
+ }
75
+ }
76
+ }
77
+ else {
78
+ metrics.toolsUnavailable.push('cargo-audit');
79
+ }
80
+ // Test framework detection
81
+ if ((0, runner_1.fileExists)(cwd, 'Cargo.toml')) {
82
+ metrics.testFramework = 'cargo-test';
83
+ }
84
+ return metrics;
85
+ }
86
+ //# sourceMappingURL=rust.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rust.js","sourceRoot":"","sources":["../../../src/analyzers/tools/rust.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"bom.d.ts","sourceRoot":"","sources":["../../../src/analyzers/xlsx/bom.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAe,MAAM,cAAc,CAAC;AAqC3D;;;;GAIG;AACH,wBAAsB,SAAS,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CA0ElE"}
1
+ {"version":3,"file":"bom.d.ts","sourceRoot":"","sources":["../../../src/analyzers/xlsx/bom.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAe,MAAM,cAAc,CAAC;AAqC3D;;;;GAIG;AACH,wBAAsB,SAAS,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAkFlE"}
@@ -95,7 +95,17 @@ async function toBomXlsx(report) {
95
95
  const vulnLines = sortedVulns.map((v) => {
96
96
  const title = (v.summary ?? '').replace(/\s+/g, ' ').trim().slice(0, ADVISORY_SUMMARY_MAX);
97
97
  const cvss = v.cvssScore !== undefined ? ` [CVSS ${v.cvssScore.toFixed(1)}]` : '';
98
- return title ? `${v.id}${cvss}: ${title}` : `${v.id}${cvss}`;
98
+ // Top-level attribution: tells the reviewer which direct manifest
99
+ // dep to upgrade. Missing when the pack couldn't parse the graph
100
+ // (e.g. TS repo with no lockfile) — silent in that case so the
101
+ // column stays clean.
102
+ const tops = v.topLevelDep ?? [];
103
+ let via = '';
104
+ if (tops.length === 1)
105
+ via = ` via ${tops[0]}`;
106
+ else if (tops.length > 1)
107
+ via = ` via ${tops[0]} (+${tops.length - 1} more)`;
108
+ return title ? `${v.id}${cvss}${via}: ${title}` : `${v.id}${cvss}${via}`;
99
109
  });
100
110
  const vulnerabilityIssues = e.vulns.length === 0 ? NO_VULNS_ISSUES : vulnLines.join('; ');
101
111
  const resolution = e.vulns.length === 0 ? NO_VULNS_RESOLUTION : e.upgradeAdvice;
@@ -1 +1 @@
1
- {"version":3,"file":"bom.js","sourceRoot":"","sources":["../../../src/analyzers/xlsx/bom.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bom.js","sourceRoot":"","sources":["../../../src/analyzers/xlsx/bom.ts"],"names":[],"mappings":"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"}
@@ -69,6 +69,7 @@ export interface DepVulnFinding {
69
69
  aliases?: string[];
70
70
  summary?: string;
71
71
  references?: string[];
72
+ topLevelDep?: string[];
72
73
  }
73
74
  /** Dependency vulnerabilities, the depVulns capability. */
74
75
  export interface DepVulnResult extends CapabilityEnvelope {
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/languages/capabilities/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/languages/capabilities/types.ts"],"names":[],"mappings":"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"}
@@ -3,17 +3,52 @@ import type { DepVulnFinding, SeverityCounts } from './capabilities/types';
3
3
  import type { LanguageSupport } from './types';
4
4
  export declare function parseCoberturaXml(raw: string, sourceFile: string, cwd: string): Coverage | null;
5
5
  /**
6
- * Pure parser for `dotnet list package --vulnerable --format json`.
7
- * Extracted from the gather function so it can be unit-tested without
8
- * a real .NET SDK on the dev machine (10h.5 release-time validation
9
- * runs the full pipeline). Returns null when the input is malformed;
10
- * otherwise returns counts + findings ready for downstream alias
11
- * enrichment.
6
+ * Pure parser for `dotnet list package --vulnerable --include-transitive
7
+ * --format json`. Extracted from the gather function so it can be
8
+ * unit-tested without a real .NET SDK on the dev machine (10h.5
9
+ * release-time validation runs the full pipeline). Returns null when
10
+ * the input is malformed; otherwise returns counts + findings ready
11
+ * for downstream alias enrichment + top-level attribution.
12
+ *
13
+ * Both top-level and transitive packages are iterated. Top-level
14
+ * findings carry `topLevelDep = [self]` (they ARE manifest deps);
15
+ * transitive findings emit with `topLevelDep` unset — the gather
16
+ * function then fills it from `project.assets.json` if available.
17
+ * Leaving attribution unset on transitives when assets.json is absent
18
+ * matches Python's venv-missing behavior: degrade gracefully rather
19
+ * than invent false parents.
12
20
  */
13
21
  export declare function parseDotnetVulnerableOutput(raw: string): {
14
22
  counts: SeverityCounts;
15
23
  findings: DepVulnFinding[];
16
24
  } | null;
25
+ /**
26
+ * Pure parser for `obj/project.assets.json`. Extracts the forward
27
+ * dep graph keyed by package name (collapsing versions — same as
28
+ * TS/Go/Rust packs) plus the set of top-level (direct manifest)
29
+ * package names across every target framework declared in `project`.
30
+ *
31
+ * Multi-framework projects: graphs are merged across target
32
+ * frameworks into a single name-level edge map. Top-level set is
33
+ * the union of declared direct deps across frameworks. This
34
+ * over-attributes slightly if a package is direct in netstandard2.0
35
+ * but transitive in net8.0 — it gets listed as a top-level — but the
36
+ * simplification beats per-framework multi-reporting complexity.
37
+ */
38
+ export declare function parseProjectAssetsJson(raw: string): {
39
+ topLevels: string[];
40
+ edges: Map<string, Set<string>>;
41
+ } | null;
42
+ /**
43
+ * BFS the parsed asset graph to produce a per-package-name index of
44
+ * its top-level ancestors. Mirrors `buildTsTopLevelDepIndex` /
45
+ * `buildRustTopLevelDepIndex` in shape and semantics; attribution is
46
+ * coarse (name-level) and unions across multiple reachable parents.
47
+ */
48
+ export declare function buildCsharpTopLevelDepIndex(parsed: {
49
+ topLevels: ReadonlyArray<string>;
50
+ edges: ReadonlyMap<string, ReadonlySet<string>>;
51
+ }): Map<string, string[]>;
17
52
  /**
18
53
  * Capture C# `using` directives from source text, including
19
54
  * `using static Foo`, aliased (`using X = Foo.Bar`), and plain forms.
@@ -1 +1 @@
1
- {"version":3,"file":"csharp.d.ts","sourceRoot":"","sources":["../../src/languages/csharp.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAgB,MAAM,6BAA6B,CAAC;AAM1E,OAAO,KAAK,EAEV,cAAc,EAQd,cAAc,EAEf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAwD/C,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAoC/F;AAkED;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CACzC,GAAG,EAAE,MAAM,GACV;IAAE,MAAM,EAAE,cAAc,CAAC;IAAC,QAAQ,EAAE,cAAc,EAAE,CAAA;CAAE,GAAG,IAAI,CA4C/D;AAoJD;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAQjE;AAsKD,eAAO,MAAM,MAAM,EAAE,eAsCpB,CAAC"}
1
+ {"version":3,"file":"csharp.d.ts","sourceRoot":"","sources":["../../src/languages/csharp.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAgB,MAAM,6BAA6B,CAAC;AAM1E,OAAO,KAAK,EAEV,cAAc,EAQd,cAAc,EAEf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAwD/C,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAoC/F;AAuGD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,2BAA2B,CACzC,GAAG,EAAE,MAAM,GACV;IAAE,MAAM,EAAE,cAAc,CAAC;IAAC,QAAQ,EAAE,cAAc,EAAE,CAAA;CAAE,GAAG,IAAI,CA0D/D;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,MAAM,GACV;IAAE,SAAS,EAAE,MAAM,EAAE,CAAC;IAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAA;CAAE,GAAG,IAAI,CAqCjE;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE;IAClD,SAAS,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACjC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;CACjD,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAsBxB;AAgPD;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAQjE;AAsKD,eAAO,MAAM,MAAM,EAAE,eAsCpB,CAAC"}
@@ -36,6 +36,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.csharp = void 0;
37
37
  exports.parseCoberturaXml = parseCoberturaXml;
38
38
  exports.parseDotnetVulnerableOutput = parseDotnetVulnerableOutput;
39
+ exports.parseProjectAssetsJson = parseProjectAssetsJson;
40
+ exports.buildCsharpTopLevelDepIndex = buildCsharpTopLevelDepIndex;
39
41
  exports.extractCsharpImportsRaw = extractCsharpImportsRaw;
40
42
  const fs = __importStar(require("fs"));
41
43
  const path = __importStar(require("path"));
@@ -168,12 +170,20 @@ function extractGhsaIdFromUrl(url) {
168
170
  return m ? m[0].toUpperCase() : null;
169
171
  }
170
172
  /**
171
- * Pure parser for `dotnet list package --vulnerable --format json`.
172
- * Extracted from the gather function so it can be unit-tested without
173
- * a real .NET SDK on the dev machine (10h.5 release-time validation
174
- * runs the full pipeline). Returns null when the input is malformed;
175
- * otherwise returns counts + findings ready for downstream alias
176
- * enrichment.
173
+ * Pure parser for `dotnet list package --vulnerable --include-transitive
174
+ * --format json`. Extracted from the gather function so it can be
175
+ * unit-tested without a real .NET SDK on the dev machine (10h.5
176
+ * release-time validation runs the full pipeline). Returns null when
177
+ * the input is malformed; otherwise returns counts + findings ready
178
+ * for downstream alias enrichment + top-level attribution.
179
+ *
180
+ * Both top-level and transitive packages are iterated. Top-level
181
+ * findings carry `topLevelDep = [self]` (they ARE manifest deps);
182
+ * transitive findings emit with `topLevelDep` unset — the gather
183
+ * function then fills it from `project.assets.json` if available.
184
+ * Leaving attribution unset on transitives when assets.json is absent
185
+ * matches Python's venv-missing behavior: degrade gracefully rather
186
+ * than invent false parents.
177
187
  */
178
188
  function parseDotnetVulnerableOutput(raw) {
179
189
  let data;
@@ -188,44 +198,202 @@ function parseDotnetVulnerableOutput(raw) {
188
198
  let medium = 0;
189
199
  let low = 0;
190
200
  const findings = [];
201
+ const emit = (pkgId, resolvedVersion, advisories, topLevelDep) => {
202
+ for (const adv of advisories) {
203
+ const severity = normalizeDotnetSeverity(adv.severity);
204
+ if (severity === 'critical')
205
+ critical++;
206
+ else if (severity === 'high')
207
+ high++;
208
+ else if (severity === 'medium')
209
+ medium++;
210
+ else
211
+ low++;
212
+ const ghsa = extractGhsaIdFromUrl(adv.advisoryUrl);
213
+ const id = ghsa ?? `nuget-${pkgId}@${resolvedVersion ?? 'unknown'}`;
214
+ const finding = {
215
+ id,
216
+ package: pkgId,
217
+ installedVersion: resolvedVersion,
218
+ tool: 'dotnet-vulnerable',
219
+ severity,
220
+ };
221
+ if (topLevelDep && topLevelDep.length > 0)
222
+ finding.topLevelDep = topLevelDep;
223
+ if (ghsa)
224
+ finding.aliases = [ghsa];
225
+ if (adv.advisoryUrl)
226
+ finding.references = [adv.advisoryUrl];
227
+ findings.push(finding);
228
+ }
229
+ };
191
230
  for (const proj of data.projects ?? []) {
192
231
  for (const fw of proj.frameworks ?? []) {
193
232
  for (const pkg of fw.topLevelPackages ?? []) {
194
233
  if (!pkg.id)
195
234
  continue;
196
- for (const adv of pkg.advisories ?? []) {
197
- const severity = normalizeDotnetSeverity(adv.severity);
198
- if (severity === 'critical')
199
- critical++;
200
- else if (severity === 'high')
201
- high++;
202
- else if (severity === 'medium')
203
- medium++;
204
- else
205
- low++;
206
- const ghsa = extractGhsaIdFromUrl(adv.advisoryUrl);
207
- // No GHSA URL means we have nothing addressable — fall back
208
- // to a synthetic id so the finding is still emitted (the
209
- // counts already incremented, and bom render needs a row).
210
- const id = ghsa ?? `nuget-${pkg.id}@${pkg.resolvedVersion ?? 'unknown'}`;
211
- const finding = {
212
- id,
213
- package: pkg.id,
214
- installedVersion: pkg.resolvedVersion,
215
- tool: 'dotnet-vulnerable',
216
- severity,
217
- };
218
- if (ghsa)
219
- finding.aliases = [ghsa];
220
- if (adv.advisoryUrl)
221
- finding.references = [adv.advisoryUrl];
222
- findings.push(finding);
223
- }
235
+ emit(pkg.id, pkg.resolvedVersion, pkg.advisories ?? [], [pkg.id]);
236
+ }
237
+ for (const pkg of fw.transitivePackages ?? []) {
238
+ if (!pkg.id)
239
+ continue;
240
+ // topLevelDep stays unset; `attachCsharpTopLevelAttribution`
241
+ // downstream fills it from project.assets.json when available.
242
+ emit(pkg.id, pkg.resolvedVersion, pkg.advisories ?? [], undefined);
224
243
  }
225
244
  }
226
245
  }
227
246
  return { counts: { critical, high, medium, low }, findings };
228
247
  }
248
+ /**
249
+ * Pure parser for `obj/project.assets.json`. Extracts the forward
250
+ * dep graph keyed by package name (collapsing versions — same as
251
+ * TS/Go/Rust packs) plus the set of top-level (direct manifest)
252
+ * package names across every target framework declared in `project`.
253
+ *
254
+ * Multi-framework projects: graphs are merged across target
255
+ * frameworks into a single name-level edge map. Top-level set is
256
+ * the union of declared direct deps across frameworks. This
257
+ * over-attributes slightly if a package is direct in netstandard2.0
258
+ * but transitive in net8.0 — it gets listed as a top-level — but the
259
+ * simplification beats per-framework multi-reporting complexity.
260
+ */
261
+ function parseProjectAssetsJson(raw) {
262
+ let data;
263
+ try {
264
+ data = JSON.parse(raw);
265
+ }
266
+ catch {
267
+ return null;
268
+ }
269
+ if (!data.targets && !data.project)
270
+ return null;
271
+ const nameOf = (key) => {
272
+ // Keys are `Pkg/Version` — split on '/' and take the package part.
273
+ const slash = key.indexOf('/');
274
+ return slash < 0 ? key : key.slice(0, slash);
275
+ };
276
+ const edges = new Map();
277
+ for (const target of Object.values(data.targets ?? {})) {
278
+ for (const [pkgVerKey, pkgEntry] of Object.entries(target)) {
279
+ const srcName = nameOf(pkgVerKey);
280
+ const deps = pkgEntry?.dependencies;
281
+ if (!deps)
282
+ continue;
283
+ const bucket = edges.get(srcName) ?? new Set();
284
+ for (const depName of Object.keys(deps)) {
285
+ bucket.add(depName);
286
+ }
287
+ edges.set(srcName, bucket);
288
+ }
289
+ }
290
+ const topLevels = new Set();
291
+ for (const fw of Object.values(data.project?.frameworks ?? {})) {
292
+ for (const name of Object.keys(fw?.dependencies ?? {})) {
293
+ topLevels.add(name);
294
+ }
295
+ }
296
+ return { topLevels: [...topLevels].sort(), edges };
297
+ }
298
+ /**
299
+ * BFS the parsed asset graph to produce a per-package-name index of
300
+ * its top-level ancestors. Mirrors `buildTsTopLevelDepIndex` /
301
+ * `buildRustTopLevelDepIndex` in shape and semantics; attribution is
302
+ * coarse (name-level) and unions across multiple reachable parents.
303
+ */
304
+ function buildCsharpTopLevelDepIndex(parsed) {
305
+ const result = new Map();
306
+ for (const top of parsed.topLevels) {
307
+ const visited = new Set();
308
+ const queue = [top];
309
+ while (queue.length > 0) {
310
+ const name = queue.shift();
311
+ if (visited.has(name))
312
+ continue;
313
+ visited.add(name);
314
+ const bucket = result.get(name) ?? new Set();
315
+ bucket.add(top);
316
+ result.set(name, bucket);
317
+ for (const child of parsed.edges.get(name) ?? []) {
318
+ if (!visited.has(child))
319
+ queue.push(child);
320
+ }
321
+ }
322
+ }
323
+ const sorted = new Map();
324
+ for (const [name, parents] of result) {
325
+ sorted.set(name, [...parents].sort());
326
+ }
327
+ return sorted;
328
+ }
329
+ /**
330
+ * Locate the nearest `obj/project.assets.json` under cwd (NuGet's
331
+ * lockfile equivalent, created by `dotnet restore`). Unlike the
332
+ * shared `findMatchingRecursive`, we cannot skip `obj/` here —
333
+ * that's literally where the file lives. Walks up to 4 levels deep
334
+ * to handle solutions with nested projects. Returns the absolute
335
+ * path of the first match, or null.
336
+ *
337
+ * Multi-project solutions currently use the first-found file's
338
+ * graph — noted as a known limitation in the phase commit.
339
+ */
340
+ function findProjectAssetsJson(cwd, maxDepth = 4) {
341
+ function search(dir, depth) {
342
+ if (depth > maxDepth)
343
+ return null;
344
+ let entries;
345
+ try {
346
+ entries = fs.readdirSync(dir, { withFileTypes: true });
347
+ }
348
+ catch {
349
+ return null;
350
+ }
351
+ // Direct-child shortcut: if this directory is `obj`, check for
352
+ // the file right here before recursing.
353
+ for (const e of entries) {
354
+ if (e.isFile() && e.name === 'project.assets.json') {
355
+ // Only accept if parent directory is `obj`.
356
+ if (path.basename(dir) === 'obj')
357
+ return path.join(dir, e.name);
358
+ }
359
+ }
360
+ for (const e of entries) {
361
+ if (e.name.startsWith('.') ||
362
+ ['node_modules', 'bin', 'TestResults', 'packages'].includes(e.name)) {
363
+ continue;
364
+ }
365
+ if (e.isDirectory()) {
366
+ const nested = search(path.join(dir, e.name), depth + 1);
367
+ if (nested)
368
+ return nested;
369
+ }
370
+ }
371
+ return null;
372
+ }
373
+ return search(cwd, 0);
374
+ }
375
+ /**
376
+ * Read + parse `obj/project.assets.json` and build the top-level
377
+ * attribution index. Returns an empty map on any failure — transitive
378
+ * findings simply ship without attribution rather than blocking the
379
+ * scan. Matches Python pack's missing-venv semantics.
380
+ */
381
+ function loadCsharpTopLevelDepIndex(cwd) {
382
+ const assetsPath = findProjectAssetsJson(cwd);
383
+ if (!assetsPath)
384
+ return new Map();
385
+ let raw;
386
+ try {
387
+ raw = fs.readFileSync(assetsPath, 'utf-8');
388
+ }
389
+ catch {
390
+ return new Map();
391
+ }
392
+ const parsed = parseProjectAssetsJson(raw);
393
+ if (!parsed)
394
+ return new Map();
395
+ return buildCsharpTopLevelDepIndex(parsed);
396
+ }
229
397
  /**
230
398
  * Single source of truth for the csharp pack's dep-vuln gathering.
231
399
  * Consumed by `csharpDepVulnsProvider` (capability dispatcher). Runs
@@ -240,13 +408,35 @@ function parseDotnetVulnerableOutput(raw) {
240
408
  async function gatherCsharpDepVulnsResult(cwd) {
241
409
  if (!hasCsharpProject(cwd))
242
410
  return { kind: 'tool-missing' };
243
- const vulnRaw = (0, runner_1.run)('dotnet list package --vulnerable --format json 2>/dev/null', cwd, 120000);
411
+ // `--include-transitive` (10h.4.4.c) extends the scan to indirect
412
+ // deps; without it NuGet would only report vulns where the
413
+ // vulnerable package is itself declared in .csproj. Transitive
414
+ // attribution lands via `project.assets.json` below.
415
+ const vulnRaw = (0, runner_1.run)('dotnet list package --vulnerable --include-transitive --format json 2>/dev/null', cwd, 120000);
244
416
  if (!vulnRaw)
245
417
  return { kind: 'no-output' };
246
418
  const parsed = parseDotnetVulnerableOutput(vulnRaw);
247
419
  if (!parsed)
248
420
  return { kind: 'parse-error' };
249
421
  const { counts, findings } = parsed;
422
+ // Attach top-level attribution to transitive findings (top-level
423
+ // findings already carry self-attribution from the parser). Skipped
424
+ // when project.assets.json is absent — user hasn't run
425
+ // `dotnet restore`, or the obj/ dir was cleaned. Findings ship with
426
+ // `topLevelDep` unset in that case, matching Python's no-venv path.
427
+ const transitiveNeedsAttribution = findings.some((f) => !f.topLevelDep || f.topLevelDep.length === 0);
428
+ if (transitiveNeedsAttribution) {
429
+ const topLevelIndex = loadCsharpTopLevelDepIndex(cwd);
430
+ if (topLevelIndex.size > 0) {
431
+ for (const f of findings) {
432
+ if (f.topLevelDep && f.topLevelDep.length > 0)
433
+ continue;
434
+ const parents = topLevelIndex.get(f.package);
435
+ if (parents && parents.length > 0)
436
+ f.topLevelDep = parents;
437
+ }
438
+ }
439
+ }
250
440
  // Alias-fallback CVSS pass: dotnet --vulnerable ships zero CVSS data
251
441
  // per advisory; the GHSA id (extracted from advisoryUrl) is the only
252
442
  // anchor. resolveCvssScores looks up via GHSA → CVE alias chain.