@vyuhlabs/dxkit 1.5.0 → 1.6.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 (258) hide show
  1. package/CHANGELOG.md +272 -0
  2. package/README.md +272 -358
  3. package/THIRD_PARTY_NOTICES.md +40 -0
  4. package/dist/analyzers/developer/detailed.d.ts +26 -0
  5. package/dist/analyzers/developer/detailed.d.ts.map +1 -0
  6. package/dist/analyzers/developer/detailed.js +193 -0
  7. package/dist/analyzers/developer/detailed.js.map +1 -0
  8. package/dist/analyzers/developer/gather.d.ts +11 -0
  9. package/dist/analyzers/developer/gather.d.ts.map +1 -0
  10. package/dist/analyzers/developer/gather.js +167 -0
  11. package/dist/analyzers/developer/gather.js.map +1 -0
  12. package/dist/analyzers/developer/index.d.ts +8 -0
  13. package/dist/analyzers/developer/index.d.ts.map +1 -0
  14. package/dist/analyzers/developer/index.js +168 -0
  15. package/dist/analyzers/developer/index.js.map +1 -0
  16. package/dist/analyzers/developer/types.d.ts +49 -0
  17. package/dist/analyzers/developer/types.d.ts.map +1 -0
  18. package/dist/analyzers/developer/types.js +6 -0
  19. package/dist/analyzers/developer/types.js.map +1 -0
  20. package/dist/analyzers/docs/shallow.d.ts +9 -0
  21. package/dist/analyzers/docs/shallow.d.ts.map +1 -0
  22. package/dist/analyzers/docs/shallow.js +8 -0
  23. package/dist/analyzers/docs/shallow.js.map +1 -0
  24. package/dist/analyzers/dx/shallow.d.ts +9 -0
  25. package/dist/analyzers/dx/shallow.d.ts.map +1 -0
  26. package/dist/analyzers/dx/shallow.js +8 -0
  27. package/dist/analyzers/dx/shallow.js.map +1 -0
  28. package/dist/analyzers/evidence.d.ts +36 -0
  29. package/dist/analyzers/evidence.d.ts.map +1 -0
  30. package/dist/analyzers/evidence.js +3 -0
  31. package/dist/analyzers/evidence.js.map +1 -0
  32. package/dist/analyzers/health/actions.d.ts +10 -0
  33. package/dist/analyzers/health/actions.d.ts.map +1 -0
  34. package/dist/analyzers/health/actions.js +284 -0
  35. package/dist/analyzers/health/actions.js.map +1 -0
  36. package/dist/analyzers/health/detailed.d.ts +26 -0
  37. package/dist/analyzers/health/detailed.d.ts.map +1 -0
  38. package/dist/analyzers/health/detailed.js +147 -0
  39. package/dist/analyzers/health/detailed.js.map +1 -0
  40. package/dist/analyzers/health.d.ts +22 -0
  41. package/dist/analyzers/health.d.ts.map +1 -0
  42. package/dist/analyzers/health.js +270 -0
  43. package/dist/analyzers/health.js.map +1 -0
  44. package/dist/analyzers/index.d.ts +3 -0
  45. package/dist/analyzers/index.d.ts.map +1 -0
  46. package/dist/analyzers/index.js +6 -0
  47. package/dist/analyzers/index.js.map +1 -0
  48. package/dist/analyzers/maintainability/shallow.d.ts +9 -0
  49. package/dist/analyzers/maintainability/shallow.d.ts.map +1 -0
  50. package/dist/analyzers/maintainability/shallow.js +8 -0
  51. package/dist/analyzers/maintainability/shallow.js.map +1 -0
  52. package/dist/analyzers/quality/actions.d.ts +5 -0
  53. package/dist/analyzers/quality/actions.d.ts.map +1 -0
  54. package/dist/analyzers/quality/actions.js +158 -0
  55. package/dist/analyzers/quality/actions.js.map +1 -0
  56. package/dist/analyzers/quality/detailed.d.ts +17 -0
  57. package/dist/analyzers/quality/detailed.d.ts.map +1 -0
  58. package/dist/analyzers/quality/detailed.js +122 -0
  59. package/dist/analyzers/quality/detailed.js.map +1 -0
  60. package/dist/analyzers/quality/gather.d.ts +38 -0
  61. package/dist/analyzers/quality/gather.d.ts.map +1 -0
  62. package/dist/analyzers/quality/gather.js +279 -0
  63. package/dist/analyzers/quality/gather.js.map +1 -0
  64. package/dist/analyzers/quality/index.d.ts +12 -0
  65. package/dist/analyzers/quality/index.d.ts.map +1 -0
  66. package/dist/analyzers/quality/index.js +281 -0
  67. package/dist/analyzers/quality/index.js.map +1 -0
  68. package/dist/analyzers/quality/shallow.d.ts +9 -0
  69. package/dist/analyzers/quality/shallow.d.ts.map +1 -0
  70. package/dist/analyzers/quality/shallow.js +8 -0
  71. package/dist/analyzers/quality/shallow.js.map +1 -0
  72. package/dist/analyzers/quality/types.d.ts +66 -0
  73. package/dist/analyzers/quality/types.d.ts.map +1 -0
  74. package/dist/analyzers/quality/types.js +3 -0
  75. package/dist/analyzers/quality/types.js.map +1 -0
  76. package/dist/analyzers/remediation.d.ts +42 -0
  77. package/dist/analyzers/remediation.d.ts.map +1 -0
  78. package/dist/analyzers/remediation.js +28 -0
  79. package/dist/analyzers/remediation.js.map +1 -0
  80. package/dist/analyzers/scoring.d.ts +32 -0
  81. package/dist/analyzers/scoring.d.ts.map +1 -0
  82. package/dist/analyzers/scoring.js +410 -0
  83. package/dist/analyzers/scoring.js.map +1 -0
  84. package/dist/analyzers/security/actions.d.ts +7 -0
  85. package/dist/analyzers/security/actions.d.ts.map +1 -0
  86. package/dist/analyzers/security/actions.js +104 -0
  87. package/dist/analyzers/security/actions.js.map +1 -0
  88. package/dist/analyzers/security/detailed.d.ts +14 -0
  89. package/dist/analyzers/security/detailed.d.ts.map +1 -0
  90. package/dist/analyzers/security/detailed.js +124 -0
  91. package/dist/analyzers/security/detailed.js.map +1 -0
  92. package/dist/analyzers/security/gather.d.ts +12 -0
  93. package/dist/analyzers/security/gather.d.ts.map +1 -0
  94. package/dist/analyzers/security/gather.js +195 -0
  95. package/dist/analyzers/security/gather.js.map +1 -0
  96. package/dist/analyzers/security/index.d.ts +8 -0
  97. package/dist/analyzers/security/index.d.ts.map +1 -0
  98. package/dist/analyzers/security/index.js +173 -0
  99. package/dist/analyzers/security/index.js.map +1 -0
  100. package/dist/analyzers/security/scoring.d.ts +29 -0
  101. package/dist/analyzers/security/scoring.d.ts.map +1 -0
  102. package/dist/analyzers/security/scoring.js +40 -0
  103. package/dist/analyzers/security/scoring.js.map +1 -0
  104. package/dist/analyzers/security/shallow.d.ts +10 -0
  105. package/dist/analyzers/security/shallow.d.ts.map +1 -0
  106. package/dist/analyzers/security/shallow.js +8 -0
  107. package/dist/analyzers/security/shallow.js.map +1 -0
  108. package/dist/analyzers/security/types.d.ts +43 -0
  109. package/dist/analyzers/security/types.d.ts.map +1 -0
  110. package/dist/analyzers/security/types.js +6 -0
  111. package/dist/analyzers/security/types.js.map +1 -0
  112. package/dist/analyzers/tests/actions.d.ts +6 -0
  113. package/dist/analyzers/tests/actions.d.ts.map +1 -0
  114. package/dist/analyzers/tests/actions.js +80 -0
  115. package/dist/analyzers/tests/actions.js.map +1 -0
  116. package/dist/analyzers/tests/detailed.d.ts +14 -0
  117. package/dist/analyzers/tests/detailed.d.ts.map +1 -0
  118. package/dist/analyzers/tests/detailed.js +121 -0
  119. package/dist/analyzers/tests/detailed.js.map +1 -0
  120. package/dist/analyzers/tests/gather.d.ts +5 -0
  121. package/dist/analyzers/tests/gather.d.ts.map +1 -0
  122. package/dist/analyzers/tests/gather.js +270 -0
  123. package/dist/analyzers/tests/gather.js.map +1 -0
  124. package/dist/analyzers/tests/import-graph.d.ts +48 -0
  125. package/dist/analyzers/tests/import-graph.d.ts.map +1 -0
  126. package/dist/analyzers/tests/import-graph.js +231 -0
  127. package/dist/analyzers/tests/import-graph.js.map +1 -0
  128. package/dist/analyzers/tests/index.d.ts +8 -0
  129. package/dist/analyzers/tests/index.d.ts.map +1 -0
  130. package/dist/analyzers/tests/index.js +247 -0
  131. package/dist/analyzers/tests/index.js.map +1 -0
  132. package/dist/analyzers/tests/scoring.d.ts +27 -0
  133. package/dist/analyzers/tests/scoring.d.ts.map +1 -0
  134. package/dist/analyzers/tests/scoring.js +38 -0
  135. package/dist/analyzers/tests/scoring.js.map +1 -0
  136. package/dist/analyzers/tests/shallow.d.ts +9 -0
  137. package/dist/analyzers/tests/shallow.d.ts.map +1 -0
  138. package/dist/analyzers/tests/shallow.js +8 -0
  139. package/dist/analyzers/tests/shallow.js.map +1 -0
  140. package/dist/analyzers/tests/types.d.ts +49 -0
  141. package/dist/analyzers/tests/types.d.ts.map +1 -0
  142. package/dist/analyzers/tests/types.js +6 -0
  143. package/dist/analyzers/tests/types.js.map +1 -0
  144. package/dist/analyzers/tools/cloc.d.ts +8 -0
  145. package/dist/analyzers/tools/cloc.d.ts.map +1 -0
  146. package/dist/analyzers/tools/cloc.js +49 -0
  147. package/dist/analyzers/tools/cloc.js.map +1 -0
  148. package/dist/analyzers/tools/coverage.d.ts +59 -0
  149. package/dist/analyzers/tools/coverage.d.ts.map +1 -0
  150. package/dist/analyzers/tools/coverage.js +280 -0
  151. package/dist/analyzers/tools/coverage.js.map +1 -0
  152. package/dist/analyzers/tools/cvss-v4-lookup.d.ts +10 -0
  153. package/dist/analyzers/tools/cvss-v4-lookup.d.ts.map +1 -0
  154. package/dist/analyzers/tools/cvss-v4-lookup.js +284 -0
  155. package/dist/analyzers/tools/cvss-v4-lookup.js.map +1 -0
  156. package/dist/analyzers/tools/cvss-v4.d.ts +24 -0
  157. package/dist/analyzers/tools/cvss-v4.d.ts.map +1 -0
  158. package/dist/analyzers/tools/cvss-v4.js +362 -0
  159. package/dist/analyzers/tools/cvss-v4.js.map +1 -0
  160. package/dist/analyzers/tools/default-exclusions.gitignore +56 -0
  161. package/dist/analyzers/tools/exclusions.d.ts +70 -0
  162. package/dist/analyzers/tools/exclusions.d.ts.map +1 -0
  163. package/dist/analyzers/tools/exclusions.js +250 -0
  164. package/dist/analyzers/tools/exclusions.js.map +1 -0
  165. package/dist/analyzers/tools/generic.d.ts +4 -0
  166. package/dist/analyzers/tools/generic.d.ts.map +1 -0
  167. package/dist/analyzers/tools/generic.js +198 -0
  168. package/dist/analyzers/tools/generic.js.map +1 -0
  169. package/dist/analyzers/tools/gitleaks.d.ts +8 -0
  170. package/dist/analyzers/tools/gitleaks.d.ts.map +1 -0
  171. package/dist/analyzers/tools/gitleaks.js +58 -0
  172. package/dist/analyzers/tools/gitleaks.js.map +1 -0
  173. package/dist/analyzers/tools/graphify.d.ts +4 -0
  174. package/dist/analyzers/tools/graphify.d.ts.map +1 -0
  175. package/dist/analyzers/tools/graphify.js +222 -0
  176. package/dist/analyzers/tools/graphify.js.map +1 -0
  177. package/dist/analyzers/tools/osv.d.ts +51 -0
  178. package/dist/analyzers/tools/osv.d.ts.map +1 -0
  179. package/dist/analyzers/tools/osv.js +188 -0
  180. package/dist/analyzers/tools/osv.js.map +1 -0
  181. package/dist/analyzers/tools/parallel.d.ts +8 -0
  182. package/dist/analyzers/tools/parallel.d.ts.map +1 -0
  183. package/dist/analyzers/tools/parallel.js +195 -0
  184. package/dist/analyzers/tools/parallel.js.map +1 -0
  185. package/dist/analyzers/tools/runner.d.ts +13 -0
  186. package/dist/analyzers/tools/runner.d.ts.map +1 -0
  187. package/dist/analyzers/tools/runner.js +109 -0
  188. package/dist/analyzers/tools/runner.js.map +1 -0
  189. package/dist/analyzers/tools/suppressions.d.ts +55 -0
  190. package/dist/analyzers/tools/suppressions.d.ts.map +1 -0
  191. package/dist/analyzers/tools/suppressions.js +203 -0
  192. package/dist/analyzers/tools/suppressions.js.map +1 -0
  193. package/dist/analyzers/tools/timing.d.ts +9 -0
  194. package/dist/analyzers/tools/timing.d.ts.map +1 -0
  195. package/dist/analyzers/tools/timing.js +29 -0
  196. package/dist/analyzers/tools/timing.js.map +1 -0
  197. package/dist/analyzers/tools/tool-registry.d.ts +86 -0
  198. package/dist/analyzers/tools/tool-registry.d.ts.map +1 -0
  199. package/dist/analyzers/tools/tool-registry.js +705 -0
  200. package/dist/analyzers/tools/tool-registry.js.map +1 -0
  201. package/dist/analyzers/types.d.ts +125 -0
  202. package/dist/analyzers/types.d.ts.map +1 -0
  203. package/dist/analyzers/types.js +11 -0
  204. package/dist/analyzers/types.js.map +1 -0
  205. package/dist/cli.d.ts.map +1 -1
  206. package/dist/cli.js +462 -0
  207. package/dist/cli.js.map +1 -1
  208. package/dist/detect.d.ts.map +1 -1
  209. package/dist/detect.js +24 -15
  210. package/dist/detect.js.map +1 -1
  211. package/dist/languages/csharp.d.ts +5 -0
  212. package/dist/languages/csharp.d.ts.map +1 -0
  213. package/dist/languages/csharp.js +265 -0
  214. package/dist/languages/csharp.js.map +1 -0
  215. package/dist/languages/go.d.ts +11 -0
  216. package/dist/languages/go.d.ts.map +1 -0
  217. package/dist/languages/go.js +321 -0
  218. package/dist/languages/go.js.map +1 -0
  219. package/dist/languages/index.d.ts +6 -0
  220. package/dist/languages/index.d.ts.map +1 -0
  221. package/dist/languages/index.js +18 -0
  222. package/dist/languages/index.js.map +1 -0
  223. package/dist/languages/python.d.ts +3 -0
  224. package/dist/languages/python.d.ts.map +1 -0
  225. package/dist/languages/python.js +284 -0
  226. package/dist/languages/python.js.map +1 -0
  227. package/dist/languages/rust.d.ts +17 -0
  228. package/dist/languages/rust.d.ts.map +1 -0
  229. package/dist/languages/rust.js +333 -0
  230. package/dist/languages/rust.js.map +1 -0
  231. package/dist/languages/types.d.ts +38 -0
  232. package/dist/languages/types.d.ts.map +1 -0
  233. package/dist/languages/types.js +3 -0
  234. package/dist/languages/types.js.map +1 -0
  235. package/dist/languages/typescript.d.ts +15 -0
  236. package/dist/languages/typescript.d.ts.map +1 -0
  237. package/dist/languages/typescript.js +353 -0
  238. package/dist/languages/typescript.js.map +1 -0
  239. package/dist/logger.d.ts +1 -0
  240. package/dist/logger.d.ts.map +1 -1
  241. package/dist/logger.js +25 -12
  242. package/dist/logger.js.map +1 -1
  243. package/dist/project-yaml.d.ts.map +1 -1
  244. package/dist/project-yaml.js +1 -0
  245. package/dist/project-yaml.js.map +1 -1
  246. package/dist/tools-cli.d.ts +2 -0
  247. package/dist/tools-cli.d.ts.map +1 -0
  248. package/dist/tools-cli.js +231 -0
  249. package/dist/tools-cli.js.map +1 -0
  250. package/dist/types.d.ts +10 -0
  251. package/dist/types.d.ts.map +1 -1
  252. package/package.json +6 -2
  253. package/templates/.claude/commands/dev-report.md +34 -4
  254. package/templates/.claude/commands/health.md +45 -2
  255. package/templates/.claude/commands/quality.md.template +38 -15
  256. package/templates/.claude/commands/test-gaps.md +36 -2
  257. package/templates/.claude/commands/vulnerabilities.md +36 -2
  258. package/templates/.project/scripts/setup/interactive-setup.sh +6 -2
