milens 0.6.2 → 0.6.4

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 (123) hide show
  1. package/.agents/skills/adapters/SKILL.md +31 -0
  2. package/.agents/skills/analyzer/SKILL.md +55 -0
  3. package/.agents/skills/apps/SKILL.md +42 -0
  4. package/.agents/skills/docs/SKILL.md +46 -0
  5. package/.agents/skills/milens/SKILL.md +168 -0
  6. package/.agents/skills/milens-code-review/SKILL.md +186 -0
  7. package/.agents/skills/milens-eval/SKILL.md +221 -0
  8. package/.agents/skills/milens-plan/SKILL.md +227 -0
  9. package/.agents/skills/milens-refactor-clean/SKILL.md +209 -0
  10. package/.agents/skills/milens-security-review/SKILL.md +224 -0
  11. package/.agents/skills/milens-tdd/SKILL.md +156 -0
  12. package/.agents/skills/parser/SKILL.md +60 -0
  13. package/.agents/skills/root/SKILL.md +64 -0
  14. package/.agents/skills/scripts/SKILL.md +27 -0
  15. package/.agents/skills/security/SKILL.md +44 -0
  16. package/.agents/skills/server/SKILL.md +46 -0
  17. package/.agents/skills/store/SKILL.md +53 -0
  18. package/.agents/skills/test/SKILL.md +73 -0
  19. package/LICENSE +75 -75
  20. package/README.md +524 -305
  21. package/adapters/README.md +107 -0
  22. package/adapters/claude-code/.claude/mcp.json +9 -0
  23. package/adapters/claude-code/CLAUDE.md +58 -0
  24. package/adapters/codex/.codex/codex.md +52 -0
  25. package/adapters/copilot/.github/copilot-instructions.md +62 -0
  26. package/adapters/cursor/.cursorrules +9 -0
  27. package/adapters/gemini/.gemini/context.md +58 -0
  28. package/adapters/opencode/.opencode/config.json +9 -0
  29. package/adapters/opencode/AGENTS.md +58 -0
  30. package/adapters/zed/.zed/settings.json +8 -0
  31. package/dist/agents-md.d.ts +3 -0
  32. package/dist/agents-md.d.ts.map +1 -0
  33. package/dist/agents-md.js +112 -0
  34. package/dist/agents-md.js.map +1 -0
  35. package/dist/analyzer/engine.d.ts +1 -0
  36. package/dist/analyzer/engine.d.ts.map +1 -1
  37. package/dist/analyzer/engine.js +27 -8
  38. package/dist/analyzer/engine.js.map +1 -1
  39. package/dist/analyzer/review.d.ts +23 -0
  40. package/dist/analyzer/review.d.ts.map +1 -0
  41. package/dist/analyzer/review.js +143 -0
  42. package/dist/analyzer/review.js.map +1 -0
  43. package/dist/analyzer/testplan.d.ts +59 -0
  44. package/dist/analyzer/testplan.d.ts.map +1 -0
  45. package/dist/analyzer/testplan.js +218 -0
  46. package/dist/analyzer/testplan.js.map +1 -0
  47. package/dist/cli.js +1192 -401
  48. package/dist/cli.js.map +1 -1
  49. package/dist/metrics.d.ts +51 -0
  50. package/dist/metrics.d.ts.map +1 -0
  51. package/dist/metrics.js +64 -0
  52. package/dist/metrics.js.map +1 -0
  53. package/dist/parser/extract.d.ts +1 -0
  54. package/dist/parser/extract.d.ts.map +1 -1
  55. package/dist/parser/extract.js +8 -0
  56. package/dist/parser/extract.js.map +1 -1
  57. package/dist/parser/lang-go.d.ts.map +1 -1
  58. package/dist/parser/lang-go.js +75 -39
  59. package/dist/parser/lang-go.js.map +1 -1
  60. package/dist/parser/lang-java.d.ts.map +1 -1
  61. package/dist/parser/lang-java.js +30 -29
  62. package/dist/parser/lang-java.js.map +1 -1
  63. package/dist/parser/lang-js.js +105 -105
  64. package/dist/parser/lang-php.js +38 -38
  65. package/dist/parser/lang-py.d.ts.map +1 -1
  66. package/dist/parser/lang-py.js +53 -31
  67. package/dist/parser/lang-py.js.map +1 -1
  68. package/dist/parser/lang-ruby.d.ts.map +1 -1
  69. package/dist/parser/lang-ruby.js +15 -14
  70. package/dist/parser/lang-ruby.js.map +1 -1
  71. package/dist/parser/lang-rust.js +30 -30
  72. package/dist/parser/lang-ts.js +191 -191
  73. package/dist/security/deps.d.ts +38 -0
  74. package/dist/security/deps.d.ts.map +1 -0
  75. package/dist/security/deps.js +685 -0
  76. package/dist/security/deps.js.map +1 -0
  77. package/dist/security/rules.d.ts +42 -0
  78. package/dist/security/rules.d.ts.map +1 -0
  79. package/dist/security/rules.js +940 -0
  80. package/dist/security/rules.js.map +1 -0
  81. package/dist/server/hooks.d.ts +26 -0
  82. package/dist/server/hooks.d.ts.map +1 -0
  83. package/dist/server/hooks.js +253 -0
  84. package/dist/server/hooks.js.map +1 -0
  85. package/dist/server/mcp-prompts.d.ts +277 -0
  86. package/dist/server/mcp-prompts.d.ts.map +1 -0
  87. package/dist/server/mcp-prompts.js +627 -0
  88. package/dist/server/mcp-prompts.js.map +1 -0
  89. package/dist/server/mcp.d.ts.map +1 -1
  90. package/dist/server/mcp.js +520 -36
  91. package/dist/server/mcp.js.map +1 -1
  92. package/dist/server/test-plan.d.ts +20 -0
  93. package/dist/server/test-plan.d.ts.map +1 -0
  94. package/dist/server/test-plan.js +100 -0
  95. package/dist/server/test-plan.js.map +1 -0
  96. package/dist/skills.js +152 -120
  97. package/dist/skills.js.map +1 -1
  98. package/dist/store/annotations.d.ts +41 -0
  99. package/dist/store/annotations.d.ts.map +1 -0
  100. package/dist/store/annotations.js +192 -0
  101. package/dist/store/annotations.js.map +1 -0
  102. package/dist/store/confidence.d.ts +18 -0
  103. package/dist/store/confidence.d.ts.map +1 -0
  104. package/dist/store/confidence.js +82 -0
  105. package/dist/store/confidence.js.map +1 -0
  106. package/dist/store/db.d.ts +68 -1
  107. package/dist/store/db.d.ts.map +1 -1
  108. package/dist/store/db.js +349 -139
  109. package/dist/store/db.js.map +1 -1
  110. package/dist/store/schema.sql +128 -83
  111. package/dist/store/vectors.d.ts +65 -0
  112. package/dist/store/vectors.d.ts.map +1 -0
  113. package/dist/store/vectors.js +212 -0
  114. package/dist/store/vectors.js.map +1 -0
  115. package/dist/types.d.ts +101 -0
  116. package/dist/types.d.ts.map +1 -1
  117. package/dist/utils.d.ts +3 -0
  118. package/dist/utils.d.ts.map +1 -0
  119. package/dist/utils.js +9 -0
  120. package/dist/utils.js.map +1 -0
  121. package/docs/README.md +24 -0
  122. package/docs/diagram2.svg +1 -1
  123. package/package.json +80 -65
