dep-oracle 1.1.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +210 -47
- package/README.tr.md +259 -115
- package/dist/mcp/server.js +14 -1
- package/dist/mcp/server.js.map +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -1,13 +1,31 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<h1 align="center">dep-oracle</h1>
|
|
3
|
+
<p align="center"><strong>Predictive Dependency Security Engine</strong></p>
|
|
4
|
+
<p align="center">
|
|
5
|
+
<a href="https://www.npmjs.com/package/dep-oracle"><img src="https://img.shields.io/npm/v/dep-oracle.svg" alt="npm version"></a>
|
|
6
|
+
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT"></a>
|
|
7
|
+
<a href="https://www.npmjs.com/package/dep-oracle"><img src="https://img.shields.io/npm/dm/dep-oracle.svg" alt="npm downloads"></a>
|
|
8
|
+
<a href="https://github.com/ertugrulakben/dep-oracle"><img src="https://img.shields.io/github/stars/ertugrulakben/dep-oracle.svg?style=social" alt="GitHub stars"></a>
|
|
9
|
+
</p>
|
|
10
|
+
<p align="center">
|
|
11
|
+
<a href="#quick-start">Quick Start</a> ·
|
|
12
|
+
<a href="#features">Features</a> ·
|
|
13
|
+
<a href="#trust-score-algorithm">Algorithm</a> ·
|
|
14
|
+
<a href="#claude-code-integration-mcp">MCP</a> ·
|
|
15
|
+
<a href="#comparison">Comparison</a>
|
|
16
|
+
</p>
|
|
17
|
+
<p align="center">
|
|
18
|
+
<strong>English</strong> | <a href="README.tr.md">Turkce</a>
|
|
19
|
+
</p>
|
|
20
|
+
</p>
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
> **Your dependencies have dependencies. Who's watching them?**
|
|
6
25
|
|
|
7
26
|
**dep-oracle** is a predictive dependency security engine that calculates **Trust Scores** (0-100) for every package in your dependency tree. It detects zombie dependencies, measures blast radius, catches typosquatting attempts, and predicts future risks — before they become vulnerabilities.
|
|
8
27
|
|
|
9
|
-
|
|
10
|
-
[](https://opensource.org/licenses/MIT)
|
|
28
|
+
**Claude Code Security** scans YOUR code. **dep-oracle** scans everything your code **depends on**.
|
|
11
29
|
|
|
12
30
|
## Why?
|
|
13
31
|
|
|
@@ -16,8 +34,6 @@
|
|
|
16
34
|
- `npm audit` only catches **known** CVEs — dep-oracle **predicts** future risks
|
|
17
35
|
- You audit your code. But do you audit your **trust**?
|
|
18
36
|
|
|
19
|
-
**Claude Code Security** scans YOUR code. **dep-oracle** scans everything your code **depends on**.
|
|
20
|
-
|
|
21
37
|
## Quick Start
|
|
22
38
|
|
|
23
39
|
```bash
|
|
@@ -27,19 +43,25 @@ npx dep-oracle
|
|
|
27
43
|
# Or install globally
|
|
28
44
|
npm install -g dep-oracle
|
|
29
45
|
dep-oracle scan
|
|
46
|
+
|
|
47
|
+
# Check a single package
|
|
48
|
+
dep-oracle check express
|
|
30
49
|
```
|
|
31
50
|
|
|
32
|
-
##
|
|
51
|
+
## Features
|
|
33
52
|
|
|
34
53
|
| Feature | Description |
|
|
35
54
|
|---------|-------------|
|
|
36
|
-
| **Trust Score** | 0-100 weighted score per package (maintainer health,
|
|
55
|
+
| **Trust Score** | 0-100 weighted score per package (security, maintainer health, activity, popularity, funding, license) |
|
|
37
56
|
| **Zombie Detection** | Finds unmaintained but critical packages (no commits in 12+ months) |
|
|
38
57
|
| **Blast Radius** | Shows how many files are affected if a dependency is compromised |
|
|
39
|
-
| **Typosquat Detection** |
|
|
40
|
-
| **Trend Prediction** | 3-month risk projection based on download/commit trends |
|
|
41
|
-
| **Migration Advisor** |
|
|
58
|
+
| **Typosquat Detection** | 1,847+ known packages + live npm registry lookup to catch suspicious names |
|
|
59
|
+
| **Trend Prediction** | 3-month risk projection based on download/commit/release trends |
|
|
60
|
+
| **Migration Advisor** | 131 package mappings with 192 safer alternatives for risky dependencies |
|
|
42
61
|
| **Offline Mode** | Works from cache without internet (`--offline`) |
|
|
62
|
+
| **MCP Server** | Native Claude Code integration — ask about your dependencies in natural language |
|
|
63
|
+
| **Multi-Format Output** | Terminal (colored tree), HTML, JSON, and SARIF |
|
|
64
|
+
| **GitHub Action** | Automate trust checks in your CI/CD pipeline |
|
|
43
65
|
|
|
44
66
|
## Usage
|
|
45
67
|
|
|
@@ -47,28 +69,32 @@ dep-oracle scan
|
|
|
47
69
|
# Scan current project
|
|
48
70
|
dep-oracle scan
|
|
49
71
|
|
|
50
|
-
# Scan with specific output
|
|
72
|
+
# Scan with specific output format
|
|
51
73
|
dep-oracle scan --format json
|
|
52
74
|
dep-oracle scan --format html
|
|
53
75
|
dep-oracle scan --format sarif
|
|
54
76
|
|
|
55
77
|
# Check a single package
|
|
56
78
|
dep-oracle check lodash
|
|
79
|
+
dep-oracle check express@4.18.2
|
|
57
80
|
|
|
58
|
-
# Offline mode (uses cached data)
|
|
81
|
+
# Offline mode (uses cached data only)
|
|
59
82
|
dep-oracle scan --offline
|
|
60
83
|
|
|
61
|
-
# Set minimum score threshold (
|
|
84
|
+
# Set minimum score threshold (exit code 1 if below)
|
|
62
85
|
dep-oracle scan --threshold 60
|
|
63
86
|
|
|
64
87
|
# Ignore specific packages
|
|
65
88
|
dep-oracle scan --ignore deprecated-but-needed,legacy-pkg
|
|
89
|
+
|
|
90
|
+
# Verbose logging
|
|
91
|
+
dep-oracle scan --verbose
|
|
66
92
|
```
|
|
67
93
|
|
|
68
94
|
## Output Example
|
|
69
95
|
|
|
70
96
|
```
|
|
71
|
-
|
|
97
|
+
dep-oracle v1.1.0
|
|
72
98
|
Scanning package.json...
|
|
73
99
|
Found 47 direct dependencies, 683 transitive
|
|
74
100
|
Collecting data... [=============================] 100% (2.3s)
|
|
@@ -76,19 +102,19 @@ Collecting data... [=============================] 100% (2.3s)
|
|
|
76
102
|
DEPENDENCY TRUST REPORT
|
|
77
103
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
78
104
|
|
|
79
|
-
|
|
105
|
+
CRITICAL (score < 50)
|
|
80
106
|
|
|
81
|
-
■ event-stream@3.3.6 Score: 12
|
|
107
|
+
■ event-stream@3.3.6 Score: 12 ZOMBIE
|
|
82
108
|
Last commit: 2018 | 0 maintainers active
|
|
83
109
|
Blast radius: 14 files | Alternative: highland
|
|
84
110
|
|
|
85
|
-
|
|
111
|
+
WARNING (score 50-79)
|
|
86
112
|
|
|
87
|
-
■ moment@2.29.4 Score: 58
|
|
113
|
+
■ moment@2.29.4 Score: 58 ZOMBIE
|
|
88
114
|
Maintenance mode | No new features
|
|
89
|
-
Blast radius: 23 files | Alternative: dayjs
|
|
115
|
+
Blast radius: 23 files | Alternative: dayjs, date-fns, luxon
|
|
90
116
|
|
|
91
|
-
|
|
117
|
+
SAFE (score 80+): 679 packages
|
|
92
118
|
|
|
93
119
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
94
120
|
SUMMARY
|
|
@@ -103,14 +129,63 @@ Each package is scored 0-100 based on six weighted metrics:
|
|
|
103
129
|
|
|
104
130
|
| Metric | Weight | What It Measures |
|
|
105
131
|
|--------|--------|------------------|
|
|
106
|
-
| Security History | 25% | CVE count, average patch time,
|
|
132
|
+
| Security History | 25% | CVE count with diminishing penalty, average patch time, fast-patch bonus |
|
|
107
133
|
| Maintainer Health | 25% | Active maintainers (bus factor), issue response time, PR merge speed |
|
|
108
|
-
| Activity | 20% | Commit frequency trend, release cadence, last publish
|
|
134
|
+
| Activity | 20% | Commit frequency trend, release cadence, last publish recency |
|
|
109
135
|
| Popularity | 15% | Weekly downloads, dependent count, GitHub stars |
|
|
110
136
|
| Funding | 10% | GitHub Sponsors, OpenCollective, corporate backing |
|
|
111
137
|
| License | 5% | MIT/Apache = safe, GPL = risk, Unknown = red flag |
|
|
112
138
|
|
|
113
|
-
**Score Ranges:** 80-100
|
|
139
|
+
**Score Ranges:** 80-100 Safe | 50-79 Warning | 0-49 Critical
|
|
140
|
+
|
|
141
|
+
### Security Scoring (v1.1.0)
|
|
142
|
+
|
|
143
|
+
The security metric uses a **diminishing penalty** model — the first vulnerability has the highest impact, and each additional one has progressively less effect:
|
|
144
|
+
|
|
145
|
+
| Vulnerabilities | Security Score |
|
|
146
|
+
|-----------------|---------------|
|
|
147
|
+
| 0 | 100 |
|
|
148
|
+
| 1 | 85 |
|
|
149
|
+
| 2 | 72 |
|
|
150
|
+
| 3 | 60 |
|
|
151
|
+
| 4 | 50 |
|
|
152
|
+
| 5+ | max(20, 100 - n*12) |
|
|
153
|
+
|
|
154
|
+
Packages that patch vulnerabilities quickly (within 7 days) receive a **+10 bonus**. Slower patches (within 30 days) receive **+5**.
|
|
155
|
+
|
|
156
|
+
### Graceful Degradation
|
|
157
|
+
|
|
158
|
+
If an API is unreachable (GitHub down, no internet, rate limited), dep-oracle doesn't crash. The missing metric weight is redistributed across available metrics. If 3+ metrics are unavailable, a reliability warning is shown.
|
|
159
|
+
|
|
160
|
+
## Typosquat Detection
|
|
161
|
+
|
|
162
|
+
dep-oracle uses a multi-layer approach to catch typosquatting:
|
|
163
|
+
|
|
164
|
+
1. **Static registry** — 1,847+ known popular package names across 40+ categories (React, Vue, Angular, Express, testing, CLI tools, etc.)
|
|
165
|
+
2. **Dynamic npm lookup** — Fetches the top 5,000 most-downloaded packages from npm and caches them for 7 days
|
|
166
|
+
3. **Pattern matching** — Levenshtein distance, prefix/suffix manipulation, character swap, missing/extra letter detection
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
dep-oracle check expresss # Catches: similar to "express" (distance: 1)
|
|
170
|
+
dep-oracle check lodashe # Catches: similar to "lodash" (distance: 1)
|
|
171
|
+
dep-oracle check react-js # Catches: suffix pattern of "react"
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Migration Advisor
|
|
175
|
+
|
|
176
|
+
When a package scores low or is flagged as a zombie, dep-oracle suggests safer alternatives from a curated database of **131 package mappings** with **192 alternatives**:
|
|
177
|
+
|
|
178
|
+
```
|
|
179
|
+
moment → dayjs, date-fns, luxon
|
|
180
|
+
request → axios, got, node-fetch, undici
|
|
181
|
+
lodash → lodash-es, radash, just (native alternatives)
|
|
182
|
+
express → fastify, koa, hono
|
|
183
|
+
gulp → esbuild, tsup, vite
|
|
184
|
+
mocha → vitest, jest, node:test
|
|
185
|
+
...and 125 more
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Each suggestion includes difficulty rating (easy/moderate/hard) and migration context.
|
|
114
189
|
|
|
115
190
|
## Claude Code Integration (MCP)
|
|
116
191
|
|
|
@@ -129,9 +204,20 @@ dep-oracle works as an MCP server for Claude Code:
|
|
|
129
204
|
```
|
|
130
205
|
|
|
131
206
|
Then in Claude Code, just ask:
|
|
132
|
-
- "What's the riskiest dependency in this project?"
|
|
133
|
-
- "Is lodash safe to use?"
|
|
134
|
-
- "Show me zombie dependencies"
|
|
207
|
+
- *"What's the riskiest dependency in this project?"*
|
|
208
|
+
- *"Is lodash safe to use?"*
|
|
209
|
+
- *"Show me zombie dependencies"*
|
|
210
|
+
- *"Suggest alternatives for moment.js"*
|
|
211
|
+
|
|
212
|
+
**Available MCP Tools:**
|
|
213
|
+
|
|
214
|
+
| Tool | Description |
|
|
215
|
+
|------|-------------|
|
|
216
|
+
| `dep_oracle_scan` | Full project dependency scan |
|
|
217
|
+
| `dep_oracle_trust_score` | Trust score for a single package |
|
|
218
|
+
| `dep_oracle_blast_radius` | Impact analysis for a package |
|
|
219
|
+
| `dep_oracle_zombies` | List all zombie dependencies |
|
|
220
|
+
| `dep_oracle_suggest_migration` | Get alternative package suggestions |
|
|
135
221
|
|
|
136
222
|
## GitHub Action
|
|
137
223
|
|
|
@@ -176,35 +262,112 @@ Or add to `package.json`:
|
|
|
176
262
|
}
|
|
177
263
|
```
|
|
178
264
|
|
|
265
|
+
### Configuration Options
|
|
266
|
+
|
|
267
|
+
| Option | Default | Description |
|
|
268
|
+
|--------|---------|-------------|
|
|
269
|
+
| `threshold` | `60` | Minimum trust score. Packages below trigger warnings and non-zero exit |
|
|
270
|
+
| `ignore` | `[]` | Packages to skip during scanning |
|
|
271
|
+
| `format` | `"terminal"` | Output format: `terminal`, `json`, `html`, `sarif` |
|
|
272
|
+
| `offline` | `false` | Use only cached data, skip all API calls |
|
|
273
|
+
| `githubToken` | `null` | GitHub token for higher API rate limits (5000/hr vs 60/hr) |
|
|
274
|
+
| `cacheTtl` | `86400` | Cache TTL in seconds (default: 24 hours) |
|
|
275
|
+
|
|
179
276
|
## Supported Package Managers
|
|
180
277
|
|
|
181
278
|
| Manager | Manifest | Lock File | Status |
|
|
182
279
|
|---------|----------|-----------|--------|
|
|
183
|
-
| npm | `package.json` | `package-lock.json` |
|
|
184
|
-
| yarn | `package.json` | `yarn.lock` |
|
|
185
|
-
| pnpm | `package.json` | `pnpm-lock.yaml` |
|
|
186
|
-
| pip | `requirements.txt` | `Pipfile.lock` |
|
|
187
|
-
| poetry | `pyproject.toml` | `poetry.lock` |
|
|
280
|
+
| npm | `package.json` | `package-lock.json` | Supported |
|
|
281
|
+
| yarn | `package.json` | `yarn.lock` | Supported |
|
|
282
|
+
| pnpm | `package.json` | `pnpm-lock.yaml` | Supported |
|
|
283
|
+
| pip | `requirements.txt` | `Pipfile.lock` | Supported |
|
|
284
|
+
| poetry | `pyproject.toml` | `poetry.lock` | Supported |
|
|
188
285
|
|
|
189
286
|
## Comparison
|
|
190
287
|
|
|
191
288
|
| Feature | npm audit | Dependabot | Socket.dev | Snyk | **dep-oracle** |
|
|
192
289
|
|---------|-----------|------------|------------|------|----------------|
|
|
193
|
-
| Known CVE scan |
|
|
194
|
-
| Predictive risk |
|
|
195
|
-
| Trust Score (0-100) |
|
|
196
|
-
| Zombie detection |
|
|
197
|
-
| Blast radius |
|
|
198
|
-
| Typosquat detection |
|
|
199
|
-
| Trend prediction |
|
|
200
|
-
|
|
|
201
|
-
|
|
|
202
|
-
|
|
|
290
|
+
| Known CVE scan | Yes | Yes | Yes | Yes | **Yes** |
|
|
291
|
+
| Predictive risk | No | No | Partial | No | **Yes** |
|
|
292
|
+
| Trust Score (0-100) | No | No | No | No | **Yes** |
|
|
293
|
+
| Zombie detection | No | No | No | No | **Yes** |
|
|
294
|
+
| Blast radius | No | No | No | No | **Yes** |
|
|
295
|
+
| Typosquat detection | No | No | Yes | No | **Yes** |
|
|
296
|
+
| Trend prediction | No | No | No | No | **Yes** |
|
|
297
|
+
| Migration advisor | No | Partial | No | Partial | **Yes (131 pkgs)** |
|
|
298
|
+
| MCP integration | No | No | Yes | Yes | **Yes** |
|
|
299
|
+
| Zero install (npx) | Yes | No | No | No | **Yes** |
|
|
300
|
+
| Free & open source | Yes | Yes | Freemium | Freemium | **Yes** |
|
|
301
|
+
|
|
302
|
+
## Programmatic API
|
|
303
|
+
|
|
304
|
+
```typescript
|
|
305
|
+
import { scan, checkPackage } from 'dep-oracle';
|
|
306
|
+
|
|
307
|
+
// Scan a project
|
|
308
|
+
const report = await scan({ dir: './my-project', format: 'json' });
|
|
309
|
+
|
|
310
|
+
// Check a single package
|
|
311
|
+
const result = await checkPackage('express');
|
|
312
|
+
console.log(result.trustScore); // 74
|
|
313
|
+
console.log(result.isZombie); // false
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
## Test Suite
|
|
317
|
+
|
|
318
|
+
dep-oracle has comprehensive test coverage:
|
|
319
|
+
|
|
320
|
+
```
|
|
321
|
+
10 test files | 144 tests | 100% passing
|
|
322
|
+
|
|
323
|
+
trust-score.test.ts 34 tests Scoring engine, metrics, edge cases
|
|
324
|
+
zombie-detector.test.ts 10 tests Zombie detection logic
|
|
325
|
+
typosquat.test.ts 15 tests Typosquat pattern matching
|
|
326
|
+
migration-advisor.test.ts 12 tests Migration suggestions
|
|
327
|
+
trend-predictor.test.ts 10 tests Trend prediction engine
|
|
328
|
+
parsers.test.ts 17 tests npm + Python parsers
|
|
329
|
+
cache.test.ts 15 tests Cache store operations
|
|
330
|
+
logger.test.ts 17 tests Logger utility
|
|
331
|
+
rate-limiter.test.ts 6 tests Rate limiter
|
|
332
|
+
schema.test.ts 8 tests Zod schema validation
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
```bash
|
|
336
|
+
npm test # Run all tests
|
|
337
|
+
npm run lint # TypeScript type checking
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
## Changelog
|
|
341
|
+
|
|
342
|
+
### v1.1.0 (2025-02-22)
|
|
343
|
+
|
|
344
|
+
- **Typosquat Detection**: Expanded to 1,847+ known packages across 40+ categories, plus dynamic npm registry fetch (top 5,000 packages, 7-day cache)
|
|
345
|
+
- **Migration Advisor**: Expanded to 131 package mappings with 192 safer alternatives
|
|
346
|
+
- **Trust Score Calibration**: Diminishing vulnerability penalty (first CVE has highest impact), fast-patch bonus (+10 for <=7 days)
|
|
347
|
+
- **Poetry.lock Support**: Full poetry.lock parsing for Python projects
|
|
348
|
+
- **Comprehensive Test Suite**: 10 test files, 144 tests covering all analyzers, parsers, cache, and utilities
|
|
349
|
+
- **Turkish README**: Full Turkish documentation (README.tr.md)
|
|
350
|
+
- **Dynamic CLI Version**: Version automatically synced from package.json
|
|
351
|
+
|
|
352
|
+
### v1.0.0 (2025-02-22)
|
|
353
|
+
|
|
354
|
+
- Initial release
|
|
355
|
+
- Trust Score engine with 6 weighted metrics
|
|
356
|
+
- npm + Python (pip, poetry, pyproject.toml) parsers
|
|
357
|
+
- Zombie detection, blast radius analysis
|
|
358
|
+
- Typosquat detection with Levenshtein distance
|
|
359
|
+
- Trend prediction (3-month risk projection)
|
|
360
|
+
- Migration advisor with curated alternatives
|
|
361
|
+
- Terminal, HTML, JSON, SARIF output formats
|
|
362
|
+
- MCP server for Claude Code integration
|
|
363
|
+
- GitHub Action support
|
|
364
|
+
- Offline mode with SQLite-compatible cache
|
|
365
|
+
- Badge generator (SVG)
|
|
203
366
|
|
|
204
367
|
## Contributing
|
|
205
368
|
|
|
206
|
-
See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, coding standards, and how to add new collectors
|
|
369
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, coding standards, and how to add new collectors, parsers, or analyzers.
|
|
207
370
|
|
|
208
371
|
## License
|
|
209
372
|
|
|
210
|
-
[MIT](LICENSE) — Ertugrul Akben
|
|
373
|
+
[MIT](LICENSE) — [Ertugrul Akben](https://ertugrulakben.com)
|
package/README.tr.md
CHANGED
|
@@ -1,138 +1,212 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
>
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<h1 align="center">dep-oracle</h1>
|
|
3
|
+
<p align="center"><strong>Prediktif Bağımlılık Güvenlik Motoru</strong></p>
|
|
4
|
+
<p align="center">
|
|
5
|
+
<a href="https://www.npmjs.com/package/dep-oracle"><img src="https://img.shields.io/npm/v/dep-oracle.svg" alt="npm version"></a>
|
|
6
|
+
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT"></a>
|
|
7
|
+
<a href="https://www.npmjs.com/package/dep-oracle"><img src="https://img.shields.io/npm/dm/dep-oracle.svg" alt="npm downloads"></a>
|
|
8
|
+
<a href="https://github.com/ertugrulakben/dep-oracle"><img src="https://img.shields.io/github/stars/ertugrulakben/dep-oracle.svg?style=social" alt="GitHub stars"></a>
|
|
9
|
+
</p>
|
|
10
|
+
<p align="center">
|
|
11
|
+
<a href="#hızlı-başlangıç">Hızlı Başlangıç</a> ·
|
|
12
|
+
<a href="#özellikler">Özellikler</a> ·
|
|
13
|
+
<a href="#güven-skoru-algoritması">Algoritma</a> ·
|
|
14
|
+
<a href="#claude-code-entegrasyonu-mcp">MCP</a> ·
|
|
15
|
+
<a href="#karşılaştırma">Karşılaştırma</a>
|
|
16
|
+
</p>
|
|
17
|
+
<p align="center">
|
|
18
|
+
<a href="README.md">English</a> | <strong>Türkçe</strong>
|
|
19
|
+
</p>
|
|
20
|
+
</p>
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
> **Bağımlılıklarının bağımlılıkları var. Kim kontrol ediyor?**
|
|
25
|
+
|
|
26
|
+
**dep-oracle**, bağımlılık ağacındaki her paket için **Güven Skoru** (0-100) hesaplayan prediktif bir bağımlılık güvenlik motorudur. Zombi bağımlılıkları tespit eder, patlama yarıçapını ölçer, typosquatting girişimlerini yakalar ve gelecekteki riskleri — daha güvenlik açığına dönüşmeden — önceden tahmin eder.
|
|
27
|
+
|
|
28
|
+
**Claude Code Security** sizin kodunuzu tarar. **dep-oracle** ise kodunuzun **bağımlı olduğu her şeyi** tarar.
|
|
9
29
|
|
|
10
30
|
## Neden dep-oracle?
|
|
11
31
|
|
|
12
|
-
Tedarik zinciri
|
|
32
|
+
Tedarik zinciri saldırıları (supply chain attacks) her yıl daha büyük bir tehdit haline geliyor:
|
|
13
33
|
|
|
14
|
-
- **2025'teki
|
|
15
|
-
- Ortalama bir projede **683
|
|
16
|
-
- `npm audit`
|
|
17
|
-
- Kendi kodunuzu denetliyorsunuz. Peki
|
|
34
|
+
- **2025'teki güvenlik ihlallerinin %62'si** tedarik zinciri saldırıları kaynaklı
|
|
35
|
+
- Ortalama bir projede **683 geçişli (transitive) bağımlılık** bulunuyor
|
|
36
|
+
- `npm audit` yalnızca **bilinen** CVE'leri yakalayabiliyor — dep-oracle gelecekteki riskleri **tahmin ediyor**
|
|
37
|
+
- Kendi kodunuzu denetliyorsunuz. Peki bağımlılık zincirinizi de denetliyor musunuz?
|
|
18
38
|
|
|
19
|
-
|
|
39
|
+
Türkiye'deki yazılım ekosistemi hızla büyüyor. Startup'lardan kurumsallara, e-ticaret projelerinden fintech uygulamalarına kadar her yerde npm, pip ve yarn paketleri kullanılıyor. Ancak `node_modules` klasörünün içinde ne olduğunu kaç kişi gerçekten biliyor? Bir paket maintainer'ı hesabını bırakırsa, bir bağımlılık yıllardır güncellenmiyorsa ya da ismini popüler bir paketten değiştirip kötü amaçlı kod enjekte eden biri varsa — dep-oracle tam da bu noktalarda devreye giriyor.
|
|
20
40
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
## Hizli Baslangic
|
|
41
|
+
## Hızlı Başlangıç
|
|
24
42
|
|
|
25
43
|
```bash
|
|
26
|
-
# Kurulum gerektirmez
|
|
44
|
+
# Kurulum gerektirmez — doğrudan çalıştırın
|
|
27
45
|
npx dep-oracle
|
|
28
46
|
|
|
29
|
-
# Ya da global olarak
|
|
47
|
+
# Ya da global olarak yükleyin
|
|
30
48
|
npm install -g dep-oracle
|
|
31
49
|
dep-oracle scan
|
|
32
|
-
```
|
|
33
50
|
|
|
34
|
-
Tek bir
|
|
51
|
+
# Tek bir paketi kontrol edin
|
|
52
|
+
dep-oracle check express
|
|
53
|
+
```
|
|
35
54
|
|
|
36
|
-
##
|
|
55
|
+
## Özellikler
|
|
37
56
|
|
|
38
|
-
|
|
|
57
|
+
| Özellik | Açıklama |
|
|
39
58
|
|---------|----------|
|
|
40
|
-
| **
|
|
41
|
-
| **Zombi Tespiti** | Kritik ama
|
|
42
|
-
| **Patlama
|
|
43
|
-
| **Typosquat Tespiti** |
|
|
44
|
-
| **Trend Tahmini** |
|
|
45
|
-
| **
|
|
46
|
-
|
|
|
47
|
-
| **MCP
|
|
48
|
-
|
|
|
49
|
-
| **
|
|
50
|
-
|
|
51
|
-
##
|
|
59
|
+
| **Güven Skoru** | Her paket için 0-100 arası ağırlıklı skor (güvenlik, maintainer sağlığı, aktivite, popülarite, fonlama, lisans) |
|
|
60
|
+
| **Zombi Tespiti** | Kritik ama bakımsız paketleri bulur (12+ aydır commit yok) |
|
|
61
|
+
| **Patlama Yarıçapı** | Bir bağımlılık ele geçirilirse kaç dosyanın etkileneceğini gösterir |
|
|
62
|
+
| **Typosquat Tespiti** | 1.847+ bilinen paket + canlı npm registry sorgusu ile şüpheli isimleri yakalar |
|
|
63
|
+
| **Trend Tahmini** | İndirme/commit/release trendlerine dayalı 3 aylık risk projeksiyonu |
|
|
64
|
+
| **Göç Danışmanı** | 131 paket eşleşmesi ve 192 daha güvenli alternatif önerisi |
|
|
65
|
+
| **Çevrimdışı Mod** | İnternet olmadan önbellekten çalışır (`--offline`) |
|
|
66
|
+
| **MCP Sunucusu** | Claude Code ile doğal dilde bağımlılık sorgulama |
|
|
67
|
+
| **Çoklu Format** | Terminal (renkli ağaç), HTML, JSON ve SARIF çıktısı |
|
|
68
|
+
| **GitHub Action** | CI/CD pipeline'ında otomatik güven kontrolü |
|
|
69
|
+
|
|
70
|
+
## Kullanım
|
|
52
71
|
|
|
53
72
|
```bash
|
|
54
73
|
# Mevcut projeyi tara
|
|
55
74
|
dep-oracle scan
|
|
56
75
|
|
|
57
|
-
#
|
|
76
|
+
# Farklı formatlarda çıktı al
|
|
58
77
|
dep-oracle scan --format json
|
|
59
78
|
dep-oracle scan --format html
|
|
60
79
|
dep-oracle scan --format sarif
|
|
61
80
|
|
|
62
81
|
# Tek bir paketi kontrol et
|
|
63
82
|
dep-oracle check lodash
|
|
83
|
+
dep-oracle check express@4.18.2
|
|
64
84
|
|
|
65
|
-
#
|
|
85
|
+
# Çevrimdışı mod (yalnızca önbellek kullanılır)
|
|
66
86
|
dep-oracle scan --offline
|
|
67
87
|
|
|
68
|
-
# Minimum skor
|
|
88
|
+
# Minimum skor eşiği belirle (altındaysa çıkış kodu 1)
|
|
69
89
|
dep-oracle scan --threshold 60
|
|
70
90
|
|
|
71
91
|
# Belirli paketleri yoksay
|
|
72
92
|
dep-oracle scan --ignore deprecated-but-needed,legacy-pkg
|
|
93
|
+
|
|
94
|
+
# Ayrıntılı loglama
|
|
95
|
+
dep-oracle scan --verbose
|
|
73
96
|
```
|
|
74
97
|
|
|
75
|
-
##
|
|
98
|
+
## Çıktı Örneği
|
|
76
99
|
|
|
77
100
|
```
|
|
78
|
-
dep-oracle v1.
|
|
79
|
-
package.json
|
|
80
|
-
47
|
|
81
|
-
Veri
|
|
101
|
+
dep-oracle v1.1.0
|
|
102
|
+
package.json taranıyor...
|
|
103
|
+
47 doğrudan bağımlılık, 683 geçişli bağımlılık bulundu
|
|
104
|
+
Veri toplanıyor... [=============================] 100% (2.3s)
|
|
82
105
|
|
|
83
|
-
|
|
106
|
+
BAĞIMLILIK GÜVEN RAPORU
|
|
107
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
84
108
|
|
|
85
|
-
|
|
109
|
+
KRİTİK (skor < 50)
|
|
86
110
|
|
|
87
|
-
event-stream@3.3.6 Skor: 12
|
|
111
|
+
■ event-stream@3.3.6 Skor: 12 ZOMBİ
|
|
88
112
|
Son commit: 2018 | 0 aktif maintainer
|
|
89
|
-
Patlama
|
|
113
|
+
Patlama yarıçapı: 14 dosya | Alternatif: highland
|
|
90
114
|
|
|
91
|
-
UYARI (skor 50-79)
|
|
115
|
+
UYARI (skor 50-79)
|
|
92
116
|
|
|
93
|
-
moment@2.29.4 Skor: 58
|
|
94
|
-
|
|
95
|
-
Patlama
|
|
117
|
+
■ moment@2.29.4 Skor: 58 ZOMBİ
|
|
118
|
+
Bakım modunda | Yeni özellik yok
|
|
119
|
+
Patlama yarıçapı: 23 dosya | Alternatif: dayjs, date-fns, luxon
|
|
96
120
|
|
|
97
|
-
|
|
121
|
+
GÜVENLİ (skor 80+): 679 paket
|
|
98
122
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
123
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
124
|
+
ÖZET
|
|
125
|
+
Genel Güven Skoru: 74/100
|
|
126
|
+
Kritik: 2 | Uyarı: 3 | Güvenli: 679
|
|
127
|
+
Zombi: 2 | Kaldırılmış: 1
|
|
103
128
|
```
|
|
104
129
|
|
|
105
|
-
##
|
|
130
|
+
## Güven Skoru Algoritması
|
|
106
131
|
|
|
107
|
-
Her paket,
|
|
132
|
+
Her paket, altı ağırlıklı metriğe göre 0-100 arası puanlanır:
|
|
108
133
|
|
|
109
|
-
| Metrik |
|
|
134
|
+
| Metrik | Ağırlık | Neyi Ölçer |
|
|
110
135
|
|--------|---------|------------|
|
|
111
|
-
|
|
|
112
|
-
| Maintainer
|
|
113
|
-
| Aktivite | %20 | Commit frekans trendi,
|
|
114
|
-
|
|
|
136
|
+
| Güvenlik Geçmişi | %25 | CVE sayısı (azalan ceza modeli), ortalama yama süresi, hızlı yama bonusu |
|
|
137
|
+
| Maintainer Sağlığı | %25 | Aktif maintainer sayısı (bus factor), issue yanıt süresi, PR merge hızı |
|
|
138
|
+
| Aktivite | %20 | Commit frekans trendi, sürüm kadansı, son yayınlama tarihi |
|
|
139
|
+
| Popülarite | %15 | Haftalık indirme, bağımlı paket sayısı, GitHub yıldızları |
|
|
115
140
|
| Fonlama | %10 | GitHub Sponsors, OpenCollective, kurumsal destek |
|
|
116
|
-
| Lisans | %5 | MIT/Apache =
|
|
141
|
+
| Lisans | %5 | MIT/Apache = güvenli, GPL = risk, Bilinmeyen = kırmızı bayrak |
|
|
142
|
+
|
|
143
|
+
**Skor Aralıkları:** 80-100 Güvenli | 50-79 Uyarı | 0-49 Kritik
|
|
144
|
+
|
|
145
|
+
### Güvenlik Puanlaması (v1.1.0)
|
|
146
|
+
|
|
147
|
+
Güvenlik metriği **azalan ceza** modeli kullanır — ilk güvenlik açığı en yüksek etkiye sahiptir, sonrakiler giderek azalan etkiye sahip olur:
|
|
148
|
+
|
|
149
|
+
| Güvenlik Açığı Sayısı | Güvenlik Puanı |
|
|
150
|
+
|-----------------------|----------------|
|
|
151
|
+
| 0 | 100 |
|
|
152
|
+
| 1 | 85 |
|
|
153
|
+
| 2 | 72 |
|
|
154
|
+
| 3 | 60 |
|
|
155
|
+
| 4 | 50 |
|
|
156
|
+
| 5+ | max(20, 100 - n*12) |
|
|
117
157
|
|
|
118
|
-
**
|
|
158
|
+
Güvenlik açıklarını hızlıca yamayan paketler (7 gün içinde) **+10 bonus** alır. Daha yavaş yamalar (30 gün içinde) **+5 bonus** alır.
|
|
159
|
+
|
|
160
|
+
### Skor Nasıl Hesaplanıyor?
|
|
161
|
+
|
|
162
|
+
Örneğin lodash paketini ele alalım:
|
|
163
|
+
|
|
164
|
+
- Güvenlik Geçmişi: Bilinen CVE'ler az, yamalar hızlı → 85 puan (x0.25 = 21.25)
|
|
165
|
+
- Maintainer Sağlığı: Aktif maintainer'lar var ama sınırlı → 70 puan (x0.25 = 17.5)
|
|
166
|
+
- Aktivite: Son sürüm yakın tarihli → 80 puan (x0.20 = 16)
|
|
167
|
+
- Popülarite: Milyonlarca haftalık indirme → 95 puan (x0.15 = 14.25)
|
|
168
|
+
- Fonlama: OpenCollective desteği var → 60 puan (x0.10 = 6)
|
|
169
|
+
- Lisans: MIT → 100 puan (x0.05 = 5)
|
|
170
|
+
|
|
171
|
+
**Toplam: 80/100 — Güvenli**
|
|
172
|
+
|
|
173
|
+
### Zarif Bozulma (Graceful Degradation)
|
|
174
|
+
|
|
175
|
+
Bir API erişilemediyse (GitHub kapalı, internet yok, rate limit), dep-oracle çökmez. Eksik metrik ağırlığı diğer mevcut metriklere dağılır. 3+ metrik kullanılamaz durumda ise güvenilirlik uyarısı gösterilir.
|
|
176
|
+
|
|
177
|
+
## Typosquat Tespiti
|
|
178
|
+
|
|
179
|
+
dep-oracle, typosquatting'i yakalamak için çok katmanlı bir yaklaşım kullanır:
|
|
180
|
+
|
|
181
|
+
1. **Statik kayıt** — 40+ kategoride 1.847+ bilinen popüler paket adı (React, Vue, Angular, Express, test araçları, CLI araçları vb.)
|
|
182
|
+
2. **Dinamik npm sorgusu** — npm'den en çok indirilen 5.000 paketi çeker ve 7 gün boyunca önbelleğine alır
|
|
183
|
+
3. **Örüntü eşleştirme** — Levenshtein mesafesi, önek/sonek manipülasyonu, karakter değişimi, eksik/fazla harf tespiti
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
dep-oracle check expresss # Yakalar: "express"e benzer (mesafe: 1)
|
|
187
|
+
dep-oracle check lodashe # Yakalar: "lodash"a benzer (mesafe: 1)
|
|
188
|
+
dep-oracle check react-js # Yakalar: "react" sonek örüntüsü
|
|
189
|
+
```
|
|
119
190
|
|
|
120
|
-
|
|
191
|
+
## Göç Danışmanı
|
|
121
192
|
|
|
122
|
-
|
|
193
|
+
Bir paket düşük skor aldığında veya zombi olarak işaretlendiğinde, dep-oracle **131 paket eşleşmesi** ve **192 alternatif** içeren küratörlü bir veritabanından daha güvenli seçenekler önerir:
|
|
123
194
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
-
|
|
128
|
-
|
|
129
|
-
|
|
195
|
+
```
|
|
196
|
+
moment → dayjs, date-fns, luxon
|
|
197
|
+
request → axios, got, node-fetch, undici
|
|
198
|
+
lodash → lodash-es, radash, just (native alternatifler)
|
|
199
|
+
express → fastify, koa, hono
|
|
200
|
+
gulp → esbuild, tsup, vite
|
|
201
|
+
mocha → vitest, jest, node:test
|
|
202
|
+
...ve 125 paket daha
|
|
203
|
+
```
|
|
130
204
|
|
|
131
|
-
|
|
205
|
+
Her öneri zorluk derecesi (kolay/orta/zor) ve göç bağlamı içerir.
|
|
132
206
|
|
|
133
207
|
## Claude Code Entegrasyonu (MCP)
|
|
134
208
|
|
|
135
|
-
dep-oracle, Claude Code
|
|
209
|
+
dep-oracle, Claude Code için bir MCP sunucusu olarak çalışır:
|
|
136
210
|
|
|
137
211
|
```json
|
|
138
212
|
// .claude/settings.json
|
|
@@ -146,22 +220,28 @@ dep-oracle, Claude Code icin bir MCP sunucusu olarak calisir. Ayarlamaniz cok ba
|
|
|
146
220
|
}
|
|
147
221
|
```
|
|
148
222
|
|
|
149
|
-
|
|
223
|
+
Ayarladıktan sonra Claude Code içinde doğrudan sorabilirsiniz:
|
|
150
224
|
|
|
151
|
-
- "Bu projedeki en riskli
|
|
152
|
-
- "lodash kullanmak
|
|
153
|
-
- "Zombi
|
|
154
|
-
- "
|
|
155
|
-
- "
|
|
225
|
+
- *"Bu projedeki en riskli bağımlılık hangisi?"*
|
|
226
|
+
- *"lodash kullanmak güvenli mi?"*
|
|
227
|
+
- *"Zombi bağımlılıkları göster"*
|
|
228
|
+
- *"moment.js için alternatif öner"*
|
|
229
|
+
- *"Güven skoru 50'nin altındaki paketleri listele"*
|
|
156
230
|
|
|
157
|
-
|
|
231
|
+
**Mevcut MCP Araçları:**
|
|
158
232
|
|
|
159
|
-
|
|
233
|
+
| Araç | Açıklama |
|
|
234
|
+
|------|----------|
|
|
235
|
+
| `dep_oracle_scan` | Tam proje bağımlılık taraması |
|
|
236
|
+
| `dep_oracle_trust_score` | Tek paket güven skoru |
|
|
237
|
+
| `dep_oracle_blast_radius` | Paket etki analizi |
|
|
238
|
+
| `dep_oracle_zombies` | Tüm zombi bağımlılıkları listele |
|
|
239
|
+
| `dep_oracle_suggest_migration` | Alternatif paket önerileri |
|
|
160
240
|
|
|
161
|
-
|
|
241
|
+
## GitHub Action
|
|
162
242
|
|
|
163
243
|
```yaml
|
|
164
|
-
name:
|
|
244
|
+
name: Bağımlılık Güven Kontrolü
|
|
165
245
|
on: [pull_request]
|
|
166
246
|
|
|
167
247
|
jobs:
|
|
@@ -175,14 +255,14 @@ jobs:
|
|
|
175
255
|
format: sarif
|
|
176
256
|
```
|
|
177
257
|
|
|
178
|
-
Bu
|
|
179
|
-
- Her PR'da otomatik
|
|
180
|
-
-
|
|
181
|
-
- SARIF
|
|
258
|
+
Bu konfigürasyonla:
|
|
259
|
+
- Her PR'da otomatik bağımlılık taraması yapılır
|
|
260
|
+
- Güven skoru 60'ın altındaki paketler için uyarı verilir
|
|
261
|
+
- SARIF formatında çıktı üretilir ve GitHub Security sekmesinde görüntülenir
|
|
182
262
|
|
|
183
|
-
##
|
|
263
|
+
## Konfigürasyon
|
|
184
264
|
|
|
185
|
-
Proje
|
|
265
|
+
Proje kökünde `.dep-oraclerc.json` dosyası oluşturun:
|
|
186
266
|
|
|
187
267
|
```json
|
|
188
268
|
{
|
|
@@ -195,7 +275,7 @@ Proje kokunde `.dep-oraclerc.json` dosyasi olusturun:
|
|
|
195
275
|
}
|
|
196
276
|
```
|
|
197
277
|
|
|
198
|
-
Ya da `package.json`
|
|
278
|
+
Ya da `package.json` içinde tanımlayabilirsiniz:
|
|
199
279
|
|
|
200
280
|
```json
|
|
201
281
|
{
|
|
@@ -206,20 +286,20 @@ Ya da `package.json` icinde tanimlayabilirsiniz:
|
|
|
206
286
|
}
|
|
207
287
|
```
|
|
208
288
|
|
|
209
|
-
###
|
|
289
|
+
### Konfigürasyon Seçenekleri
|
|
210
290
|
|
|
211
|
-
|
|
|
291
|
+
| Seçenek | Varsayılan | Açıklama |
|
|
212
292
|
|---------|-----------|----------|
|
|
213
|
-
| `threshold` | `60` | Minimum
|
|
214
|
-
| `ignore` | `[]` | Tarama
|
|
215
|
-
| `format` | `"terminal"` |
|
|
216
|
-
| `offline` | `false` |
|
|
217
|
-
| `githubToken` | `null` | GitHub API rate limit'i
|
|
218
|
-
| `cacheTtl` | `86400` |
|
|
293
|
+
| `threshold` | `60` | Minimum güven skoru eşiği. Altındaki paketler uyarı verir ve sıfır olmayan çıkış kodu döndürür |
|
|
294
|
+
| `ignore` | `[]` | Tarama dışında tutulacak paket listesi |
|
|
295
|
+
| `format` | `"terminal"` | Çıktı formatı: `terminal`, `json`, `html`, `sarif` |
|
|
296
|
+
| `offline` | `false` | Çevrimdışı mod. Yalnızca önbellek kullanılır, API çağrısı yapılmaz |
|
|
297
|
+
| `githubToken` | `null` | GitHub API rate limit'i artırmak için token (5000/saat vs 60/saat) |
|
|
298
|
+
| `cacheTtl` | `86400` | Önbellek geçerlilik süresi (saniye cinsinden, varsayılan: 24 saat) |
|
|
219
299
|
|
|
220
|
-
## Desteklenen Paket
|
|
300
|
+
## Desteklenen Paket Yöneticileri
|
|
221
301
|
|
|
222
|
-
|
|
|
302
|
+
| Yönetici | Manifest Dosyası | Kilit Dosyası | Durum |
|
|
223
303
|
|----------|-------------------|---------------|-------|
|
|
224
304
|
| npm | `package.json` | `package-lock.json` | Destekleniyor |
|
|
225
305
|
| yarn | `package.json` | `yarn.lock` | Destekleniyor |
|
|
@@ -227,29 +307,93 @@ Ya da `package.json` icinde tanimlayabilirsiniz:
|
|
|
227
307
|
| pip | `requirements.txt` | `Pipfile.lock` | Destekleniyor |
|
|
228
308
|
| poetry | `pyproject.toml` | `poetry.lock` | Destekleniyor |
|
|
229
309
|
|
|
230
|
-
##
|
|
310
|
+
## Karşılaştırma
|
|
231
311
|
|
|
232
|
-
|
|
|
312
|
+
| Özellik | npm audit | Dependabot | Socket.dev | Snyk | **dep-oracle** |
|
|
233
313
|
|---------|-----------|------------|------------|------|----------------|
|
|
234
|
-
| Bilinen CVE
|
|
235
|
-
| Prediktif risk analizi | Yok | Yok |
|
|
236
|
-
|
|
|
314
|
+
| Bilinen CVE taraması | Var | Var | Var | Var | **Var** |
|
|
315
|
+
| Prediktif risk analizi | Yok | Yok | Kısmi | Yok | **Var** |
|
|
316
|
+
| Güven Skoru (0-100) | Yok | Yok | Yok | Yok | **Var** |
|
|
237
317
|
| Zombi tespiti | Yok | Yok | Yok | Yok | **Var** |
|
|
238
|
-
| Patlama
|
|
318
|
+
| Patlama yarıçapı | Yok | Yok | Yok | Yok | **Var** |
|
|
239
319
|
| Typosquat tespiti | Yok | Yok | Var | Yok | **Var** |
|
|
240
320
|
| Trend tahmini | Yok | Yok | Yok | Yok | **Var** |
|
|
321
|
+
| Göç danışmanı | Yok | Kısmi | Yok | Kısmi | **Var (131 paket)** |
|
|
241
322
|
| MCP entegrasyonu | Yok | Yok | Var | Var | **Var** |
|
|
242
|
-
|
|
|
243
|
-
|
|
|
323
|
+
| Sıfır kurulum (npx) | Var | Yok | Yok | Yok | **Var** |
|
|
324
|
+
| Ücretsiz ve açık kaynak | Var | Var | Freemium | Freemium | **Var** |
|
|
325
|
+
|
|
326
|
+
## Programatik API
|
|
327
|
+
|
|
328
|
+
```typescript
|
|
329
|
+
import { scan, checkPackage } from 'dep-oracle';
|
|
330
|
+
|
|
331
|
+
// Projeyi tara
|
|
332
|
+
const report = await scan({ dir: './benim-projem', format: 'json' });
|
|
333
|
+
|
|
334
|
+
// Tek paket kontrol et
|
|
335
|
+
const result = await checkPackage('express');
|
|
336
|
+
console.log(result.trustScore); // 74
|
|
337
|
+
console.log(result.isZombie); // false
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
## Test Suite
|
|
341
|
+
|
|
342
|
+
dep-oracle kapsamlı test kapsamına sahiptir:
|
|
343
|
+
|
|
344
|
+
```
|
|
345
|
+
10 test dosyası | 144 test | %100 başarılı
|
|
346
|
+
|
|
347
|
+
trust-score.test.ts 34 test Puanlama motoru, metrikler, kenar durumlar
|
|
348
|
+
zombie-detector.test.ts 10 test Zombi tespit mantığı
|
|
349
|
+
typosquat.test.ts 15 test Typosquat örüntü eşleştirme
|
|
350
|
+
migration-advisor.test.ts 12 test Göç önerileri
|
|
351
|
+
trend-predictor.test.ts 10 test Trend tahmin motoru
|
|
352
|
+
parsers.test.ts 17 test npm + Python parser'ları
|
|
353
|
+
cache.test.ts 15 test Önbellek işlemleri
|
|
354
|
+
logger.test.ts 17 test Logger yardımcı aracı
|
|
355
|
+
rate-limiter.test.ts 6 test Rate limiter
|
|
356
|
+
schema.test.ts 8 test Zod şema doğrulama
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
```bash
|
|
360
|
+
npm test # Tüm testleri çalıştır
|
|
361
|
+
npm run lint # TypeScript tip kontrolü
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
## Değişiklik Günlüğü
|
|
365
|
+
|
|
366
|
+
### v1.1.0 (2025-02-22)
|
|
367
|
+
|
|
368
|
+
- **Typosquat Tespiti**: 40+ kategoride 1.847+ bilinen pakete genişletildi, ayrıca dinamik npm registry sorgusu eklendi (en popüler 5.000 paket, 7 günlük önbellek)
|
|
369
|
+
- **Göç Danışmanı**: 131 paket eşleşmesi ve 192 daha güvenli alternatife genişletildi
|
|
370
|
+
- **Güven Skoru Kalibrasyonu**: Azalan güvenlik açığı cezası (ilk CVE en yüksek etki), hızlı yama bonusu (<=7 gün için +10)
|
|
371
|
+
- **Poetry.lock Desteği**: Python projeleri için tam poetry.lock ayrıştırma
|
|
372
|
+
- **Kapsamlı Test Suite**: 10 test dosyası, 144 test — tüm analizörler, parser'lar, önbellek ve yardımcı araçları kapsar
|
|
373
|
+
- **Türkçe README**: Tam Türkçe dokümantasyon
|
|
374
|
+
- **Dinamik CLI Versiyonu**: Versiyon otomatik olarak package.json'dan senkronize edilir
|
|
375
|
+
|
|
376
|
+
### v1.0.0 (2025-02-22)
|
|
244
377
|
|
|
245
|
-
|
|
378
|
+
- İlk sürüm
|
|
379
|
+
- 6 ağırlıklı metrikli Güven Skoru motoru
|
|
380
|
+
- npm + Python (pip, poetry, pyproject.toml) parser'ları
|
|
381
|
+
- Zombi tespiti, patlama yarıçapı analizi
|
|
382
|
+
- Levenshtein mesafesi ile typosquat tespiti
|
|
383
|
+
- Trend tahmini (3 aylık risk projeksiyonu)
|
|
384
|
+
- Küratörlü alternatiflerle göç danışmanı
|
|
385
|
+
- Terminal, HTML, JSON, SARIF çıktı formatları
|
|
386
|
+
- Claude Code entegrasyonu için MCP sunucusu
|
|
387
|
+
- GitHub Action desteği
|
|
388
|
+
- SQLite uyumlu önbellek ile çevrimdışı mod
|
|
389
|
+
- Rozet üreticisi (SVG)
|
|
246
390
|
|
|
247
|
-
##
|
|
391
|
+
## Katkıda Bulunma
|
|
248
392
|
|
|
249
|
-
|
|
393
|
+
Katkıda bulunmak istiyorsanız [CONTRIBUTING.md](CONTRIBUTING.md) dosyasına göz atın. Geliştirme ortamı kurulumu, kodlama standartları ve yeni collector/parser/analyzer ekleme rehberi orada.
|
|
250
394
|
|
|
251
|
-
Her
|
|
395
|
+
Her türlü katkı değerlidir: hata bildirimi, dokümantasyon iyileştirmesi, yeni özellik önerisi veya kod katkısı.
|
|
252
396
|
|
|
253
397
|
## Lisans
|
|
254
398
|
|
|
255
|
-
[MIT](LICENSE)
|
|
399
|
+
[MIT](LICENSE) — [Ertuğrul Akben](https://ertugrulakben.com)
|
package/dist/mcp/server.js
CHANGED
|
@@ -15,6 +15,9 @@ import {
|
|
|
15
15
|
// src/mcp/server.ts
|
|
16
16
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
17
17
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
18
|
+
import { readFileSync } from "fs";
|
|
19
|
+
import { fileURLToPath } from "url";
|
|
20
|
+
import { dirname, join } from "path";
|
|
18
21
|
|
|
19
22
|
// src/mcp/tools.ts
|
|
20
23
|
import { resolve } from "path";
|
|
@@ -462,8 +465,18 @@ async function handleReport(args) {
|
|
|
462
465
|
}
|
|
463
466
|
|
|
464
467
|
// src/mcp/server.ts
|
|
468
|
+
var __filename2 = fileURLToPath(import.meta.url);
|
|
469
|
+
var __dirname2 = dirname(__filename2);
|
|
470
|
+
var pkgPath = join(__dirname2, "..", "..", "package.json");
|
|
471
|
+
var pkgVersion = (() => {
|
|
472
|
+
try {
|
|
473
|
+
return JSON.parse(readFileSync(pkgPath, "utf-8")).version;
|
|
474
|
+
} catch {
|
|
475
|
+
return "1.1.0";
|
|
476
|
+
}
|
|
477
|
+
})();
|
|
465
478
|
var server = new Server(
|
|
466
|
-
{ name: "dep-oracle", version:
|
|
479
|
+
{ name: "dep-oracle", version: pkgVersion },
|
|
467
480
|
{ capabilities: { tools: {} } }
|
|
468
481
|
);
|
|
469
482
|
registerTools(server);
|
package/dist/mcp/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/mcp/server.ts","../../src/mcp/tools.ts","../../src/reporters/json.ts"],"sourcesContent":["/**\n * MCP stdio server entry point for dep-oracle.\n *\n * Exposes the full dep-oracle analysis engine as MCP tools so that\n * Claude (and other MCP clients) can scan projects, evaluate trust\n * scores, detect zombies, and more -- all through the standard\n * Model Context Protocol.\n */\n\nimport { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { registerTools } from './tools.js';\n\nconst server = new Server(\n { name: 'dep-oracle', version: '1.0.0' },\n { capabilities: { tools: {} } },\n);\n\nregisterTools(server);\n\nconst transport = new StdioServerTransport();\nawait server.connect(transport);\n","/**\n * MCP tool definitions for dep-oracle.\n *\n * Registers 8 tools that expose the full analysis pipeline:\n * 1. dep_oracle_scan -- full project scan\n * 2. dep_oracle_trust_score -- single package trust score\n * 3. dep_oracle_blast_radius -- import impact analysis\n * 4. dep_oracle_zombies -- list zombie dependencies\n * 5. dep_oracle_suggest_migration -- migration suggestions\n * 6. dep_oracle_typosquat_check -- typosquat risk check\n * 7. dep_oracle_compare -- side-by-side package comparison\n * 8. dep_oracle_report -- generate HTML report\n *\n * All tools share the same core engine (parsers, collectors, analyzers)\n * as the CLI.\n */\n\nimport { resolve } from 'node:path';\nimport type { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport {\n ListToolsRequestSchema,\n CallToolRequestSchema,\n} from '@modelcontextprotocol/sdk/types.js';\n\nimport { CacheManager } from '../cache/store.js';\nimport { NpmParser } from '../parsers/npm.js';\nimport { PythonParser } from '../parsers/python.js';\nimport type { DependencyTree, TrustReport, ScanResult } from '../parsers/schema.js';\nimport { CollectorOrchestrator } from '../collectors/orchestrator.js';\nimport { TrustScoreEngine } from '../analyzers/trust-score.js';\nimport { ZombieDetector } from '../analyzers/zombie-detector.js';\nimport { BlastRadiusCalculator } from '../analyzers/blast-radius.js';\nimport { MigrationAdvisor } from '../analyzers/migration-advisor.js';\nimport { TyposquatDetector } from '../analyzers/typosquat.js';\nimport { buildImportGraph, getBlastRadius } from '../utils/graph.js';\nimport { JsonReporter } from '../reporters/json.js';\n\n// ---------------------------------------------------------------------------\n// Shared instances (created once per MCP server lifetime)\n// ---------------------------------------------------------------------------\n\nconst cache = new CacheManager();\nconst orchestrator = new CollectorOrchestrator(cache, {\n githubToken: process.env.GITHUB_TOKEN,\n});\nconst trustEngine = new TrustScoreEngine();\nconst zombieDetector = new ZombieDetector();\nconst blastRadiusCalc = new BlastRadiusCalculator();\nconst migrationAdvisor = new MigrationAdvisor();\nconst typosquatDetector = new TyposquatDetector();\nconst jsonReporter = new JsonReporter();\nconst parsers = [new NpmParser(), new PythonParser()];\n\n// ---------------------------------------------------------------------------\n// Tool definitions\n// ---------------------------------------------------------------------------\n\nconst TOOLS = [\n {\n name: 'dep_oracle_scan',\n description:\n 'Perform a full dependency security scan on a project directory. ' +\n 'Parses the manifest (package.json, requirements.txt, etc.), collects data ' +\n 'from registries and GitHub, computes trust scores for every dependency, ' +\n 'detects zombies, typosquats, and calculates blast radius. Returns a complete ' +\n 'ScanResult JSON with per-package trust reports and an overall project score.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n dir: {\n type: 'string',\n description:\n 'Absolute path to the project directory to scan. ' +\n 'Defaults to the current working directory if omitted.',\n },\n },\n required: [] as string[],\n },\n },\n {\n name: 'dep_oracle_trust_score',\n description:\n 'Calculate the trust score for a single npm package. Queries the npm registry, ' +\n 'GitHub, OSV vulnerability database, and other sources to produce a weighted ' +\n 'score (0-100) across 6 dimensions: security, maintainer, activity, popularity, ' +\n 'funding, and license. Returns a TrustReport JSON with the overall score, ' +\n 'per-dimension metrics, zombie status, and alternative suggestions.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n package: {\n type: 'string',\n description: 'npm package name (e.g. \"express\", \"@scope/pkg\").',\n },\n version: {\n type: 'string',\n description:\n 'Specific version to analyze (e.g. \"4.18.2\"). If omitted, the latest version is used.',\n },\n },\n required: ['package'],\n },\n },\n {\n name: 'dep_oracle_blast_radius',\n description:\n 'Analyze the blast radius (import impact) of a package within a project. ' +\n 'Scans all JS/TS source files to find how many files import the given package. ' +\n 'Returns the count of affected files, their paths, and the percentage of the ' +\n 'codebase impacted. Useful for understanding the risk if a dependency is ' +\n 'compromised or needs replacement.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n package: {\n type: 'string',\n description: 'Package name to check import usage for.',\n },\n dir: {\n type: 'string',\n description:\n 'Absolute path to the project directory. Defaults to cwd if omitted.',\n },\n },\n required: ['package'],\n },\n },\n {\n name: 'dep_oracle_zombies',\n description:\n 'Detect zombie (abandoned/unmaintained) dependencies in a project. ' +\n 'Parses the manifest, queries registry and GitHub for each dependency, and ' +\n 'flags packages that show signs of abandonment: deprecated, no commits in 12+ months, ' +\n 'no active maintainers, etc. Returns an array of zombie packages with severity ' +\n 'levels and reasons.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n dir: {\n type: 'string',\n description:\n 'Absolute path to the project directory. Defaults to cwd if omitted.',\n },\n },\n required: [] as string[],\n },\n },\n {\n name: 'dep_oracle_suggest_migration',\n description:\n 'Get migration suggestions for a given package. Looks up the package in a ' +\n 'curated knowledge base of common replacements and returns alternatives with ' +\n 'descriptions and difficulty ratings. Useful for replacing deprecated, abandoned, ' +\n 'or low-trust packages (e.g. moment -> dayjs, request -> got, lodash -> es-toolkit).',\n inputSchema: {\n type: 'object' as const,\n properties: {\n package: {\n type: 'string',\n description: 'Package name to find migration alternatives for.',\n },\n },\n required: ['package'],\n },\n },\n {\n name: 'dep_oracle_typosquat_check',\n description:\n 'Check whether a package name is a potential typosquat of a popular package. ' +\n 'Uses Levenshtein distance, homoglyph detection, and pattern analysis to identify ' +\n 'suspicious package names that closely resemble well-known packages. Returns a ' +\n 'risk assessment with similar package names and the edit distance.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n package: {\n type: 'string',\n description: 'Package name to check for typosquatting risk.',\n },\n },\n required: ['package'],\n },\n },\n {\n name: 'dep_oracle_compare',\n description:\n 'Compare two packages side-by-side by computing trust scores for both. ' +\n 'Returns the full trust report for each package including scores, metrics, ' +\n 'zombie status, and trend direction. Useful for evaluating alternatives ' +\n 'or choosing between competing libraries.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n packageA: {\n type: 'string',\n description: 'First package name to compare.',\n },\n packageB: {\n type: 'string',\n description: 'Second package name to compare.',\n },\n },\n required: ['packageA', 'packageB'],\n },\n },\n {\n name: 'dep_oracle_report',\n description:\n 'Generate a JSON report for a project. Runs a full scan and outputs the results ' +\n 'as formatted JSON. Optionally writes the report to a file. Returns the JSON ' +\n 'content or the path to the generated file.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n dir: {\n type: 'string',\n description:\n 'Absolute path to the project directory. Defaults to cwd if omitted.',\n },\n output: {\n type: 'string',\n description:\n 'Absolute path to write the report file. If omitted, the report content is returned directly.',\n },\n },\n required: [] as string[],\n },\n },\n];\n\n// ---------------------------------------------------------------------------\n// Tool registration\n// ---------------------------------------------------------------------------\n\nexport function registerTools(server: Server): void {\n // List all available tools\n server.setRequestHandler(ListToolsRequestSchema, async () => ({\n tools: TOOLS,\n }));\n\n // Handle tool invocations\n server.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name, arguments: args } = request.params;\n\n try {\n switch (name) {\n case 'dep_oracle_scan':\n return await handleScan(args);\n case 'dep_oracle_trust_score':\n return await handleTrustScore(args);\n case 'dep_oracle_blast_radius':\n return await handleBlastRadius(args);\n case 'dep_oracle_zombies':\n return await handleZombies(args);\n case 'dep_oracle_suggest_migration':\n return await handleSuggestMigration(args);\n case 'dep_oracle_typosquat_check':\n return await handleTyposquatCheck(args);\n case 'dep_oracle_compare':\n return await handleCompare(args);\n case 'dep_oracle_report':\n return await handleReport(args);\n default:\n return errorResponse(`Unknown tool: ${name}`);\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return errorResponse(`Tool \"${name}\" failed: ${message}`);\n }\n });\n}\n\n// ---------------------------------------------------------------------------\n// Helper: build a successful text content response\n// ---------------------------------------------------------------------------\n\nfunction successResponse(data: unknown) {\n const text = typeof data === 'string' ? data : JSON.stringify(data, null, 2);\n return {\n content: [{ type: 'text' as const, text }],\n };\n}\n\nfunction errorResponse(message: string) {\n return {\n content: [{ type: 'text' as const, text: message }],\n isError: true,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Shared: parse project dependencies\n// ---------------------------------------------------------------------------\n\nasync function parseProject(dir: string): Promise<DependencyTree | null> {\n for (const parser of parsers) {\n if (await parser.detect(dir)) {\n return parser.parse(dir);\n }\n }\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// Shared: build a full trust report for a single package\n// ---------------------------------------------------------------------------\n\nasync function buildTrustReport(\n packageName: string,\n version: string,\n blastRadius: number = 0,\n): Promise<TrustReport> {\n const results = await orchestrator.collectAll(packageName, version);\n const trustResult = trustEngine.calculate(results);\n const zombie = zombieDetector.detect(\n results.registry.data,\n results.github.data,\n );\n const typosquat = typosquatDetector.check(packageName);\n const alternatives = migrationAdvisor.suggest(\n packageName,\n zombie.isZombie ? 'zombie dependency' : 'low trust score',\n );\n\n // Determine trend from popularity data\n const trend = results.popularity.data?.trend ?? 'stable';\n\n return {\n package: packageName,\n version,\n trustScore: trustResult.trustScore,\n metrics: trustResult.metrics,\n isZombie: zombie.isZombie,\n blastRadius,\n alternatives: alternatives.map((a) => a.alternative),\n trend,\n typosquatRisk: typosquat.isRisky ? 1.0 : 0.0,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Tool handlers\n// ---------------------------------------------------------------------------\n\nasync function handleScan(args: Record<string, unknown> | undefined) {\n const dir = resolve(String(args?.dir ?? process.cwd()));\n\n const tree = await parseProject(dir);\n if (!tree) {\n return errorResponse(\n `No supported manifest file found in \"${dir}\". ` +\n 'Supported: package.json, requirements.txt, pyproject.toml, Pipfile.',\n );\n }\n\n // Build import graph for blast radius\n const importGraph = await buildImportGraph(dir);\n\n // Collect trust reports for all direct dependencies\n const directNodes = Array.from(tree.nodes.values()).filter((n) => n.isDirect);\n const reports: TrustReport[] = [];\n\n for (const node of directNodes) {\n const blastRadius = getBlastRadius(node.name, importGraph);\n const report = await buildTrustReport(node.name, node.version, blastRadius);\n reports.push(report);\n }\n\n // Overall score: weighted average\n const overallScore =\n reports.length > 0\n ? Math.round(\n reports.reduce((sum, r) => sum + r.trustScore, 0) / reports.length,\n )\n : 0;\n\n // Summary\n const zombieCount = reports.filter((r) => r.isZombie).length;\n const criticalCount = reports.filter((r) => r.trustScore < 50).length;\n const summary =\n `Scanned ${reports.length} direct dependencies. ` +\n `Overall trust score: ${overallScore}/100. ` +\n `${zombieCount} zombie(s) detected. ` +\n `${criticalCount} package(s) below trust threshold.`;\n\n const scanResult: ScanResult = {\n tree,\n reports,\n overallScore,\n summary,\n };\n\n // Serialize (handles Map objects)\n const serialized = jsonReporter.report(scanResult);\n return successResponse(serialized);\n}\n\nasync function handleTrustScore(args: Record<string, unknown> | undefined) {\n const packageName = String(args?.package ?? '');\n if (!packageName) {\n return errorResponse('Missing required parameter: \"package\".');\n }\n\n const version = String(args?.version ?? 'latest');\n const report = await buildTrustReport(packageName, version);\n return successResponse(report);\n}\n\nasync function handleBlastRadius(args: Record<string, unknown> | undefined) {\n const packageName = String(args?.package ?? '');\n if (!packageName) {\n return errorResponse('Missing required parameter: \"package\".');\n }\n\n const dir = resolve(String(args?.dir ?? process.cwd()));\n const result = await blastRadiusCalc.calculate(packageName, dir);\n return successResponse(result);\n}\n\nasync function handleZombies(args: Record<string, unknown> | undefined) {\n const dir = resolve(String(args?.dir ?? process.cwd()));\n\n const tree = await parseProject(dir);\n if (!tree) {\n return errorResponse(\n `No supported manifest file found in \"${dir}\".`,\n );\n }\n\n const directNodes = Array.from(tree.nodes.values()).filter((n) => n.isDirect);\n const zombies: Array<{\n package: string;\n version: string;\n severity: string;\n reason: string;\n lastActivity: string | null;\n }> = [];\n\n for (const node of directNodes) {\n const results = await orchestrator.collectAll(node.name, node.version);\n const zombie = zombieDetector.detect(\n results.registry.data,\n results.github.data,\n );\n\n if (zombie.isZombie) {\n zombies.push({\n package: node.name,\n version: node.version,\n severity: zombie.severity,\n reason: zombie.reason,\n lastActivity: zombie.lastActivity?.toISOString() ?? null,\n });\n }\n }\n\n if (zombies.length === 0) {\n return successResponse({\n message: 'No zombie dependencies detected.',\n zombies: [],\n });\n }\n\n return successResponse({\n message: `Found ${zombies.length} zombie dependency(ies).`,\n zombies,\n });\n}\n\nasync function handleSuggestMigration(args: Record<string, unknown> | undefined) {\n const packageName = String(args?.package ?? '');\n if (!packageName) {\n return errorResponse('Missing required parameter: \"package\".');\n }\n\n const suggestions = migrationAdvisor.suggest(packageName, 'manual query');\n\n if (suggestions.length === 0) {\n return successResponse({\n package: packageName,\n message: `No migration suggestions found for \"${packageName}\". ` +\n 'This package may not have known alternatives in our database.',\n suggestions: [],\n });\n }\n\n return successResponse({\n package: packageName,\n suggestions,\n });\n}\n\nasync function handleTyposquatCheck(args: Record<string, unknown> | undefined) {\n const packageName = String(args?.package ?? '');\n if (!packageName) {\n return errorResponse('Missing required parameter: \"package\".');\n }\n\n const result = typosquatDetector.check(packageName);\n return successResponse({\n package: packageName,\n ...result,\n });\n}\n\nasync function handleCompare(args: Record<string, unknown> | undefined) {\n const packageA = String(args?.packageA ?? '');\n const packageB = String(args?.packageB ?? '');\n\n if (!packageA || !packageB) {\n return errorResponse('Missing required parameters: \"packageA\" and \"packageB\".');\n }\n\n const [reportA, reportB] = await Promise.all([\n buildTrustReport(packageA, 'latest'),\n buildTrustReport(packageB, 'latest'),\n ]);\n\n return successResponse({\n comparison: {\n packageA: reportA,\n packageB: reportB,\n winner:\n reportA.trustScore > reportB.trustScore\n ? packageA\n : reportA.trustScore < reportB.trustScore\n ? packageB\n : 'tie',\n scoreDifference: Math.abs(reportA.trustScore - reportB.trustScore),\n },\n });\n}\n\nasync function handleReport(args: Record<string, unknown> | undefined) {\n const dir = resolve(String(args?.dir ?? process.cwd()));\n const output = args?.output ? resolve(String(args.output)) : null;\n\n const tree = await parseProject(dir);\n if (!tree) {\n return errorResponse(\n `No supported manifest file found in \"${dir}\".`,\n );\n }\n\n // Build import graph for blast radius\n const importGraph = await buildImportGraph(dir);\n\n // Collect trust reports for direct dependencies\n const directNodes = Array.from(tree.nodes.values()).filter((n) => n.isDirect);\n const reports: TrustReport[] = [];\n\n for (const node of directNodes) {\n const blastRadius = getBlastRadius(node.name, importGraph);\n const report = await buildTrustReport(node.name, node.version, blastRadius);\n reports.push(report);\n }\n\n const overallScore =\n reports.length > 0\n ? Math.round(\n reports.reduce((sum, r) => sum + r.trustScore, 0) / reports.length,\n )\n : 0;\n\n const zombieCount = reports.filter((r) => r.isZombie).length;\n const criticalCount = reports.filter((r) => r.trustScore < 50).length;\n const summary =\n `Scanned ${reports.length} direct dependencies. ` +\n `Overall trust score: ${overallScore}/100. ` +\n `${zombieCount} zombie(s) detected. ` +\n `${criticalCount} package(s) below trust threshold.`;\n\n const scanResult: ScanResult = {\n tree,\n reports,\n overallScore,\n summary,\n };\n\n const jsonContent = jsonReporter.report(scanResult);\n\n if (output) {\n const { writeFile } = await import('node:fs/promises');\n await writeFile(output, jsonContent, 'utf-8');\n return successResponse({\n message: `Report written to ${output}`,\n path: output,\n });\n }\n\n return successResponse(jsonContent);\n}\n","import type { ScanResult } from \"../parsers/schema.js\";\n\n// ---------------------------------------------------------------------------\n// JsonReporter\n// ---------------------------------------------------------------------------\n\n/**\n * Serialize a ScanResult as formatted JSON.\n *\n * The output is a self-contained JSON string suitable for piping into jq,\n * saving to a file, or passing to downstream tooling.\n */\nexport class JsonReporter {\n /**\n * Convert the scan result into a pretty-printed JSON string.\n *\n * Map objects (e.g. DependencyTree.nodes) are converted to plain\n * objects so that they survive JSON serialization.\n */\n report(result: ScanResult): string {\n return JSON.stringify(this.toSerializable(result), null, 2);\n }\n\n // -------------------------------------------------------------------------\n // Internals\n // -------------------------------------------------------------------------\n\n /**\n * Walk the value recursively and convert Map instances into plain objects\n * so JSON.stringify can handle them.\n */\n private toSerializable(value: unknown): unknown {\n if (value === null || value === undefined) {\n return value;\n }\n\n if (value instanceof Map) {\n const obj: Record<string, unknown> = {};\n for (const [k, v] of value.entries()) {\n obj[String(k)] = this.toSerializable(v);\n }\n return obj;\n }\n\n if (Array.isArray(value)) {\n return value.map((item) => this.toSerializable(item));\n }\n\n if (typeof value === \"object\") {\n const result: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value)) {\n result[k] = this.toSerializable(v);\n }\n return result;\n }\n\n return value;\n }\n}\n"],"mappings":"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","names":["server"]}
|
|
1
|
+
{"version":3,"sources":["../../src/mcp/server.ts","../../src/mcp/tools.ts","../../src/reporters/json.ts"],"sourcesContent":["/**\n * MCP stdio server entry point for dep-oracle.\n *\n * Exposes the full dep-oracle analysis engine as MCP tools so that\n * Claude (and other MCP clients) can scan projects, evaluate trust\n * scores, detect zombies, and more -- all through the standard\n * Model Context Protocol.\n */\n\nimport { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { readFileSync } from 'node:fs';\nimport { fileURLToPath } from 'node:url';\nimport { dirname, join } from 'node:path';\nimport { registerTools } from './tools.js';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\nconst pkgPath = join(__dirname, '..', '..', 'package.json');\nconst pkgVersion = (() => {\n try {\n return JSON.parse(readFileSync(pkgPath, 'utf-8')).version as string;\n } catch {\n return '1.1.0';\n }\n})();\n\nconst server = new Server(\n { name: 'dep-oracle', version: pkgVersion },\n { capabilities: { tools: {} } },\n);\n\nregisterTools(server);\n\nconst transport = new StdioServerTransport();\nawait server.connect(transport);\n","/**\n * MCP tool definitions for dep-oracle.\n *\n * Registers 8 tools that expose the full analysis pipeline:\n * 1. dep_oracle_scan -- full project scan\n * 2. dep_oracle_trust_score -- single package trust score\n * 3. dep_oracle_blast_radius -- import impact analysis\n * 4. dep_oracle_zombies -- list zombie dependencies\n * 5. dep_oracle_suggest_migration -- migration suggestions\n * 6. dep_oracle_typosquat_check -- typosquat risk check\n * 7. dep_oracle_compare -- side-by-side package comparison\n * 8. dep_oracle_report -- generate HTML report\n *\n * All tools share the same core engine (parsers, collectors, analyzers)\n * as the CLI.\n */\n\nimport { resolve } from 'node:path';\nimport type { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport {\n ListToolsRequestSchema,\n CallToolRequestSchema,\n} from '@modelcontextprotocol/sdk/types.js';\n\nimport { CacheManager } from '../cache/store.js';\nimport { NpmParser } from '../parsers/npm.js';\nimport { PythonParser } from '../parsers/python.js';\nimport type { DependencyTree, TrustReport, ScanResult } from '../parsers/schema.js';\nimport { CollectorOrchestrator } from '../collectors/orchestrator.js';\nimport { TrustScoreEngine } from '../analyzers/trust-score.js';\nimport { ZombieDetector } from '../analyzers/zombie-detector.js';\nimport { BlastRadiusCalculator } from '../analyzers/blast-radius.js';\nimport { MigrationAdvisor } from '../analyzers/migration-advisor.js';\nimport { TyposquatDetector } from '../analyzers/typosquat.js';\nimport { buildImportGraph, getBlastRadius } from '../utils/graph.js';\nimport { JsonReporter } from '../reporters/json.js';\n\n// ---------------------------------------------------------------------------\n// Shared instances (created once per MCP server lifetime)\n// ---------------------------------------------------------------------------\n\nconst cache = new CacheManager();\nconst orchestrator = new CollectorOrchestrator(cache, {\n githubToken: process.env.GITHUB_TOKEN,\n});\nconst trustEngine = new TrustScoreEngine();\nconst zombieDetector = new ZombieDetector();\nconst blastRadiusCalc = new BlastRadiusCalculator();\nconst migrationAdvisor = new MigrationAdvisor();\nconst typosquatDetector = new TyposquatDetector();\nconst jsonReporter = new JsonReporter();\nconst parsers = [new NpmParser(), new PythonParser()];\n\n// ---------------------------------------------------------------------------\n// Tool definitions\n// ---------------------------------------------------------------------------\n\nconst TOOLS = [\n {\n name: 'dep_oracle_scan',\n description:\n 'Perform a full dependency security scan on a project directory. ' +\n 'Parses the manifest (package.json, requirements.txt, etc.), collects data ' +\n 'from registries and GitHub, computes trust scores for every dependency, ' +\n 'detects zombies, typosquats, and calculates blast radius. Returns a complete ' +\n 'ScanResult JSON with per-package trust reports and an overall project score.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n dir: {\n type: 'string',\n description:\n 'Absolute path to the project directory to scan. ' +\n 'Defaults to the current working directory if omitted.',\n },\n },\n required: [] as string[],\n },\n },\n {\n name: 'dep_oracle_trust_score',\n description:\n 'Calculate the trust score for a single npm package. Queries the npm registry, ' +\n 'GitHub, OSV vulnerability database, and other sources to produce a weighted ' +\n 'score (0-100) across 6 dimensions: security, maintainer, activity, popularity, ' +\n 'funding, and license. Returns a TrustReport JSON with the overall score, ' +\n 'per-dimension metrics, zombie status, and alternative suggestions.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n package: {\n type: 'string',\n description: 'npm package name (e.g. \"express\", \"@scope/pkg\").',\n },\n version: {\n type: 'string',\n description:\n 'Specific version to analyze (e.g. \"4.18.2\"). If omitted, the latest version is used.',\n },\n },\n required: ['package'],\n },\n },\n {\n name: 'dep_oracle_blast_radius',\n description:\n 'Analyze the blast radius (import impact) of a package within a project. ' +\n 'Scans all JS/TS source files to find how many files import the given package. ' +\n 'Returns the count of affected files, their paths, and the percentage of the ' +\n 'codebase impacted. Useful for understanding the risk if a dependency is ' +\n 'compromised or needs replacement.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n package: {\n type: 'string',\n description: 'Package name to check import usage for.',\n },\n dir: {\n type: 'string',\n description:\n 'Absolute path to the project directory. Defaults to cwd if omitted.',\n },\n },\n required: ['package'],\n },\n },\n {\n name: 'dep_oracle_zombies',\n description:\n 'Detect zombie (abandoned/unmaintained) dependencies in a project. ' +\n 'Parses the manifest, queries registry and GitHub for each dependency, and ' +\n 'flags packages that show signs of abandonment: deprecated, no commits in 12+ months, ' +\n 'no active maintainers, etc. Returns an array of zombie packages with severity ' +\n 'levels and reasons.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n dir: {\n type: 'string',\n description:\n 'Absolute path to the project directory. Defaults to cwd if omitted.',\n },\n },\n required: [] as string[],\n },\n },\n {\n name: 'dep_oracle_suggest_migration',\n description:\n 'Get migration suggestions for a given package. Looks up the package in a ' +\n 'curated knowledge base of common replacements and returns alternatives with ' +\n 'descriptions and difficulty ratings. Useful for replacing deprecated, abandoned, ' +\n 'or low-trust packages (e.g. moment -> dayjs, request -> got, lodash -> es-toolkit).',\n inputSchema: {\n type: 'object' as const,\n properties: {\n package: {\n type: 'string',\n description: 'Package name to find migration alternatives for.',\n },\n },\n required: ['package'],\n },\n },\n {\n name: 'dep_oracle_typosquat_check',\n description:\n 'Check whether a package name is a potential typosquat of a popular package. ' +\n 'Uses Levenshtein distance, homoglyph detection, and pattern analysis to identify ' +\n 'suspicious package names that closely resemble well-known packages. Returns a ' +\n 'risk assessment with similar package names and the edit distance.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n package: {\n type: 'string',\n description: 'Package name to check for typosquatting risk.',\n },\n },\n required: ['package'],\n },\n },\n {\n name: 'dep_oracle_compare',\n description:\n 'Compare two packages side-by-side by computing trust scores for both. ' +\n 'Returns the full trust report for each package including scores, metrics, ' +\n 'zombie status, and trend direction. Useful for evaluating alternatives ' +\n 'or choosing between competing libraries.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n packageA: {\n type: 'string',\n description: 'First package name to compare.',\n },\n packageB: {\n type: 'string',\n description: 'Second package name to compare.',\n },\n },\n required: ['packageA', 'packageB'],\n },\n },\n {\n name: 'dep_oracle_report',\n description:\n 'Generate a JSON report for a project. Runs a full scan and outputs the results ' +\n 'as formatted JSON. Optionally writes the report to a file. Returns the JSON ' +\n 'content or the path to the generated file.',\n inputSchema: {\n type: 'object' as const,\n properties: {\n dir: {\n type: 'string',\n description:\n 'Absolute path to the project directory. Defaults to cwd if omitted.',\n },\n output: {\n type: 'string',\n description:\n 'Absolute path to write the report file. If omitted, the report content is returned directly.',\n },\n },\n required: [] as string[],\n },\n },\n];\n\n// ---------------------------------------------------------------------------\n// Tool registration\n// ---------------------------------------------------------------------------\n\nexport function registerTools(server: Server): void {\n // List all available tools\n server.setRequestHandler(ListToolsRequestSchema, async () => ({\n tools: TOOLS,\n }));\n\n // Handle tool invocations\n server.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name, arguments: args } = request.params;\n\n try {\n switch (name) {\n case 'dep_oracle_scan':\n return await handleScan(args);\n case 'dep_oracle_trust_score':\n return await handleTrustScore(args);\n case 'dep_oracle_blast_radius':\n return await handleBlastRadius(args);\n case 'dep_oracle_zombies':\n return await handleZombies(args);\n case 'dep_oracle_suggest_migration':\n return await handleSuggestMigration(args);\n case 'dep_oracle_typosquat_check':\n return await handleTyposquatCheck(args);\n case 'dep_oracle_compare':\n return await handleCompare(args);\n case 'dep_oracle_report':\n return await handleReport(args);\n default:\n return errorResponse(`Unknown tool: ${name}`);\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return errorResponse(`Tool \"${name}\" failed: ${message}`);\n }\n });\n}\n\n// ---------------------------------------------------------------------------\n// Helper: build a successful text content response\n// ---------------------------------------------------------------------------\n\nfunction successResponse(data: unknown) {\n const text = typeof data === 'string' ? data : JSON.stringify(data, null, 2);\n return {\n content: [{ type: 'text' as const, text }],\n };\n}\n\nfunction errorResponse(message: string) {\n return {\n content: [{ type: 'text' as const, text: message }],\n isError: true,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Shared: parse project dependencies\n// ---------------------------------------------------------------------------\n\nasync function parseProject(dir: string): Promise<DependencyTree | null> {\n for (const parser of parsers) {\n if (await parser.detect(dir)) {\n return parser.parse(dir);\n }\n }\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// Shared: build a full trust report for a single package\n// ---------------------------------------------------------------------------\n\nasync function buildTrustReport(\n packageName: string,\n version: string,\n blastRadius: number = 0,\n): Promise<TrustReport> {\n const results = await orchestrator.collectAll(packageName, version);\n const trustResult = trustEngine.calculate(results);\n const zombie = zombieDetector.detect(\n results.registry.data,\n results.github.data,\n );\n const typosquat = typosquatDetector.check(packageName);\n const alternatives = migrationAdvisor.suggest(\n packageName,\n zombie.isZombie ? 'zombie dependency' : 'low trust score',\n );\n\n // Determine trend from popularity data\n const trend = results.popularity.data?.trend ?? 'stable';\n\n return {\n package: packageName,\n version,\n trustScore: trustResult.trustScore,\n metrics: trustResult.metrics,\n isZombie: zombie.isZombie,\n blastRadius,\n alternatives: alternatives.map((a) => a.alternative),\n trend,\n typosquatRisk: typosquat.isRisky ? 1.0 : 0.0,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Tool handlers\n// ---------------------------------------------------------------------------\n\nasync function handleScan(args: Record<string, unknown> | undefined) {\n const dir = resolve(String(args?.dir ?? process.cwd()));\n\n const tree = await parseProject(dir);\n if (!tree) {\n return errorResponse(\n `No supported manifest file found in \"${dir}\". ` +\n 'Supported: package.json, requirements.txt, pyproject.toml, Pipfile.',\n );\n }\n\n // Build import graph for blast radius\n const importGraph = await buildImportGraph(dir);\n\n // Collect trust reports for all direct dependencies\n const directNodes = Array.from(tree.nodes.values()).filter((n) => n.isDirect);\n const reports: TrustReport[] = [];\n\n for (const node of directNodes) {\n const blastRadius = getBlastRadius(node.name, importGraph);\n const report = await buildTrustReport(node.name, node.version, blastRadius);\n reports.push(report);\n }\n\n // Overall score: weighted average\n const overallScore =\n reports.length > 0\n ? Math.round(\n reports.reduce((sum, r) => sum + r.trustScore, 0) / reports.length,\n )\n : 0;\n\n // Summary\n const zombieCount = reports.filter((r) => r.isZombie).length;\n const criticalCount = reports.filter((r) => r.trustScore < 50).length;\n const summary =\n `Scanned ${reports.length} direct dependencies. ` +\n `Overall trust score: ${overallScore}/100. ` +\n `${zombieCount} zombie(s) detected. ` +\n `${criticalCount} package(s) below trust threshold.`;\n\n const scanResult: ScanResult = {\n tree,\n reports,\n overallScore,\n summary,\n };\n\n // Serialize (handles Map objects)\n const serialized = jsonReporter.report(scanResult);\n return successResponse(serialized);\n}\n\nasync function handleTrustScore(args: Record<string, unknown> | undefined) {\n const packageName = String(args?.package ?? '');\n if (!packageName) {\n return errorResponse('Missing required parameter: \"package\".');\n }\n\n const version = String(args?.version ?? 'latest');\n const report = await buildTrustReport(packageName, version);\n return successResponse(report);\n}\n\nasync function handleBlastRadius(args: Record<string, unknown> | undefined) {\n const packageName = String(args?.package ?? '');\n if (!packageName) {\n return errorResponse('Missing required parameter: \"package\".');\n }\n\n const dir = resolve(String(args?.dir ?? process.cwd()));\n const result = await blastRadiusCalc.calculate(packageName, dir);\n return successResponse(result);\n}\n\nasync function handleZombies(args: Record<string, unknown> | undefined) {\n const dir = resolve(String(args?.dir ?? process.cwd()));\n\n const tree = await parseProject(dir);\n if (!tree) {\n return errorResponse(\n `No supported manifest file found in \"${dir}\".`,\n );\n }\n\n const directNodes = Array.from(tree.nodes.values()).filter((n) => n.isDirect);\n const zombies: Array<{\n package: string;\n version: string;\n severity: string;\n reason: string;\n lastActivity: string | null;\n }> = [];\n\n for (const node of directNodes) {\n const results = await orchestrator.collectAll(node.name, node.version);\n const zombie = zombieDetector.detect(\n results.registry.data,\n results.github.data,\n );\n\n if (zombie.isZombie) {\n zombies.push({\n package: node.name,\n version: node.version,\n severity: zombie.severity,\n reason: zombie.reason,\n lastActivity: zombie.lastActivity?.toISOString() ?? null,\n });\n }\n }\n\n if (zombies.length === 0) {\n return successResponse({\n message: 'No zombie dependencies detected.',\n zombies: [],\n });\n }\n\n return successResponse({\n message: `Found ${zombies.length} zombie dependency(ies).`,\n zombies,\n });\n}\n\nasync function handleSuggestMigration(args: Record<string, unknown> | undefined) {\n const packageName = String(args?.package ?? '');\n if (!packageName) {\n return errorResponse('Missing required parameter: \"package\".');\n }\n\n const suggestions = migrationAdvisor.suggest(packageName, 'manual query');\n\n if (suggestions.length === 0) {\n return successResponse({\n package: packageName,\n message: `No migration suggestions found for \"${packageName}\". ` +\n 'This package may not have known alternatives in our database.',\n suggestions: [],\n });\n }\n\n return successResponse({\n package: packageName,\n suggestions,\n });\n}\n\nasync function handleTyposquatCheck(args: Record<string, unknown> | undefined) {\n const packageName = String(args?.package ?? '');\n if (!packageName) {\n return errorResponse('Missing required parameter: \"package\".');\n }\n\n const result = typosquatDetector.check(packageName);\n return successResponse({\n package: packageName,\n ...result,\n });\n}\n\nasync function handleCompare(args: Record<string, unknown> | undefined) {\n const packageA = String(args?.packageA ?? '');\n const packageB = String(args?.packageB ?? '');\n\n if (!packageA || !packageB) {\n return errorResponse('Missing required parameters: \"packageA\" and \"packageB\".');\n }\n\n const [reportA, reportB] = await Promise.all([\n buildTrustReport(packageA, 'latest'),\n buildTrustReport(packageB, 'latest'),\n ]);\n\n return successResponse({\n comparison: {\n packageA: reportA,\n packageB: reportB,\n winner:\n reportA.trustScore > reportB.trustScore\n ? packageA\n : reportA.trustScore < reportB.trustScore\n ? packageB\n : 'tie',\n scoreDifference: Math.abs(reportA.trustScore - reportB.trustScore),\n },\n });\n}\n\nasync function handleReport(args: Record<string, unknown> | undefined) {\n const dir = resolve(String(args?.dir ?? process.cwd()));\n const output = args?.output ? resolve(String(args.output)) : null;\n\n const tree = await parseProject(dir);\n if (!tree) {\n return errorResponse(\n `No supported manifest file found in \"${dir}\".`,\n );\n }\n\n // Build import graph for blast radius\n const importGraph = await buildImportGraph(dir);\n\n // Collect trust reports for direct dependencies\n const directNodes = Array.from(tree.nodes.values()).filter((n) => n.isDirect);\n const reports: TrustReport[] = [];\n\n for (const node of directNodes) {\n const blastRadius = getBlastRadius(node.name, importGraph);\n const report = await buildTrustReport(node.name, node.version, blastRadius);\n reports.push(report);\n }\n\n const overallScore =\n reports.length > 0\n ? Math.round(\n reports.reduce((sum, r) => sum + r.trustScore, 0) / reports.length,\n )\n : 0;\n\n const zombieCount = reports.filter((r) => r.isZombie).length;\n const criticalCount = reports.filter((r) => r.trustScore < 50).length;\n const summary =\n `Scanned ${reports.length} direct dependencies. ` +\n `Overall trust score: ${overallScore}/100. ` +\n `${zombieCount} zombie(s) detected. ` +\n `${criticalCount} package(s) below trust threshold.`;\n\n const scanResult: ScanResult = {\n tree,\n reports,\n overallScore,\n summary,\n };\n\n const jsonContent = jsonReporter.report(scanResult);\n\n if (output) {\n const { writeFile } = await import('node:fs/promises');\n await writeFile(output, jsonContent, 'utf-8');\n return successResponse({\n message: `Report written to ${output}`,\n path: output,\n });\n }\n\n return successResponse(jsonContent);\n}\n","import type { ScanResult } from \"../parsers/schema.js\";\n\n// ---------------------------------------------------------------------------\n// JsonReporter\n// ---------------------------------------------------------------------------\n\n/**\n * Serialize a ScanResult as formatted JSON.\n *\n * The output is a self-contained JSON string suitable for piping into jq,\n * saving to a file, or passing to downstream tooling.\n */\nexport class JsonReporter {\n /**\n * Convert the scan result into a pretty-printed JSON string.\n *\n * Map objects (e.g. DependencyTree.nodes) are converted to plain\n * objects so that they survive JSON serialization.\n */\n report(result: ScanResult): string {\n return JSON.stringify(this.toSerializable(result), null, 2);\n }\n\n // -------------------------------------------------------------------------\n // Internals\n // -------------------------------------------------------------------------\n\n /**\n * Walk the value recursively and convert Map instances into plain objects\n * so JSON.stringify can handle them.\n */\n private toSerializable(value: unknown): unknown {\n if (value === null || value === undefined) {\n return value;\n }\n\n if (value instanceof Map) {\n const obj: Record<string, unknown> = {};\n for (const [k, v] of value.entries()) {\n obj[String(k)] = this.toSerializable(v);\n }\n return obj;\n }\n\n if (Array.isArray(value)) {\n return value.map((item) => this.toSerializable(item));\n }\n\n if (typeof value === \"object\") {\n const result: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value)) {\n result[k] = this.toSerializable(v);\n }\n return result;\n }\n\n return value;\n }\n}\n"],"mappings":"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","names":["server","__filename","__dirname"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dep-oracle",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
|
+
"mcpName": "io.github.ertugrulakben/dep-oracle",
|
|
4
5
|
"description": "Predictive dependency security engine. Trust scores, zombie detection, blast radius analysis for your supply chain.",
|
|
5
6
|
"type": "module",
|
|
6
7
|
"bin": {
|