@@ -0,0 +1,321 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.go = void 0;
37
+ exports.mapGolangciLinterSeverity = mapGolangciLinterSeverity;
38
+ const fs = __importStar(require("fs"));
39
+ const path = __importStar(require("path"));
40
+ const coverage_1 = require("../analyzers/tools/coverage");
41
+ const osv_1 = require("../analyzers/tools/osv");
42
+ const runner_1 = require("../analyzers/tools/runner");
43
+ const tool_registry_1 = require("../analyzers/tools/tool-registry");
44
+ /**
45
+ * Tier a golangci-lint finding by the linter that produced it.
46
+ *
47
+ * golangci-lint bundles ~60 linters with different character. The
48
+ * `FromLinter` field identifies which one fired. `Severity` (often empty)
49
+ * is used only as a fallback floor for unknown linters.
50
+ */
51
+ function mapGolangciLinterSeverity(linter) {
52
+ if (!linter)
53
+ return 'low';
54
+ // Security — gosec exclusively flags vuln patterns.
55
+ if (linter === 'gosec')
56
+ return 'critical';
57
+ // Correctness bugs — go vet, staticcheck analyses, type errors, etc.
58
+ if (linter === 'govet' ||
59
+ linter === 'staticcheck' ||
60
+ linter === 'typecheck' ||
61
+ linter === 'errorlint' ||
62
+ linter === 'ineffassign' ||
63
+ linter === 'unused' ||
64
+ linter === 'nilerr' ||
65
+ linter === 'bodyclose' ||
66
+ linter === 'rowserrcheck' ||
67
+ linter === 'sqlclosecheck' ||
68
+ linter === 'noctx') {
69
+ return 'high';
70
+ }
71
+ // Best practices / maintenance
72
+ if (linter === 'errcheck' ||
73
+ linter === 'gocritic' ||
74
+ linter === 'revive' ||
75
+ linter === 'goconst' ||
76
+ linter === 'gocyclo' ||
77
+ linter === 'funlen' ||
78
+ linter === 'dupl' ||
79
+ linter === 'gosimple' ||
80
+ linter === 'unconvert' ||
81
+ linter === 'unparam' ||
82
+ linter === 'prealloc' ||
83
+ linter === 'gocognit') {
84
+ return 'medium';
85
+ }
86
+ // Style / formatting
87
+ if (linter === 'gofmt' ||
88
+ linter === 'gofumpt' ||
89
+ linter === 'goimports' ||
90
+ linter === 'stylecheck' ||
91
+ linter === 'whitespace' ||
92
+ linter === 'misspell' ||
93
+ linter === 'godot' ||
94
+ linter === 'lll') {
95
+ return 'low';
96
+ }
97
+ return 'low';
98
+ }
99
+ function tierGolangciIssue(issue) {
100
+ const byLinter = mapGolangciLinterSeverity(issue.FromLinter);
101
+ // For unknown linters we fell through to 'low' — but golangci-lint's
102
+ // own Severity field may say otherwise. Use it as a floor.
103
+ if (byLinter === 'low' && issue.FromLinter) {
104
+ const sev = (issue.Severity || '').toLowerCase();
105
+ if (sev === 'error')
106
+ return 'high';
107
+ if (sev === 'warning')
108
+ return 'medium';
109
+ }
110
+ return byLinter;
111
+ }
112
+ exports.go = {
113
+ id: 'go',
114
+ displayName: 'Go',
115
+ sourceExtensions: ['.go'],
116
+ testFilePatterns: ['*_test.go'],
117
+ extraExcludes: ['vendor'],
118
+ detect(cwd) {
119
+ return (0, runner_1.fileExists)(cwd, 'go.mod');
120
+ },
121
+ tools: ['golangci-lint', 'govulncheck'],
122
+ semgrepRulesets: ['p/gosec'],
123
+ mapLintSeverity: mapGolangciLinterSeverity,
124
+ parseCoverage(cwd) {
125
+ for (const file of ['coverage.out', 'cover.out']) {
126
+ const abs = path.join(cwd, file);
127
+ let raw;
128
+ try {
129
+ raw = fs.readFileSync(abs, 'utf-8');
130
+ }
131
+ catch {
132
+ continue;
133
+ }
134
+ try {
135
+ return (0, coverage_1.parseGoCoverProfile)(raw, file, cwd);
136
+ }
137
+ catch {
138
+ continue;
139
+ }
140
+ }
141
+ return null;
142
+ },
143
+ extractImports(content) {
144
+ const out = [];
145
+ // Single-line: `import "fmt"` or `import foo "pkg/name"`
146
+ const singleRe = /^\s*import\s+(?:[a-zA-Z_]\w*\s+)?"([^"]+)"/gm;
147
+ let m;
148
+ while ((m = singleRe.exec(content)) !== null) {
149
+ out.push(m[1]);
150
+ }
151
+ // Multi-line: `import (\n "fmt"\n alias "pkg"\n)`
152
+ const blockRe = /import\s*\(([\s\S]*?)\)/g;
153
+ while ((m = blockRe.exec(content)) !== null) {
154
+ const block = m[1];
155
+ const lineRe = /(?:[a-zA-Z_]\w*\s+)?"([^"]+)"/g;
156
+ let lm;
157
+ while ((lm = lineRe.exec(block)) !== null) {
158
+ if (!out.includes(lm[1])) {
159
+ out.push(lm[1]);
160
+ }
161
+ }
162
+ }
163
+ return out;
164
+ },
165
+ resolveImport(fromFile, spec, cwd) {
166
+ // Go import paths are module-based, not file-relative.
167
+ // Internal packages resolve as <module>/internal/... → cwd/internal/...
168
+ let goMod;
169
+ try {
170
+ goMod = fs.readFileSync(path.join(cwd, 'go.mod'), 'utf-8');
171
+ }
172
+ catch {
173
+ return null;
174
+ }
175
+ const moduleMatch = goMod.match(/^module\s+(\S+)/m);
176
+ if (!moduleMatch)
177
+ return null;
178
+ const modulePath = moduleMatch[1];
179
+ if (!spec.startsWith(modulePath + '/'))
180
+ return null;
181
+ const rel = spec.slice(modulePath.length + 1);
182
+ const dir = path.join(cwd, rel);
183
+ try {
184
+ if (fs.statSync(dir).isDirectory()) {
185
+ return rel;
186
+ }
187
+ }
188
+ catch {
189
+ // not found
190
+ }
191
+ return null;
192
+ },
193
+ async gatherMetrics(cwd) {
194
+ const metrics = {
195
+ toolsUsed: [],
196
+ toolsUnavailable: [],
197
+ };
198
+ const lint = (0, tool_registry_1.findTool)(tool_registry_1.TOOL_DEFS['golangci-lint'], cwd);
199
+ if (lint.available && lint.path) {
200
+ const raw = (0, runner_1.run)(`${lint.path} run --out-format json ./... 2>/dev/null`, cwd, 120000);
201
+ if (raw) {
202
+ try {
203
+ const data = JSON.parse(raw);
204
+ const issues = data.Issues || [];
205
+ // Tier each issue by its FromLinter, then collapse:
206
+ // critical + high → errors, medium + low → warnings.
207
+ let errors = 0;
208
+ let warnings = 0;
209
+ for (const issue of issues) {
210
+ const tier = tierGolangciIssue(issue);
211
+ if (tier === 'critical' || tier === 'high')
212
+ errors++;
213
+ else
214
+ warnings++;
215
+ }
216
+ metrics.lintErrors = errors;
217
+ metrics.lintWarnings = warnings;
218
+ metrics.lintTool = 'golangci-lint';
219
+ metrics.toolsUsed.push('golangci-lint');
220
+ }
221
+ catch {
222
+ metrics.toolsUnavailable.push('golangci-lint (parse error)');
223
+ }
224
+ }
225
+ else {
226
+ metrics.lintErrors = 0;
227
+ metrics.lintWarnings = 0;
228
+ metrics.lintTool = 'golangci-lint';
229
+ metrics.toolsUsed.push('golangci-lint');
230
+ }
231
+ }
232
+ else {
233
+ metrics.toolsUnavailable.push('golangci-lint');
234
+ }
235
+ const vuln = (0, tool_registry_1.findTool)(tool_registry_1.TOOL_DEFS.govulncheck, cwd);
236
+ if (vuln.available && vuln.path) {
237
+ const raw = (0, runner_1.run)(`${vuln.path} -json ./... 2>/dev/null`, cwd, 120000);
238
+ if (raw) {
239
+ try {
240
+ // govulncheck emits ndjson with three relevant shapes:
241
+ // { "osv": { ...full OSV record... } } — the advisory detail
242
+ // { "finding": { "osv": "GO-YYYY-NNNN", "trace": [...] } } — a call-site hit
243
+ // { "config": ... } / { "progress": ... } — ignored
244
+ const findingIds = new Set();
245
+ const embeddedOsv = new Map();
246
+ for (const line of raw.split('\n')) {
247
+ if (!line.trim())
248
+ continue;
249
+ try {
250
+ const obj = JSON.parse(line);
251
+ if (obj.finding?.osv)
252
+ findingIds.add(obj.finding.osv);
253
+ if (obj.osv?.id)
254
+ embeddedOsv.set(obj.osv.id, obj.osv);
255
+ }
256
+ catch {
257
+ /* skip non-JSON lines */
258
+ }
259
+ }
260
+ // Prefer severity from the embedded OSV record (already in the
261
+ // govulncheck output, no extra API call). Fall back to an OSV.dev
262
+ // lookup for IDs without embedded data. Fall back to 'high' (the
263
+ // legacy govulncheck default) for anything still unknown.
264
+ const ids = [...findingIds];
265
+ const needsLookup = ids.filter((id) => {
266
+ const rec = embeddedOsv.get(id);
267
+ if (!rec)
268
+ return true;
269
+ return (0, osv_1.classifyOsvSeverity)(rec) === 'unknown';
270
+ });
271
+ const lookedUp = needsLookup.length > 0 ? await (0, osv_1.enrichSeverities)(needsLookup) : new Map();
272
+ let critical = 0;
273
+ let high = 0;
274
+ let medium = 0;
275
+ let low = 0;
276
+ let enrichedCount = 0;
277
+ for (const id of ids) {
278
+ const rec = embeddedOsv.get(id);
279
+ let sev = rec ? (0, osv_1.classifyOsvSeverity)(rec) : 'unknown';
280
+ if (sev === 'unknown')
281
+ sev = lookedUp.get(id) ?? 'unknown';
282
+ if (sev !== 'unknown') {
283
+ enrichedCount++;
284
+ if (sev === 'critical')
285
+ critical++;
286
+ else if (sev === 'high')
287
+ high++;
288
+ else if (sev === 'medium')
289
+ medium++;
290
+ else
291
+ low++;
292
+ }
293
+ else {
294
+ high++; // govulncheck legacy default
295
+ }
296
+ }
297
+ metrics.depVulnCritical = critical;
298
+ metrics.depVulnHigh = high;
299
+ metrics.depVulnMedium = medium;
300
+ metrics.depVulnLow = low;
301
+ metrics.depAuditTool = 'govulncheck';
302
+ metrics.toolsUsed.push('govulncheck');
303
+ if (enrichedCount > 0 && needsLookup.length > 0) {
304
+ metrics.toolsUsed.push('osv.dev');
305
+ }
306
+ }
307
+ catch {
308
+ metrics.toolsUnavailable.push('govulncheck (parse error)');
309
+ }
310
+ }
311
+ }
312
+ else {
313
+ metrics.toolsUnavailable.push('govulncheck');
314
+ }
315
+ if ((0, runner_1.fileExists)(cwd, 'go.mod')) {
316
+ metrics.testFramework = 'go-test';
317
+ }
318
+ return metrics;
319
+ },
320
+ };
321
+ //# sourceMappingURL=go.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"go.js","sourceRoot":"","sources":["../../src/languages/go.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { LanguageId, LanguageSupport } from './types';
2
+ export type { LanguageId, LanguageSupport, LintSeverity } from './types';
3
+ export declare const LANGUAGES: readonly LanguageSupport[];
4
+ export declare function getLanguage(id: LanguageId): LanguageSupport | undefined;
5
+ export declare function detectActiveLanguages(cwd: string): LanguageSupport[];
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/languages/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAO3D,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEzE,eAAO,MAAM,SAAS,EAAE,SAAS,eAAe,EAA2C,CAAC;AAE5F,wBAAgB,WAAW,CAAC,EAAE,EAAE,UAAU,GAAG,eAAe,GAAG,SAAS,CAEvE;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,EAAE,CAEpE"}
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LANGUAGES = void 0;
4
+ exports.getLanguage = getLanguage;
5
+ exports.detectActiveLanguages = detectActiveLanguages;
6
+ const csharp_1 = require("./csharp");
7
+ const go_1 = require("./go");
8
+ const python_1 = require("./python");
9
+ const rust_1 = require("./rust");
10
+ const typescript_1 = require("./typescript");
11
+ exports.LANGUAGES = [python_1.python, typescript_1.typescript, csharp_1.csharp, go_1.go, rust_1.rust];
12
+ function getLanguage(id) {
13
+ return exports.LANGUAGES.find((l) => l.id === id);
14
+ }
15
+ function detectActiveLanguages(cwd) {
16
+ return exports.LANGUAGES.filter((l) => l.detect(cwd));
17
+ }
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/languages/index.ts"],"names":[],"mappings":";;;AAWA,kCAEC;AAED,sDAEC;AAhBD,qCAAkC;AAClC,6BAA0B;AAC1B,qCAAkC;AAClC,iCAA8B;AAC9B,6CAA0C;AAI7B,QAAA,SAAS,GAA+B,CAAC,eAAM,EAAE,uBAAU,EAAE,eAAM,EAAE,OAAE,EAAE,WAAI,CAAC,CAAC;AAE5F,SAAgB,WAAW,CAAC,EAAc;IACxC,OAAO,iBAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;AAC5C,CAAC;AAED,SAAgB,qBAAqB,CAAC,GAAW;IAC/C,OAAO,iBAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;AAChD,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { LanguageSupport } from './types';
2
+ export declare const python: LanguageSupport;
3
+ //# sourceMappingURL=python.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"python.d.ts","sourceRoot":"","sources":["../../src/languages/python.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,eAAe,EAAgB,MAAM,SAAS,CAAC;AAoE7D,eAAO,MAAM,MAAM,EAAE,eAiLpB,CAAC"}
@@ -0,0 +1,284 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.python = void 0;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const coverage_1 = require("../analyzers/tools/coverage");
40
+ const osv_1 = require("../analyzers/tools/osv");
41
+ const runner_1 = require("../analyzers/tools/runner");
42
+ const tool_registry_1 = require("../analyzers/tools/tool-registry");
43
+ function stripPyComments(src) {
44
+ return src.replace(/(^|[^\w"'])#[^\n]*/g, '$1');
45
+ }
46
+ function isFile(p) {
47
+ try {
48
+ return fs.statSync(p).isFile();
49
+ }
50
+ catch {
51
+ return false;
52
+ }
53
+ }
54
+ function toRel(abs, cwd) {
55
+ return path.relative(cwd, abs).split(path.sep).join('/');
56
+ }
57
+ function hasPyFileWithinDepth(cwd, maxDepth = 2) {
58
+ function search(dir, depth) {
59
+ if (depth > maxDepth)
60
+ return false;
61
+ let entries;
62
+ try {
63
+ entries = fs.readdirSync(dir, { withFileTypes: true });
64
+ }
65
+ catch {
66
+ return false;
67
+ }
68
+ for (const e of entries) {
69
+ if (e.name.startsWith('.') ||
70
+ ['node_modules', 'vendor', 'bin', 'obj', 'target'].includes(e.name)) {
71
+ continue;
72
+ }
73
+ if (e.isFile() && e.name.endsWith('.py'))
74
+ return true;
75
+ if (e.isDirectory() && search(path.join(dir, e.name), depth + 1))
76
+ return true;
77
+ }
78
+ return false;
79
+ }
80
+ return search(cwd, 0);
81
+ }
82
+ function mapRuffSeverity(code) {
83
+ const prefix = code.match(/^[A-Z]+/)?.[0] ?? '';
84
+ switch (prefix) {
85
+ case 'S':
86
+ return 'critical';
87
+ case 'F':
88
+ case 'B':
89
+ return 'high';
90
+ case 'E':
91
+ case 'C':
92
+ return 'medium';
93
+ default:
94
+ return 'low';
95
+ }
96
+ }
97
+ exports.python = {
98
+ id: 'python',
99
+ displayName: 'Python',
100
+ sourceExtensions: ['.py'],
101
+ testFilePatterns: ['test_*.py', '*_test.py'],
102
+ extraExcludes: ['__pycache__', '.pytest_cache', '.ruff_cache', '.venv', 'venv', '.mypy_cache'],
103
+ detect(cwd) {
104
+ return ((0, runner_1.fileExists)(cwd, 'pyproject.toml') ||
105
+ (0, runner_1.fileExists)(cwd, 'setup.py') ||
106
+ (0, runner_1.fileExists)(cwd, 'requirements.txt') ||
107
+ (0, runner_1.fileExists)(cwd, 'Pipfile') ||
108
+ hasPyFileWithinDepth(cwd, 2));
109
+ },
110
+ tools: ['ruff', 'pip-audit', 'coverage-py'],
111
+ semgrepRulesets: ['p/python'],
112
+ parseCoverage(cwd) {
113
+ const file = path.join(cwd, 'coverage.json');
114
+ let raw;
115
+ try {
116
+ raw = fs.readFileSync(file, 'utf-8');
117
+ }
118
+ catch {
119
+ return null;
120
+ }
121
+ try {
122
+ return (0, coverage_1.parseCoveragePy)(raw, 'coverage.json', cwd);
123
+ }
124
+ catch {
125
+ return null;
126
+ }
127
+ },
128
+ extractImports(content) {
129
+ const out = [];
130
+ for (const line of stripPyComments(content).split('\n')) {
131
+ const trimmed = line.trim();
132
+ const fromMatch = trimmed.match(/^from\s+([.\w]+)\s+import\s+/);
133
+ if (fromMatch) {
134
+ out.push(fromMatch[1]);
135
+ continue;
136
+ }
137
+ const impMatch = trimmed.match(/^import\s+(.+)$/);
138
+ if (impMatch) {
139
+ for (const part of impMatch[1].split(',')) {
140
+ const name = part
141
+ .trim()
142
+ .split(/\s+as\s+/)[0]
143
+ .trim();
144
+ if (name)
145
+ out.push(name);
146
+ }
147
+ }
148
+ }
149
+ return out;
150
+ },
151
+ resolveImport(fromFile, spec, cwd) {
152
+ const fromDir = path.dirname(path.join(cwd, fromFile));
153
+ const dotMatch = spec.match(/^(\.+)(.*)$/);
154
+ let baseDir;
155
+ let remainder;
156
+ if (dotMatch) {
157
+ const dots = dotMatch[1].length;
158
+ remainder = dotMatch[2];
159
+ baseDir = fromDir;
160
+ for (let i = 1; i < dots; i++)
161
+ baseDir = path.dirname(baseDir);
162
+ }
163
+ else {
164
+ baseDir = cwd;
165
+ remainder = spec;
166
+ }
167
+ if (!remainder)
168
+ return null;
169
+ const parts = remainder.split('.').filter(Boolean);
170
+ const candidate = path.join(baseDir, ...parts);
171
+ if (isFile(candidate + '.py'))
172
+ return toRel(candidate + '.py', cwd);
173
+ const init = path.join(candidate, '__init__.py');
174
+ if (isFile(init))
175
+ return toRel(init, cwd);
176
+ return null;
177
+ },
178
+ async gatherMetrics(cwd) {
179
+ const metrics = {
180
+ toolsUsed: [],
181
+ toolsUnavailable: [],
182
+ };
183
+ const ruff = (0, tool_registry_1.findTool)(tool_registry_1.TOOL_DEFS.ruff, cwd);
184
+ if (ruff.available && ruff.path) {
185
+ const raw = (0, runner_1.run)(`${ruff.path} check . --output-format json 2>/dev/null`, cwd, 60000);
186
+ if (raw) {
187
+ try {
188
+ const results = JSON.parse(raw);
189
+ if (Array.isArray(results)) {
190
+ let errors = 0;
191
+ let warnings = 0;
192
+ for (const r of results) {
193
+ const sev = mapRuffSeverity(r.code);
194
+ if (sev === 'critical' || sev === 'high')
195
+ errors++;
196
+ else
197
+ warnings++;
198
+ }
199
+ metrics.lintErrors = errors;
200
+ metrics.lintWarnings = warnings;
201
+ metrics.lintTool = 'ruff';
202
+ metrics.toolsUsed.push('ruff');
203
+ }
204
+ }
205
+ catch {
206
+ metrics.toolsUnavailable.push('ruff (parse error)');
207
+ }
208
+ }
209
+ else {
210
+ metrics.lintErrors = 0;
211
+ metrics.lintWarnings = 0;
212
+ metrics.lintTool = 'ruff';
213
+ metrics.toolsUsed.push('ruff');
214
+ }
215
+ }
216
+ else {
217
+ metrics.toolsUnavailable.push('ruff');
218
+ }
219
+ const pipAudit = (0, tool_registry_1.findTool)(tool_registry_1.TOOL_DEFS['pip-audit'], cwd);
220
+ if (pipAudit.available && pipAudit.path) {
221
+ const raw = (0, runner_1.run)(`${pipAudit.path} --format json 2>/dev/null`, cwd, 120000);
222
+ if (raw) {
223
+ try {
224
+ const data = JSON.parse(raw);
225
+ const vulnIds = [];
226
+ for (const dep of data.dependencies || []) {
227
+ for (const v of dep.vulns || []) {
228
+ if (v.id)
229
+ vulnIds.push(v.id);
230
+ }
231
+ }
232
+ // pip-audit doesn't carry severity per vuln — look up via OSV.dev.
233
+ // Unknown/unreachable IDs fall back to medium (pip-audit's legacy default).
234
+ const severities = await (0, osv_1.enrichSeverities)(vulnIds);
235
+ let critical = 0;
236
+ let high = 0;
237
+ let medium = 0;
238
+ let low = 0;
239
+ let enrichedCount = 0;
240
+ for (const id of vulnIds) {
241
+ const sev = severities.get(id);
242
+ if (sev && sev !== 'unknown') {
243
+ enrichedCount++;
244
+ if (sev === 'critical')
245
+ critical++;
246
+ else if (sev === 'high')
247
+ high++;
248
+ else if (sev === 'medium')
249
+ medium++;
250
+ else
251
+ low++;
252
+ }
253
+ else {
254
+ medium++;
255
+ }
256
+ }
257
+ metrics.depVulnCritical = critical;
258
+ metrics.depVulnHigh = high;
259
+ metrics.depVulnMedium = medium;
260
+ metrics.depVulnLow = low;
261
+ metrics.depAuditTool = 'pip-audit';
262
+ metrics.toolsUsed.push('pip-audit');
263
+ if (enrichedCount > 0)
264
+ metrics.toolsUsed.push('osv.dev');
265
+ }
266
+ catch {
267
+ metrics.toolsUnavailable.push('pip-audit (parse error)');
268
+ }
269
+ }
270
+ }
271
+ else {
272
+ metrics.toolsUnavailable.push('pip-audit');
273
+ }
274
+ if ((0, runner_1.fileExists)(cwd, 'pytest.ini', 'conftest.py') || (0, runner_1.fileExists)(cwd, 'pyproject.toml')) {
275
+ const pyproject = (0, runner_1.run)('cat pyproject.toml 2>/dev/null', cwd);
276
+ if (pyproject?.includes('[tool.pytest') || (0, runner_1.fileExists)(cwd, 'pytest.ini', 'conftest.py')) {
277
+ metrics.testFramework = 'pytest';
278
+ }
279
+ }
280
+ return metrics;
281
+ },
282
+ mapLintSeverity: mapRuffSeverity,
283
+ };
284
+ //# sourceMappingURL=python.js.map