@@ -0,0 +1,685 @@
1
+ // ── Dependency vulnerability audit module for milens ──
2
+ import { readFileSync, existsSync } from 'node:fs';
3
+ import { join } from 'node:path';
4
+ // ── Internal utilities ──
5
+ function manifestExists(rootPath, filename) {
6
+ return existsSync(join(rootPath, filename));
7
+ }
8
+ function readManifest(rootPath, filename) {
9
+ return readFileSync(join(rootPath, filename), 'utf-8');
10
+ }
11
+ function parseSemver(version) {
12
+ const v = version.trim().replace(/^[~^=<>]*/, '');
13
+ const m = v.match(/^(\d+)\.(\d+)\.(\d+)((?:-[A-Za-z0-9_.-]+(?:\.[A-Za-z0-9_.-]+)*)?(?:\+[A-Za-z0-9_.-]+)?)?$/);
14
+ if (!m)
15
+ return null;
16
+ return {
17
+ major: parseInt(m[1], 10),
18
+ minor: parseInt(m[2], 10),
19
+ patch: parseInt(m[3], 10),
20
+ prerelease: m[4] ?? '',
21
+ };
22
+ }
23
+ function cmpSemver(a, b) {
24
+ if (a.major !== b.major)
25
+ return a.major - b.major;
26
+ if (a.minor !== b.minor)
27
+ return a.minor - b.minor;
28
+ if (a.patch !== b.patch)
29
+ return a.patch - b.patch;
30
+ if (!a.prerelease && b.prerelease)
31
+ return 1;
32
+ if (a.prerelease && !b.prerelease)
33
+ return -1;
34
+ if (a.prerelease < b.prerelease)
35
+ return -1;
36
+ if (a.prerelease > b.prerelease)
37
+ return 1;
38
+ return 0;
39
+ }
40
+ function satisfiesRange(version, range) {
41
+ const sv = parseSemver(version);
42
+ if (!sv)
43
+ return false;
44
+ for (const clause of range.split('||').map((c) => c.trim())) {
45
+ if (satisfiesClause(sv, clause))
46
+ return true;
47
+ }
48
+ return false;
49
+ }
50
+ function satisfiesClause(sv, clause) {
51
+ const parts = clause.trim().split(/\s+/);
52
+ let lower = null;
53
+ let upper = null;
54
+ for (let i = 0; i < parts.length; i++) {
55
+ const part = parts[i];
56
+ if (part === '>=' || part === '>' || part === '<=' || part === '<' || part === '=' || part === '==') {
57
+ i++;
58
+ if (i >= parts.length)
59
+ return false;
60
+ const pv = parseSemver(parts[i]);
61
+ if (!pv)
62
+ return false;
63
+ const entry = { op: part.replace(/^==$/, '='), v: pv };
64
+ if (entry.op === '>=' || entry.op === '>') {
65
+ lower = entry;
66
+ }
67
+ else {
68
+ upper = entry;
69
+ }
70
+ }
71
+ else if (part === '>=') {
72
+ // Edge case: operator already handled
73
+ }
74
+ }
75
+ if (!lower && !upper)
76
+ return false;
77
+ if (lower) {
78
+ const c = cmpSemver(sv, lower.v);
79
+ if (lower.op === '>=' && c < 0)
80
+ return false;
81
+ if (lower.op === '>' && c <= 0)
82
+ return false;
83
+ }
84
+ if (upper) {
85
+ const c = cmpSemver(sv, upper.v);
86
+ if (upper.op === '<=' && c > 0)
87
+ return false;
88
+ if (upper.op === '<' && c >= 0)
89
+ return false;
90
+ }
91
+ return true;
92
+ }
93
+ // ── Offline CVE database ──
94
+ const CVE_DATABASE = [
95
+ // ═══════════════════════════════════════════════════════════════
96
+ // npm ecosystem
97
+ // ═══════════════════════════════════════════════════════════════
98
+ {
99
+ id: 'CVE-2018-16487',
100
+ cve: 'CVE-2018-16487',
101
+ severity: 'CRITICAL',
102
+ package: 'lodash',
103
+ affectedVersions: '< 4.17.11',
104
+ fixedVersion: '4.17.11',
105
+ description: 'Prototype pollution vulnerability in lodash.defaultsDeep leading to denial of service and potential remote code execution.',
106
+ },
107
+ {
108
+ id: 'CVE-2019-10744',
109
+ cve: 'CVE-2019-10744',
110
+ severity: 'CRITICAL',
111
+ package: 'lodash',
112
+ affectedVersions: '< 4.17.19',
113
+ fixedVersion: '4.17.19',
114
+ description: 'Prototype pollution in lodash.defaultsDeep, merge, mergeWith, and set allowing attackers to modify Object.prototype.',
115
+ },
116
+ {
117
+ id: 'CVE-2020-8203',
118
+ cve: 'CVE-2020-8203',
119
+ severity: 'HIGH',
120
+ package: 'lodash',
121
+ affectedVersions: '< 4.17.20',
122
+ fixedVersion: '4.17.20',
123
+ description: 'Prototype pollution in lodash zipObjectDeep function allowing modification of Object.prototype.',
124
+ },
125
+ {
126
+ id: 'CVE-2020-7598',
127
+ cve: 'CVE-2020-7598',
128
+ severity: 'HIGH',
129
+ package: 'minimist',
130
+ affectedVersions: '< 1.2.3',
131
+ fixedVersion: '1.2.3',
132
+ description: 'Prototype pollution in minimist via constructor or __proto__ keys in command-line arguments.',
133
+ },
134
+ {
135
+ id: 'CVE-2022-0235',
136
+ cve: 'CVE-2022-0235',
137
+ severity: 'HIGH',
138
+ package: 'node-fetch',
139
+ affectedVersions: '< 2.6.7',
140
+ fixedVersion: '2.6.7',
141
+ description: 'node-fetch forwards secure headers to untrusted destinations exposing authorization headers in redirect chains.',
142
+ },
143
+ {
144
+ id: 'CVE-2023-26136',
145
+ cve: 'CVE-2023-26136',
146
+ severity: 'CRITICAL',
147
+ package: 'tough-cookie',
148
+ affectedVersions: '< 4.1.3',
149
+ fixedVersion: '4.1.3',
150
+ description: 'Prototype pollution in tough-cookie rejectPublicSuffixes handling when cookie jar rejects are used.',
151
+ },
152
+ {
153
+ id: 'CVE-2024-21892',
154
+ cve: 'CVE-2024-21892',
155
+ severity: 'HIGH',
156
+ package: 'express',
157
+ affectedVersions: '< 4.18.3',
158
+ fixedVersion: '4.18.3',
159
+ description: 'Express vulnerable to code injection via res.sendFile, res.download, res.render called with user-controlled paths.',
160
+ },
161
+ {
162
+ id: 'CVE-2020-7610',
163
+ cve: 'CVE-2020-7610',
164
+ severity: 'CRITICAL',
165
+ package: 'bson',
166
+ affectedVersions: '< 1.1.4',
167
+ fixedVersion: '1.1.4',
168
+ description: 'bson deserialization is vulnerable to prototype pollution via malicious __proto__ fields in BSON documents.',
169
+ },
170
+ {
171
+ id: 'CVE-2020-28469',
172
+ cve: 'CVE-2020-28469',
173
+ severity: 'HIGH',
174
+ package: 'glob-parent',
175
+ affectedVersions: '< 5.1.2',
176
+ fixedVersion: '5.1.2',
177
+ description: 'glob-parent vulnerable to regular expression denial of service (ReDoS) via crafted glob patterns.',
178
+ },
179
+ {
180
+ id: 'CVE-2023-26115',
181
+ cve: 'CVE-2023-26115',
182
+ severity: 'HIGH',
183
+ package: 'word-wrap',
184
+ affectedVersions: '< 1.2.4',
185
+ fixedVersion: '1.2.4',
186
+ description: 'word-wrap vulnerable to regular expression denial of service (ReDoS) in the `result` variable.',
187
+ },
188
+ {
189
+ id: 'CVE-2022-25901',
190
+ cve: 'CVE-2022-25901',
191
+ severity: 'HIGH',
192
+ package: 'superagent',
193
+ affectedVersions: '< 8.0.0',
194
+ fixedVersion: '8.0.0',
195
+ description: 'superagent vulnerable to ReDoS in the `get` method via crafted URLs.',
196
+ },
197
+ {
198
+ id: 'CVE-2022-37603',
199
+ cve: 'CVE-2022-37603',
200
+ severity: 'HIGH',
201
+ package: 'loader-utils',
202
+ affectedVersions: '< 2.0.4',
203
+ fixedVersion: '2.0.4',
204
+ description: 'loader-utils prototype pollution via `parseQuery` function allowing modification of Object.prototype.',
205
+ },
206
+ {
207
+ id: 'CVE-2022-25883',
208
+ cve: 'CVE-2022-25883',
209
+ severity: 'HIGH',
210
+ package: 'semver',
211
+ affectedVersions: '< 7.5.2',
212
+ fixedVersion: '7.5.2',
213
+ description: 'semver vulnerable to regular expression denial of service (ReDoS) when parsing crafted semver strings.',
214
+ },
215
+ {
216
+ id: 'CVE-2022-43410',
217
+ cve: 'CVE-2022-43410',
218
+ severity: 'MEDIUM',
219
+ package: 'jenkins',
220
+ affectedVersions: '< 2.375.1',
221
+ fixedVersion: '2.375.1',
222
+ description: 'Jenkins webhook-trigger plugin allows stored XSS via crafted webhook payloads.',
223
+ },
224
+ {
225
+ id: 'CVE-2024-4068',
226
+ cve: 'CVE-2024-4068',
227
+ severity: 'HIGH',
228
+ package: 'braces',
229
+ affectedVersions: '< 3.0.3',
230
+ fixedVersion: '3.0.3',
231
+ description: 'braces vulnerable to uncontrolled resource consumption via crafted brace expansion patterns.',
232
+ },
233
+ {
234
+ id: 'CVE-2024-48948',
235
+ cve: 'CVE-2024-48948',
236
+ severity: 'HIGH',
237
+ package: 'elliptic',
238
+ affectedVersions: '< 6.5.6',
239
+ fixedVersion: '6.5.6',
240
+ description: 'elliptic ECDSA signature verification accepts altered signatures revealing private key bits via lattice-based fault attacks.',
241
+ },
242
+ {
243
+ id: 'CVE-2024-28849',
244
+ cve: 'CVE-2024-28849',
245
+ severity: 'MEDIUM',
246
+ package: 'follow-redirects',
247
+ affectedVersions: '< 1.15.6',
248
+ fixedVersion: '1.15.6',
249
+ description: 'follow-redirects drops sensitive authorization headers when following cross-origin HTTP to HTTPS redirects.',
250
+ },
251
+ // ═══════════════════════════════════════════════════════════════
252
+ // Python ecosystem
253
+ // ═══════════════════════════════════════════════════════════════
254
+ {
255
+ id: 'CVE-2023-24580',
256
+ cve: 'CVE-2023-24580',
257
+ severity: 'HIGH',
258
+ package: 'django',
259
+ affectedVersions: '>= 3.2 < 3.2.18 || >= 4.0 < 4.0.10 || >= 4.1 < 4.1.7',
260
+ fixedVersion: '4.1.7',
261
+ description: 'Django file upload denial of service via multipart form parser consuming excessive memory on crafted inputs.',
262
+ },
263
+ {
264
+ id: 'CVE-2023-43665',
265
+ cve: 'CVE-2023-43665',
266
+ severity: 'HIGH',
267
+ package: 'django',
268
+ affectedVersions: '>= 3.2 < 3.2.22 || >= 4.0 < 4.0.8 || >= 4.1 < 4.1.12 || >= 4.2 < 4.2.6',
269
+ fixedVersion: '4.2.6',
270
+ description: 'Django denial of service in `django.utils.text.Truncator` via extremely long unicode strings.',
271
+ },
272
+ {
273
+ id: 'CVE-2023-30861',
274
+ cve: 'CVE-2023-30861',
275
+ severity: 'HIGH',
276
+ package: 'flask',
277
+ affectedVersions: '>= 0.12 < 2.3.2',
278
+ fixedVersion: '2.3.2',
279
+ description: 'Flask cookie disclosure via permanent session cookies sent over HTTP without ensuring HTTPS enforcement.',
280
+ },
281
+ {
282
+ id: 'CVE-2023-45803',
283
+ cve: 'CVE-2023-45803',
284
+ severity: 'MEDIUM',
285
+ package: 'requests',
286
+ affectedVersions: '< 2.31.0',
287
+ fixedVersion: '2.31.0',
288
+ description: 'Requests library leaks proxy credentials via redirect to a different origin when using HTTPS proxies.',
289
+ },
290
+ {
291
+ id: 'CVE-2023-50447',
292
+ cve: 'CVE-2023-50447',
293
+ severity: 'CRITICAL',
294
+ package: 'pillow',
295
+ affectedVersions: '< 10.2.0',
296
+ fixedVersion: '10.2.0',
297
+ description: 'Pillow arbitrary code execution via environment variables passed into underlying build pipelines during image processing.',
298
+ },
299
+ {
300
+ id: 'CVE-2024-28820',
301
+ cve: 'CVE-2024-28820',
302
+ severity: 'HIGH',
303
+ package: 'aiohttp',
304
+ affectedVersions: '< 3.9.2',
305
+ fixedVersion: '3.9.2',
306
+ description: 'aiohttp HTTP request smuggling via improper validation of Content-Length and Transfer-Encoding headers.',
307
+ },
308
+ {
309
+ id: 'CVE-2023-5752',
310
+ cve: 'CVE-2023-5752',
311
+ severity: 'MEDIUM',
312
+ package: 'pip',
313
+ affectedVersions: '< 23.3',
314
+ fixedVersion: '23.3',
315
+ description: 'pip Mercurial-based installs may be subject to command injection via crafted repository URL in requirements.',
316
+ },
317
+ // ═══════════════════════════════════════════════════════════════
318
+ // Rust ecosystem (Cargo crates)
319
+ // ═══════════════════════════════════════════════════════════════
320
+ {
321
+ id: 'CVE-2024-24576',
322
+ cve: 'CVE-2024-24576',
323
+ severity: 'CRITICAL',
324
+ package: 'rustix',
325
+ affectedVersions: '< 0.38.20',
326
+ fixedVersion: '0.38.20',
327
+ description: 'rustix command injection vulnerability on Windows via crafted arguments to CreateProcess-like APIs.',
328
+ },
329
+ {
330
+ id: 'RUSTSEC-2023-0071',
331
+ severity: 'HIGH',
332
+ package: 'openssl',
333
+ affectedVersions: '< 0.10.55',
334
+ fixedVersion: '0.10.55',
335
+ description: 'OpenSSL crate exposes unsound API allowing use-after-free via `X509StoreRef` lifetime mismanagement.',
336
+ },
337
+ {
338
+ id: 'RUSTSEC-2024-0321',
339
+ severity: 'HIGH',
340
+ package: 'hyper',
341
+ affectedVersions: '>= 0.14 < 0.14.28',
342
+ fixedVersion: '0.14.28',
343
+ description: 'hyper HTTP/1 request smuggling due to incorrect handling of Content-Length headers in chunked encoding.',
344
+ },
345
+ // ═══════════════════════════════════════════════════════════════
346
+ // Go ecosystem
347
+ // ═══════════════════════════════════════════════════════════════
348
+ {
349
+ id: 'CVE-2023-45288',
350
+ cve: 'CVE-2023-45288',
351
+ severity: 'HIGH',
352
+ package: 'golang.org/x/net',
353
+ affectedVersions: '< 0.17.0',
354
+ fixedVersion: '0.17.0',
355
+ description: 'Go HTTP/2 rapid reset attack causing denial of service via unlimited CONTINUATION frames exhausting server resources.',
356
+ },
357
+ {
358
+ id: 'CVE-2023-44487',
359
+ cve: 'CVE-2023-44487',
360
+ severity: 'HIGH',
361
+ package: 'google.golang.org/grpc',
362
+ affectedVersions: '< 1.56.3',
363
+ fixedVersion: '1.56.3',
364
+ description: 'gRPC HTTP/2 rapid reset attack affecting Go gRPC servers causing CPU exhaustion.',
365
+ },
366
+ {
367
+ id: 'GHSA-qppj-fm5r-hxr3',
368
+ severity: 'MEDIUM',
369
+ package: 'github.com/gorilla/websocket',
370
+ affectedVersions: '< 1.5.1',
371
+ fixedVersion: '1.5.1',
372
+ description: 'Gorilla WebSocket denial of service via oversized control frames exhausting memory allocation.',
373
+ },
374
+ // ═══════════════════════════════════════════════════════════════
375
+ // Java ecosystem
376
+ // ═══════════════════════════════════════════════════════════════
377
+ {
378
+ id: 'CVE-2021-44228',
379
+ cve: 'CVE-2021-44228',
380
+ severity: 'CRITICAL',
381
+ package: 'org.apache.logging.log4j:log4j-core',
382
+ affectedVersions: '>= 2.0 < 2.15.0',
383
+ fixedVersion: '2.15.0',
384
+ description: 'Log4Shell: JNDI injection in log4j2 message lookup substitution allowing remote code execution via crafted log messages.',
385
+ },
386
+ {
387
+ id: 'CVE-2021-45105',
388
+ cve: 'CVE-2021-45105',
389
+ severity: 'HIGH',
390
+ package: 'org.apache.logging.log4j:log4j-core',
391
+ affectedVersions: '>= 2.0 < 2.17.0',
392
+ fixedVersion: '2.17.0',
393
+ description: 'Log4j infinite recursion in context lookup pattern causing denial of service via crafted log message input.',
394
+ },
395
+ {
396
+ id: 'CVE-2022-22965',
397
+ cve: 'CVE-2022-22965',
398
+ severity: 'CRITICAL',
399
+ package: 'org.springframework:spring-beans',
400
+ affectedVersions: '>= 5.2 < 5.2.20 || >= 5.3 < 5.3.17',
401
+ fixedVersion: '5.3.17',
402
+ description: 'Spring4Shell: remote code execution in Spring Framework via data binding to ClassLoader accessible via request parameters.',
403
+ },
404
+ {
405
+ id: 'CVE-2022-22963',
406
+ cve: 'CVE-2022-22963',
407
+ severity: 'CRITICAL',
408
+ package: 'org.springframework.cloud:spring-cloud-function',
409
+ affectedVersions: '>= 3.1 < 3.1.7 || >= 3.2 < 3.2.3',
410
+ fixedVersion: '3.2.3',
411
+ description: 'Spring Cloud Function SpEL injection via crafted Spring Expression Language in routing-expression header allowing remote code execution.',
412
+ },
413
+ {
414
+ id: 'CVE-2020-25649',
415
+ cve: 'CVE-2020-25649',
416
+ severity: 'HIGH',
417
+ package: 'com.fasterxml.jackson.core:jackson-databind',
418
+ affectedVersions: '>= 2.0 < 2.12.3',
419
+ fixedVersion: '2.12.3',
420
+ description: 'Jackson-databind deserialization of untrusted data allowing remote code execution via unsafe deserialization gadget chains.',
421
+ },
422
+ {
423
+ id: 'CVE-2023-41080',
424
+ cve: 'CVE-2023-41080',
425
+ severity: 'MEDIUM',
426
+ package: 'org.apache.tomcat.embed:tomcat-embed-core',
427
+ affectedVersions: '>= 9.0 < 9.0.79 || >= 10.0 < 10.0.27 || >= 10.1 < 10.1.10',
428
+ fixedVersion: '10.1.10',
429
+ description: 'Apache Tomcat open redirect vulnerability via FORM authentication when the ROOT webapp is deployed.',
430
+ },
431
+ // ═══════════════════════════════════════════════════════════════
432
+ // More npm entries
433
+ // ═══════════════════════════════════════════════════════════════
434
+ {
435
+ id: 'CVE-2024-4067',
436
+ cve: 'CVE-2024-4067',
437
+ severity: 'HIGH',
438
+ package: 'micromatch',
439
+ affectedVersions: '< 4.0.8',
440
+ fixedVersion: '4.0.8',
441
+ description: 'micromatch regular expression denial of service (ReDoS) via crafted glob patterns in the `braces` dependency.',
442
+ },
443
+ {
444
+ id: 'CVE-2023-45133',
445
+ cve: 'CVE-2023-45133',
446
+ severity: 'HIGH',
447
+ package: 'babel-traverse',
448
+ affectedVersions: '< 7.23.2',
449
+ fixedVersion: '7.23.2',
450
+ description: 'Babel traverse infinite loop via crafted input causing denial of service during AST traversal.',
451
+ },
452
+ ];
453
+ // ── Version helper ──
454
+ function normalizePackageName(raw, ecosystem) {
455
+ let name = raw.trim().replace(/['"]/g, '').toLowerCase();
456
+ if (ecosystem === 'java') {
457
+ // Java package names are case-sensitive but normalize colons
458
+ name = raw.trim().replace(/['"]/g, '');
459
+ }
460
+ return name;
461
+ }
462
+ // ── Public API ──
463
+ /**
464
+ * Detect which package ecosystem a project uses by checking for manifest files.
465
+ */
466
+ export function detectEcosystem(rootPath) {
467
+ if (manifestExists(rootPath, 'package.json'))
468
+ return 'npm';
469
+ if (manifestExists(rootPath, 'requirements.txt') || manifestExists(rootPath, 'Pipfile'))
470
+ return 'python';
471
+ if (manifestExists(rootPath, 'Cargo.toml'))
472
+ return 'rust';
473
+ if (manifestExists(rootPath, 'go.mod'))
474
+ return 'go';
475
+ if (manifestExists(rootPath, 'pom.xml') || manifestExists(rootPath, 'build.gradle'))
476
+ return 'java';
477
+ return 'unknown';
478
+ }
479
+ /**
480
+ * Parse dependencies from manifest files.
481
+ */
482
+ export function parseDependencies(rootPath, ecosystem) {
483
+ switch (ecosystem) {
484
+ case 'npm':
485
+ return parseNpmDeps(rootPath);
486
+ case 'python':
487
+ return parsePythonDeps(rootPath);
488
+ case 'rust':
489
+ return parseRustDeps(rootPath);
490
+ case 'go':
491
+ return parseGoDeps(rootPath);
492
+ case 'java':
493
+ return parseJavaDeps(rootPath);
494
+ default:
495
+ return [];
496
+ }
497
+ }
498
+ function parseNpmDeps(rootPath) {
499
+ try {
500
+ const raw = readManifest(rootPath, 'package.json');
501
+ const pkg = JSON.parse(raw);
502
+ const deps = [];
503
+ const addDeps = (obj) => {
504
+ if (!obj)
505
+ return;
506
+ for (const [name, version] of Object.entries(obj)) {
507
+ deps.push({ name, version: version.replace(/^[~^]/, ''), ecosystem: 'npm' });
508
+ }
509
+ };
510
+ addDeps(pkg.dependencies);
511
+ addDeps(pkg.devDependencies);
512
+ addDeps(pkg.peerDependencies);
513
+ addDeps(pkg.optionalDependencies);
514
+ return deps;
515
+ }
516
+ catch {
517
+ return [];
518
+ }
519
+ }
520
+ function parsePythonDeps(rootPath) {
521
+ try {
522
+ const raw = readManifest(rootPath, 'requirements.txt');
523
+ const deps = [];
524
+ for (const line of raw.split('\n')) {
525
+ const trimmed = line.trim();
526
+ if (!trimmed || trimmed.startsWith('#') || trimmed.startsWith('-'))
527
+ continue;
528
+ const m = trimmed.match(/^([A-Za-z0-9_.-]+)\s*([><=!~]+)\s*([A-Za-z0-9_.*]+)/);
529
+ if (m) {
530
+ deps.push({ name: m[1].toLowerCase(), version: m[3].replace(/[*]/g, '0'), ecosystem: 'python' });
531
+ }
532
+ else {
533
+ const nameOnly = trimmed.match(/^([A-Za-z0-9_.-]+)/);
534
+ if (nameOnly) {
535
+ deps.push({ name: nameOnly[1].toLowerCase(), version: '0.0.0', ecosystem: 'python' });
536
+ }
537
+ }
538
+ }
539
+ return deps;
540
+ }
541
+ catch {
542
+ return [];
543
+ }
544
+ }
545
+ function parseRustDeps(rootPath) {
546
+ try {
547
+ const raw = readManifest(rootPath, 'Cargo.toml');
548
+ const deps = [];
549
+ // Match [dependencies] section
550
+ const sectionMatch = raw.match(/\[dependencies\]([\s\S]*?)(?=\n\[|$)/);
551
+ if (!sectionMatch)
552
+ return deps;
553
+ const section = sectionMatch[1];
554
+ const re = /^([A-Za-z0-9_-]+)\s*=\s*"(.*?)"/gm;
555
+ let m;
556
+ while ((m = re.exec(section)) !== null) {
557
+ const version = (m[2] || '').replace(/^[~^]/, '');
558
+ deps.push({ name: m[1], version, ecosystem: 'rust' });
559
+ }
560
+ return deps;
561
+ }
562
+ catch {
563
+ return [];
564
+ }
565
+ }
566
+ function parseGoDeps(rootPath) {
567
+ try {
568
+ const raw = readManifest(rootPath, 'go.mod');
569
+ const deps = [];
570
+ const inRequire = /^require\s*\(([\s\S]*?)\)/gm;
571
+ let blockMatch;
572
+ while ((blockMatch = inRequire.exec(raw)) !== null) {
573
+ const block = blockMatch[1];
574
+ const lineRe = /^\s*([^\s]+)\s+v?([^\s]+)/gm;
575
+ let lineMatch;
576
+ while ((lineMatch = lineRe.exec(block)) !== null) {
577
+ deps.push({ name: lineMatch[1], version: lineMatch[2], ecosystem: 'go' });
578
+ }
579
+ }
580
+ // Single-line require
581
+ const singleRe = /^require\s+([^\s]+)\s+v?([^\s]+)/gm;
582
+ let singleMatch;
583
+ while ((singleMatch = singleRe.exec(raw)) !== null) {
584
+ deps.push({ name: singleMatch[1], version: singleMatch[2], ecosystem: 'go' });
585
+ }
586
+ return deps;
587
+ }
588
+ catch {
589
+ return [];
590
+ }
591
+ }
592
+ function parseJavaDeps(rootPath) {
593
+ try {
594
+ if (manifestExists(rootPath, 'pom.xml')) {
595
+ return parsePomXml(rootPath);
596
+ }
597
+ if (manifestExists(rootPath, 'build.gradle')) {
598
+ return parseGradleDeps(rootPath);
599
+ }
600
+ return [];
601
+ }
602
+ catch {
603
+ return [];
604
+ }
605
+ }
606
+ function parsePomXml(rootPath) {
607
+ try {
608
+ const raw = readManifest(rootPath, 'pom.xml');
609
+ const deps = [];
610
+ const depRe = /<dependency>\s*<groupId>([^<]+)<\/groupId>\s*<artifactId>([^<]+)<\/artifactId>\s*<version>([^<]+)<\/version>/g;
611
+ let m;
612
+ while ((m = depRe.exec(raw)) !== null) {
613
+ const name = `${m[1]}:${m[2]}`;
614
+ deps.push({ name, version: m[3], ecosystem: 'java' });
615
+ }
616
+ return deps;
617
+ }
618
+ catch {
619
+ return [];
620
+ }
621
+ }
622
+ function parseGradleDeps(rootPath) {
623
+ try {
624
+ const raw = readManifest(rootPath, 'build.gradle');
625
+ const deps = [];
626
+ const depRe = /(?:implementation|compile|api|testImplementation|runtimeOnly)\s*\(?\s*['"]([^:'"]+):([^:'"]+):([^:'"]+)['"]\s*\)?/g;
627
+ let m;
628
+ while ((m = depRe.exec(raw)) !== null) {
629
+ const name = `${m[1]}:${m[2]}`;
630
+ deps.push({ name, version: m[3], ecosystem: 'java' });
631
+ }
632
+ return deps;
633
+ }
634
+ catch {
635
+ return [];
636
+ }
637
+ }
638
+ /**
639
+ * Check dependencies against known vulnerabilities (offline database).
640
+ */
641
+ export function checkVulnerabilities(deps) {
642
+ const ecosystems = new Set();
643
+ const findings = [];
644
+ for (const dep of deps) {
645
+ ecosystems.add(dep.ecosystem);
646
+ for (const cve of CVE_DATABASE) {
647
+ const cvePkg = cve.package.toLowerCase();
648
+ const depName = dep.name.toLowerCase();
649
+ if (cvePkg !== depName)
650
+ continue;
651
+ const version = dep.version;
652
+ if (!version || version === '*') {
653
+ findings.push(cve);
654
+ continue;
655
+ }
656
+ if (satisfiesRange(version, cve.affectedVersions)) {
657
+ findings.push(cve);
658
+ }
659
+ }
660
+ }
661
+ // Deduplicate by vulnerability ID
662
+ const seen = new Set();
663
+ const uniqueFindings = findings.filter((f) => {
664
+ if (seen.has(f.id))
665
+ return false;
666
+ seen.add(f.id);
667
+ return true;
668
+ });
669
+ const primaryEcosystem = ecosystems.size === 1 ? [...ecosystems][0] : 'unknown';
670
+ return {
671
+ ecosystem: primaryEcosystem,
672
+ totalDependencies: deps.length,
673
+ vulnerableDependencies: uniqueFindings.length,
674
+ findings: uniqueFindings,
675
+ };
676
+ }
677
+ /**
678
+ * Full audit: detect ecosystem → parse dependencies → check vulnerabilities.
679
+ */
680
+ export function auditDependencies(rootPath) {
681
+ const ecosystem = detectEcosystem(rootPath);
682
+ const deps = parseDependencies(rootPath, ecosystem);
683
+ return checkVulnerabilities(deps);
684
+ }
685
+ //# sourceMappingURL=deps.js.map