toolip 2.0.1 → 2.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 +243 -94
- package/dist/src/commands/scan.js +6 -4
- package/dist/src/commands/scan.js.map +1 -1
- package/dist/src/commands/score.js +20 -3
- package/dist/src/commands/score.js.map +1 -1
- package/dist/src/core/dependency-scan.d.ts +2 -0
- package/dist/src/core/dependency-scan.js +3 -0
- package/dist/src/core/dependency-scan.js.map +1 -1
- package/dist/src/core/score.d.ts +22 -0
- package/dist/src/core/score.js +138 -13
- package/dist/src/core/score.js.map +1 -1
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -6,9 +6,9 @@ Toolip helps developers inspect what enters their applications, identify risky c
|
|
|
6
6
|
|
|
7
7
|
## Status
|
|
8
8
|
|
|
9
|
-
The latest stable release is Toolip v2.
|
|
9
|
+
The latest stable release is **Toolip v2.1.1**.
|
|
10
10
|
|
|
11
|
-
Toolip v2.
|
|
11
|
+
Toolip v2.1.1 combines local vulnerability intelligence, AST-based security analysis, supply-chain auditing, Git security, container checks, SBOM generation, configurable policy, shareable reports, GitHub workflows, unified dependency-health scoring, and a read-only MCP server.
|
|
12
12
|
|
|
13
13
|
## Why Toolip Exists
|
|
14
14
|
|
|
@@ -20,16 +20,17 @@ Toolip does not aim to replace enterprise security platforms. It focuses on usef
|
|
|
20
20
|
|
|
21
21
|
## Design Principles
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
23
|
+
* Local-first and privacy-conscious
|
|
24
|
+
* Free and useful without an account
|
|
25
|
+
* Deterministic analysis where possible
|
|
26
|
+
* Explicit confidence for heuristic findings
|
|
27
|
+
* Stable, machine-readable output
|
|
28
|
+
* Actionable remediation
|
|
29
|
+
* Bounded resource usage
|
|
30
|
+
* Opt-in remote integrations
|
|
31
|
+
* Verified npm release artifacts
|
|
32
|
+
* One shared analysis engine across every interface
|
|
33
|
+
* One canonical dependency-health calculation across commands
|
|
33
34
|
|
|
34
35
|
## Installation
|
|
35
36
|
|
|
@@ -39,6 +40,12 @@ Install the latest stable release globally:
|
|
|
39
40
|
npm install -g toolip
|
|
40
41
|
```
|
|
41
42
|
|
|
43
|
+
Install a specific version:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
npm install -g toolip@2.1.1
|
|
47
|
+
```
|
|
48
|
+
|
|
42
49
|
Verify the installation:
|
|
43
50
|
|
|
44
51
|
```bash
|
|
@@ -67,6 +74,7 @@ Audit Git safety:
|
|
|
67
74
|
|
|
68
75
|
```bash
|
|
69
76
|
toolip git-audit
|
|
77
|
+
toolip git-history
|
|
70
78
|
toolip pre-commit
|
|
71
79
|
```
|
|
72
80
|
|
|
@@ -80,6 +88,13 @@ toolip tree
|
|
|
80
88
|
toolip alternatives request
|
|
81
89
|
```
|
|
82
90
|
|
|
91
|
+
Generate software bills of materials:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
toolip sbom --format cyclonedx
|
|
95
|
+
toolip sbom --format spdx
|
|
96
|
+
```
|
|
97
|
+
|
|
83
98
|
Use the local encrypted vault:
|
|
84
99
|
|
|
85
100
|
```bash
|
|
@@ -99,57 +114,86 @@ toolip learn dependencies
|
|
|
99
114
|
|
|
100
115
|
## Current Commands
|
|
101
116
|
|
|
102
|
-
| Command
|
|
103
|
-
|
|
|
104
|
-
| `toolip self-test`
|
|
105
|
-
| `toolip profile`
|
|
106
|
-
| `toolip scan`
|
|
107
|
-
| `toolip vulnerabilities`
|
|
108
|
-
| `toolip ast-scan`
|
|
109
|
-
| `toolip reachability`
|
|
110
|
-
| `toolip install-scripts`
|
|
111
|
-
| `toolip sbom`
|
|
112
|
-
| `toolip history`
|
|
113
|
-
| `toolip config`
|
|
114
|
-
| `toolip package-health <package> <version>` | Inspect package metadata and provenance through deps.dev
|
|
115
|
-
| `toolip dependency-confusion`
|
|
116
|
-
| `toolip git-history`
|
|
117
|
-
| `toolip doctor`
|
|
118
|
-
| `toolip score`
|
|
119
|
-
| `toolip inspect <package>`
|
|
120
|
-
| `toolip compare <packages...>`
|
|
121
|
-
| `toolip licenses`
|
|
122
|
-
| `toolip alternatives <package>`
|
|
123
|
-
| `toolip tree`
|
|
124
|
-
| `toolip vault`
|
|
125
|
-
| `toolip git-audit`
|
|
126
|
-
| `toolip pre-commit`
|
|
127
|
-
| `toolip hook install`
|
|
128
|
-
| `toolip learn [topic]`
|
|
129
|
-
| `toolip docker-scan`
|
|
130
|
-
| `toolip monorepo`
|
|
131
|
-
| `toolip audit-repo <url>`
|
|
132
|
-
| `toolip upgrade-pr <package> <version>`
|
|
133
|
-
| `toolip diff <base> [head]`
|
|
134
|
-
| `toolip publish`
|
|
135
|
-
| `toolip watch`
|
|
136
|
-
| `toolip announce`
|
|
137
|
-
| `toolip mcp`
|
|
117
|
+
| Command | Purpose |
|
|
118
|
+
| ------------------------------------------- | --------------------------------------------------------------------- |
|
|
119
|
+
| `toolip self-test` | Run internal diagnostics |
|
|
120
|
+
| `toolip profile` | Detect project technologies and structure |
|
|
121
|
+
| `toolip scan` | Analyze dependency and project risk |
|
|
122
|
+
| `toolip vulnerabilities` | Match resolved npm dependencies against OSV.dev |
|
|
123
|
+
| `toolip ast-scan` | Analyze JavaScript and TypeScript through the TypeScript Compiler API |
|
|
124
|
+
| `toolip reachability` | Show package usage observed in source imports |
|
|
125
|
+
| `toolip install-scripts` | Inspect npm lifecycle scripts for suspicious behavior indicators |
|
|
126
|
+
| `toolip sbom` | Generate CycloneDX 1.5 or SPDX 2.3 JSON |
|
|
127
|
+
| `toolip history` | Inspect local security history and score trends |
|
|
128
|
+
| `toolip config` | Initialize and validate Toolip policy configuration |
|
|
129
|
+
| `toolip package-health <package> <version>` | Inspect package metadata and provenance through deps.dev |
|
|
130
|
+
| `toolip dependency-confusion` | Check internal-looking package names against public npm |
|
|
131
|
+
| `toolip git-history` | Scan local Git history for deleted or historical secrets |
|
|
132
|
+
| `toolip doctor` | Run security hygiene checks |
|
|
133
|
+
| `toolip score` | Calculate a project security score |
|
|
134
|
+
| `toolip inspect <package>` | Inspect npm package metadata and risk signals |
|
|
135
|
+
| `toolip compare <packages...>` | Compare package health and maintenance signals |
|
|
136
|
+
| `toolip licenses` | Analyze dependency licenses |
|
|
137
|
+
| `toolip alternatives <package>` | Suggest maintained package alternatives |
|
|
138
|
+
| `toolip tree` | Display dependency relationships |
|
|
139
|
+
| `toolip vault` | Manage encrypted local secrets |
|
|
140
|
+
| `toolip git-audit` | Audit repository and ignore-file safety |
|
|
141
|
+
| `toolip pre-commit` | Run blocking security checks before commit |
|
|
142
|
+
| `toolip hook install` | Install the Toolip pre-commit hook |
|
|
143
|
+
| `toolip learn [topic]` | Read secure-development lessons |
|
|
144
|
+
| `toolip docker-scan` | Scan Dockerfiles for risky container patterns |
|
|
145
|
+
| `toolip monorepo` | Discover npm and pnpm workspace packages |
|
|
146
|
+
| `toolip audit-repo <url>` | Audit a public GitHub repository through `gh` |
|
|
147
|
+
| `toolip upgrade-pr <package> <version>` | Create a tested dependency-upgrade pull request |
|
|
148
|
+
| `toolip diff <base> [head]` | Summarize security-relevant Git changes |
|
|
149
|
+
| `toolip publish` | Generate a static HTML security report |
|
|
150
|
+
| `toolip watch` | Continuously rerun security checks as files change |
|
|
151
|
+
| `toolip announce` | Generate a deterministic security update summary |
|
|
152
|
+
| `toolip mcp` | Start the read-only Toolip MCP server over stdio |
|
|
138
153
|
|
|
139
154
|
Use command-specific help for current options:
|
|
140
155
|
|
|
141
156
|
```bash
|
|
142
157
|
toolip doctor --help
|
|
143
158
|
toolip scan --help
|
|
159
|
+
toolip score --help
|
|
144
160
|
toolip vault --help
|
|
145
161
|
```
|
|
146
162
|
|
|
147
163
|
## Core Capabilities
|
|
148
164
|
|
|
165
|
+
### Vulnerability Intelligence
|
|
166
|
+
|
|
167
|
+
Toolip matches resolved npm dependencies against OSV.dev and reports known disclosed vulnerabilities using exact package versions.
|
|
168
|
+
|
|
169
|
+
It separates disclosed vulnerabilities from general package-maintenance signals so security risk and dependency freshness are not treated as the same thing.
|
|
170
|
+
|
|
171
|
+
See [docs/VULNERABILITY-INTELLIGENCE.md](docs/VULNERABILITY-INTELLIGENCE.md).
|
|
172
|
+
|
|
149
173
|
### Dependency Intelligence
|
|
150
174
|
|
|
151
175
|
Toolip reads project manifests and lockfiles, identifies outdated or deprecated dependencies, inspects package metadata, compares alternatives, reports license distribution, and visualizes dependency relationships.
|
|
152
176
|
|
|
177
|
+
Toolip also integrates with deps.dev for package metadata, dependency graph information, license data, provenance, attestations, and advisory intelligence.
|
|
178
|
+
|
|
179
|
+
### Risk-Aware Dependency Scoring
|
|
180
|
+
|
|
181
|
+
Toolip v2.1 introduced a risk-aware dependency-health model.
|
|
182
|
+
|
|
183
|
+
The scoring engine distinguishes between:
|
|
184
|
+
|
|
185
|
+
* disclosed vulnerabilities
|
|
186
|
+
* deprecated packages
|
|
187
|
+
* missing maintainer signals
|
|
188
|
+
* stale publishing activity
|
|
189
|
+
* major version gaps
|
|
190
|
+
* minor version gaps
|
|
191
|
+
* patch version gaps
|
|
192
|
+
|
|
193
|
+
Vulnerability penalties receive the greatest weight. Maintenance and freshness penalties are independently capped, preventing outdated packages alone from collapsing dependency health to zero.
|
|
194
|
+
|
|
195
|
+
Toolip v2.1.1 also ensures that `toolip scan` and `toolip score` consume the same canonical dependency-health result.
|
|
196
|
+
|
|
153
197
|
### AST Security Analysis
|
|
154
198
|
|
|
155
199
|
Toolip uses the TypeScript Compiler API for semantic dangerous-code checks. It resolves supported imports and call targets instead of treating every matching method name as the same operation.
|
|
@@ -182,7 +226,27 @@ Toolip checks source and configuration files for secret exposure, unsafe executi
|
|
|
182
226
|
|
|
183
227
|
### Git Safety
|
|
184
228
|
|
|
185
|
-
Toolip audits sensitive file patterns, ignore rules, committed artifacts, and pre-commit risks.
|
|
229
|
+
Toolip audits sensitive file patterns, ignore rules, committed artifacts, and pre-commit risks.
|
|
230
|
+
|
|
231
|
+
Git-history scanning can detect credentials that were committed and later deleted. Historical test fixtures are classified separately from genuine application credentials, and evidence remains redacted.
|
|
232
|
+
|
|
233
|
+
### Docker and Container Security
|
|
234
|
+
|
|
235
|
+
Toolip scans Dockerfiles for risky patterns including:
|
|
236
|
+
|
|
237
|
+
* root execution
|
|
238
|
+
* secret-like `ARG` or `ENV` declarations
|
|
239
|
+
* unpinned base images
|
|
240
|
+
* remote `ADD` instructions
|
|
241
|
+
* package-install cleanup issues
|
|
242
|
+
|
|
243
|
+
See [docs/DOCKER-SCANNING.md](docs/DOCKER-SCANNING.md).
|
|
244
|
+
|
|
245
|
+
### Monorepo Support
|
|
246
|
+
|
|
247
|
+
Toolip discovers npm and pnpm workspaces and identifies package boundaries for per-workspace analysis and reporting.
|
|
248
|
+
|
|
249
|
+
See [docs/MONOREPOS.md](docs/MONOREPOS.md).
|
|
186
250
|
|
|
187
251
|
### Local Secrets Management
|
|
188
252
|
|
|
@@ -192,66 +256,149 @@ Toolip Vault provides password-protected local encryption for development secret
|
|
|
192
256
|
|
|
193
257
|
Learning mode explains security concepts, common mistakes, practical risks, secure alternatives, and recommended development practices.
|
|
194
258
|
|
|
195
|
-
### Reports
|
|
259
|
+
### Reports and Automation
|
|
196
260
|
|
|
197
|
-
|
|
261
|
+
Toolip can generate:
|
|
262
|
+
|
|
263
|
+
* terminal reports
|
|
264
|
+
* structured JSON output
|
|
265
|
+
* historical security records
|
|
266
|
+
* CycloneDX and SPDX SBOMs
|
|
267
|
+
* static HTML security reports
|
|
268
|
+
* Git security diffs
|
|
269
|
+
* deterministic release summaries
|
|
270
|
+
|
|
271
|
+
These outputs can support CI, review workflows, historical comparison, and integration with other tools.
|
|
198
272
|
|
|
199
273
|
## Architecture
|
|
200
274
|
|
|
201
|
-
Toolip
|
|
275
|
+
Toolip separates interfaces, application services, analyzers, providers, contracts, reporting, and storage.
|
|
202
276
|
|
|
203
277
|
Commands handle input and presentation. Application services orchestrate work. Analyzers return normalized findings. Providers isolate Git, filesystem, package registry, vulnerability database, and GitHub access. Storage implementations manage cache, policy, history, and baselines.
|
|
204
278
|
|
|
205
|
-
|
|
279
|
+
CLI commands, watch mode, HTML reports, GitHub automation, and the MCP server reuse the same security engine and shared finding contracts.
|
|
206
280
|
|
|
207
281
|
See [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for the architectural model and [docs/ENGINEERING.md](docs/ENGINEERING.md) for development standards.
|
|
208
282
|
|
|
209
|
-
## Toolip v2 Capabilities
|
|
210
|
-
|
|
211
|
-
Toolip v2.
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
283
|
+
## Toolip v2.1 Capabilities
|
|
284
|
+
|
|
285
|
+
Toolip v2.1.1 includes:
|
|
286
|
+
|
|
287
|
+
* OSV-backed CVE and vulnerability matching
|
|
288
|
+
* AST-based JavaScript and TypeScript security analysis
|
|
289
|
+
* package reachability evidence
|
|
290
|
+
* npm lifecycle-script inspection
|
|
291
|
+
* CycloneDX and SPDX SBOM generation
|
|
292
|
+
* historical security trends
|
|
293
|
+
* project policy and severity configuration
|
|
294
|
+
* deps.dev package intelligence
|
|
295
|
+
* dependency-confusion detection
|
|
296
|
+
* full Git-history secret scanning
|
|
297
|
+
* Dockerfile and container configuration analysis
|
|
298
|
+
* monorepo-aware discovery
|
|
299
|
+
* remote public repository audits
|
|
300
|
+
* tested dependency-upgrade pull requests
|
|
301
|
+
* security diffs between commits and branches
|
|
302
|
+
* static HTML report generation
|
|
303
|
+
* real-time terminal watch mode
|
|
304
|
+
* deterministic release-summary generation
|
|
305
|
+
* a read-only MCP server
|
|
306
|
+
* risk-aware dependency-health scoring
|
|
307
|
+
* unified dependency-health results across `scan` and `score`
|
|
232
308
|
|
|
233
309
|
Remote repository audits and pull-request creation remain opt-in and use the user's own GitHub authorization.
|
|
234
310
|
|
|
235
311
|
## Configuration
|
|
236
312
|
|
|
237
|
-
Toolip
|
|
313
|
+
Toolip supports `.toolipignore` for scan exclusions and `toolip.config.json` for project policy.
|
|
314
|
+
|
|
315
|
+
Create a configuration file:
|
|
316
|
+
|
|
317
|
+
```bash
|
|
318
|
+
toolip config init
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
Validate it:
|
|
322
|
+
|
|
323
|
+
```bash
|
|
324
|
+
toolip config validate
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
Display the resolved configuration:
|
|
238
328
|
|
|
239
|
-
|
|
329
|
+
```bash
|
|
330
|
+
toolip config show
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
The configuration schema supports:
|
|
334
|
+
|
|
335
|
+
* include and exclude paths
|
|
336
|
+
* rule enablement
|
|
337
|
+
* severity overrides
|
|
338
|
+
* path-specific rule policy
|
|
339
|
+
* suppressions with reasons
|
|
340
|
+
* optional suppression expiry dates
|
|
341
|
+
* history retention
|
|
342
|
+
* provider settings
|
|
343
|
+
* OSV and deps.dev timeouts
|
|
240
344
|
|
|
241
345
|
## Output and Automation
|
|
242
346
|
|
|
243
|
-
Toolip commands use non-zero exit codes for blocking failures where appropriate.
|
|
347
|
+
Toolip commands use non-zero exit codes for blocking failures where appropriate.
|
|
348
|
+
|
|
349
|
+
Machine-readable reports are intended for CI, review workflows, historical comparison, and integration with other tools.
|
|
350
|
+
|
|
351
|
+
Toolip reports can include:
|
|
244
352
|
|
|
245
|
-
|
|
353
|
+
* report schema version
|
|
354
|
+
* Toolip version
|
|
355
|
+
* project identity
|
|
356
|
+
* summary counts
|
|
357
|
+
* normalized findings
|
|
358
|
+
* analyzer metadata
|
|
359
|
+
* provider status
|
|
360
|
+
* generation timestamp
|
|
361
|
+
* scoring breakdowns
|
|
362
|
+
* confidence levels
|
|
363
|
+
* evidence fingerprints
|
|
364
|
+
* remediation guidance
|
|
246
365
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
-
|
|
250
|
-
|
|
251
|
-
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
366
|
+
## GitHub Integration
|
|
367
|
+
|
|
368
|
+
Remote repository audits and dependency-upgrade pull requests use the authenticated GitHub CLI.
|
|
369
|
+
|
|
370
|
+
Authenticate before using GitHub-connected commands:
|
|
371
|
+
|
|
372
|
+
```bash
|
|
373
|
+
gh auth login
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
Audit a public repository:
|
|
377
|
+
|
|
378
|
+
```bash
|
|
379
|
+
toolip audit-repo https://github.com/owner/repository
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
Create a tested dependency-upgrade pull request:
|
|
383
|
+
|
|
384
|
+
```bash
|
|
385
|
+
toolip upgrade-pr express 5.1.0 --dry-run
|
|
386
|
+
toolip upgrade-pr express 5.1.0
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
## MCP Server
|
|
390
|
+
|
|
391
|
+
Toolip includes a read-only MCP server over stdio.
|
|
392
|
+
|
|
393
|
+
Start it with:
|
|
394
|
+
|
|
395
|
+
```bash
|
|
396
|
+
toolip mcp
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
The MCP server exposes supported security analysis tools without exposing arbitrary shell execution or unrestricted write operations.
|
|
400
|
+
|
|
401
|
+
See [docs/MCP.md](docs/MCP.md).
|
|
255
402
|
|
|
256
403
|
## Development
|
|
257
404
|
|
|
@@ -290,7 +437,9 @@ The release check performs type checking, tests, a clean production build, packa
|
|
|
290
437
|
|
|
291
438
|
## Release Safety
|
|
292
439
|
|
|
293
|
-
Toolip v1.0.6 exposed an important release-engineering failure: the published npm package did not contain the compiled CLI.
|
|
440
|
+
Toolip v1.0.6 exposed an important release-engineering failure: the published npm package did not contain the compiled CLI.
|
|
441
|
+
|
|
442
|
+
Toolip now verifies releases from the packed artifact rather than assuming a successful local build means the package is valid.
|
|
294
443
|
|
|
295
444
|
A release is blocked unless the tarball contains:
|
|
296
445
|
|
|
@@ -309,6 +458,8 @@ toolip self-test
|
|
|
309
458
|
toolip --help
|
|
310
459
|
```
|
|
311
460
|
|
|
461
|
+
Release verification also checks version synchronization, the CLI executable shebang, changelog validity, required package contents, and isolated installation of the exact tarball that will be published.
|
|
462
|
+
|
|
312
463
|
See [RELEASING.md](RELEASING.md) for the complete release policy.
|
|
313
464
|
|
|
314
465
|
## Security
|
|
@@ -319,7 +470,9 @@ Please report suspected Toolip vulnerabilities privately according to [SECURITY.
|
|
|
319
470
|
|
|
320
471
|
## Contributing
|
|
321
472
|
|
|
322
|
-
Contributions should include tests, clear tradeoffs, and accurate security claims.
|
|
473
|
+
Contributions should include tests, clear tradeoffs, and accurate security claims.
|
|
474
|
+
|
|
475
|
+
Analyzer changes require regression coverage and must use the shared finding contracts.
|
|
323
476
|
|
|
324
477
|
See [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
325
478
|
|
|
@@ -334,7 +487,3 @@ GitHub: https://github.com/wbizmo
|
|
|
334
487
|
## License
|
|
335
488
|
|
|
336
489
|
Toolip is available under the MIT License.
|
|
337
|
-
|
|
338
|
-
## Vulnerability Intelligence
|
|
339
|
-
|
|
340
|
-
Toolip matches resolved npm dependencies against OSV.dev. See [docs/VULNERABILITY-INTELLIGENCE.md](docs/VULNERABILITY-INTELLIGENCE.md).
|
|
@@ -3,7 +3,7 @@ import { createScannerContext } from '../core/scanner-context.js';
|
|
|
3
3
|
import { createReport } from '../core/report.js';
|
|
4
4
|
import { writeReport } from '../core/report-writer.js';
|
|
5
5
|
import { scanDependencies } from '../core/dependency-scan.js';
|
|
6
|
-
import {
|
|
6
|
+
import { calculateScore } from '../core/score.js';
|
|
7
7
|
import { TOOLIP_VERSION } from '../config/version.js';
|
|
8
8
|
import { printReportSummary, printScannerContext } from '../utils/output.js';
|
|
9
9
|
export function registerScanCommand(program) {
|
|
@@ -18,8 +18,10 @@ export function registerScanCommand(program) {
|
|
|
18
18
|
const context = await createScannerContext(options.path);
|
|
19
19
|
printScannerContext(context);
|
|
20
20
|
const dependencyScan = await scanDependencies(context.root);
|
|
21
|
-
const dependencyHealth =
|
|
22
|
-
const score = calculateScore({
|
|
21
|
+
const dependencyHealth = dependencyScan.dependencyHealth;
|
|
22
|
+
const score = calculateScore({
|
|
23
|
+
dependencyHealth: dependencyHealth.score
|
|
24
|
+
});
|
|
23
25
|
const report = createReport({
|
|
24
26
|
version: TOOLIP_VERSION,
|
|
25
27
|
command: 'scan',
|
|
@@ -34,7 +36,7 @@ export function registerScanCommand(program) {
|
|
|
34
36
|
console.log(`${chalk.dim('High Risk:')} ${dependencyScan.summary.highRisk}`);
|
|
35
37
|
console.log(`${chalk.dim('Medium Risk:')} ${dependencyScan.summary.mediumRisk}`);
|
|
36
38
|
console.log(`${chalk.dim('Average Risk:')} ${dependencyScan.summary.averageRiskScore}`);
|
|
37
|
-
console.log(`${chalk.dim('Dependency Health:')} ${dependencyHealth}`);
|
|
39
|
+
console.log(`${chalk.dim('Dependency Health:')} ${dependencyHealth.score}`);
|
|
38
40
|
console.log(`${chalk.dim('Overall Grade:')} ${score.grade}`);
|
|
39
41
|
console.log('');
|
|
40
42
|
printReportSummary(report);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scan.js","sourceRoot":"","sources":["../../../src/commands/scan.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"scan.js","sourceRoot":"","sources":["../../../src/commands/scan.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,15 +1,26 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import { scanDependencies } from '../core/dependency-scan.js';
|
|
3
|
-
import {
|
|
3
|
+
import { calculateScore } from '../core/score.js';
|
|
4
4
|
export function registerScoreCommand(program) {
|
|
5
5
|
program
|
|
6
6
|
.command('score')
|
|
7
7
|
.description('Calculate a Toolip security scorecard for the current project.')
|
|
8
8
|
.option('-p, --path <path>', 'Project path to score.', process.cwd())
|
|
9
|
+
.option('--json', 'Print structured JSON output.')
|
|
9
10
|
.action(async (options) => {
|
|
10
11
|
const dependencyScan = await scanDependencies(options.path);
|
|
11
|
-
const dependencyHealth =
|
|
12
|
-
const score = calculateScore({
|
|
12
|
+
const dependencyHealth = dependencyScan.dependencyHealth;
|
|
13
|
+
const score = calculateScore({
|
|
14
|
+
dependencyHealth: dependencyHealth.score
|
|
15
|
+
});
|
|
16
|
+
if (options.json) {
|
|
17
|
+
console.log(JSON.stringify({
|
|
18
|
+
score,
|
|
19
|
+
dependencyHealth,
|
|
20
|
+
dependencySummary: dependencyScan.summary
|
|
21
|
+
}, null, 2));
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
13
24
|
console.log(chalk.bold('Toolip Security Scorecard'));
|
|
14
25
|
console.log('');
|
|
15
26
|
console.log(`${chalk.dim('Dependency Health ....')} ${score.dependencyHealth}`);
|
|
@@ -19,6 +30,12 @@ export function registerScoreCommand(program) {
|
|
|
19
30
|
console.log('');
|
|
20
31
|
console.log(`${chalk.dim('Overall Score ........')} ${score.overall}`);
|
|
21
32
|
console.log(`${chalk.dim('Grade ................')} ${score.grade}`);
|
|
33
|
+
console.log('');
|
|
34
|
+
console.log(chalk.dim('Dependency score breakdown'));
|
|
35
|
+
console.log(`${chalk.dim('Vulnerability penalty')} ${dependencyHealth.vulnerabilityPenalty}`);
|
|
36
|
+
console.log(`${chalk.dim('Deprecation penalty ..')} ${dependencyHealth.deprecationPenalty}`);
|
|
37
|
+
console.log(`${chalk.dim('Maintenance penalty ..')} ${dependencyHealth.maintenancePenalty}`);
|
|
38
|
+
console.log(`${chalk.dim('Freshness penalty ....')} ${dependencyHealth.freshnessPenalty}`);
|
|
22
39
|
});
|
|
23
40
|
}
|
|
24
41
|
//# sourceMappingURL=score.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"score.js","sourceRoot":"","sources":["../../../src/commands/score.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"score.js","sourceRoot":"","sources":["../../../src/commands/score.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { PackageHealth } from './dependency-types.js';
|
|
2
2
|
import type { ToolipFinding } from './report.js';
|
|
3
|
+
import { type DependencyHealthBreakdown } from './score.js';
|
|
3
4
|
export type DependencyScanResult = {
|
|
4
5
|
packages: PackageHealth[];
|
|
5
6
|
findings: ToolipFinding[];
|
|
7
|
+
dependencyHealth: DependencyHealthBreakdown;
|
|
6
8
|
summary: {
|
|
7
9
|
totalDependencies: number;
|
|
8
10
|
outdated: number;
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import { readDependencies } from './read-dependencies.js';
|
|
2
2
|
import { analyzePackage } from './analyze-package.js';
|
|
3
|
+
import { calculateDependencyHealthFromPackages } from './score.js';
|
|
3
4
|
export async function scanDependencies(root) {
|
|
4
5
|
const dependencies = await readDependencies(root);
|
|
5
6
|
const packages = await Promise.all(dependencies.map((dependency) => analyzePackage(dependency)));
|
|
6
7
|
const findings = packages.flatMap(packageToFindings);
|
|
8
|
+
const dependencyHealth = calculateDependencyHealthFromPackages(packages);
|
|
7
9
|
return {
|
|
8
10
|
packages,
|
|
9
11
|
findings,
|
|
12
|
+
dependencyHealth,
|
|
10
13
|
summary: {
|
|
11
14
|
totalDependencies: packages.length,
|
|
12
15
|
outdated: packages.filter((pkg) => pkg.outdated).length,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dependency-scan.js","sourceRoot":"","sources":["../../../src/core/dependency-scan.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"dependency-scan.js","sourceRoot":"","sources":["../../../src/core/dependency-scan.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAGtD,OAAO,EACL,qCAAqC,EAEtC,MAAM,YAAY,CAAC;AAiBpB,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAAY;IACjD,MAAM,YAAY,GAAG,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAClD,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,CAChC,YAAY,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CAC7D,CAAC;IAEF,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAErD,MAAM,gBAAgB,GACpB,qCAAqC,CACnC,QAAQ,CACT,CAAC;IAEJ,OAAO;QACL,QAAQ;QACR,QAAQ;QACR,gBAAgB;QAChB,OAAO,EAAE;YACP,iBAAiB,EAAE,QAAQ,CAAC,MAAM;YAClC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,MAAM;YACvD,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,MAAM;YAC3D,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,MAAM;YAC9D,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,SAAS,IAAI,EAAE,IAAI,GAAG,CAAC,SAAS,GAAG,EAAE,CAAC,CAAC,MAAM;YACtF,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,SAAS,GAAG,CAAC,IAAI,GAAG,CAAC,SAAS,GAAG,EAAE,CAAC,CAAC,MAAM;YACjF,gBAAgB,EAAE,QAAQ,CAAC,MAAM,KAAK,CAAC;gBACrC,CAAC,CAAC,CAAC;gBACH,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC;SAC5F;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,GAAkB;IAClD,MAAM,QAAQ,GAAoB,EAAE,CAAC;IAErC,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC;QACnB,QAAQ,CAAC,IAAI,CAAC;YACZ,EAAE,EAAE,yBAAyB,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,YAAY,EAAE,GAAG,CAAC,EAAE;YACnF,KAAK,EAAE,uBAAuB,GAAG,CAAC,IAAI,EAAE;YACxC,QAAQ,EAAE,MAAM;YAChB,QAAQ,EAAE,cAAc;YACxB,OAAO,EAAE,GAAG,GAAG,CAAC,IAAI,+CAA+C;YACnE,cAAc,EAAE,sFAAsF;YACtG,QAAQ,EAAE,GAAG,CAAC,aAAa,IAAI,SAAS;SACzC,CAAC,CAAC;IACL,CAAC;IAED,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;QACjB,QAAQ,CAAC,IAAI,CAAC;YACZ,EAAE,EAAE,uBAAuB,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,YAAY,EAAE,GAAG,CAAC,EAAE;YACjF,KAAK,EAAE,qBAAqB,GAAG,CAAC,IAAI,EAAE;YACtC,QAAQ,EAAE,QAAQ;YAClB,QAAQ,EAAE,cAAc;YACxB,OAAO,EAAE,GAAG,GAAG,CAAC,IAAI,iCAAiC,GAAG,CAAC,gBAAgB,aAAa,GAAG,CAAC,aAAa,IAAI,SAAS,GAAG;YACvH,cAAc,EAAE,qFAAqF;YACrG,QAAQ,EAAE,GAAG,GAAG,CAAC,gBAAgB,OAAO,GAAG,CAAC,aAAa,IAAI,SAAS,EAAE;SACzE,CAAC,CAAC;IACL,CAAC;IAED,IAAI,GAAG,CAAC,WAAW,KAAK,CAAC,EAAE,CAAC;QAC1B,QAAQ,CAAC,IAAI,CAAC;YACZ,EAAE,EAAE,6BAA6B,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,YAAY,EAAE,GAAG,CAAC,EAAE;YACvF,KAAK,EAAE,2BAA2B,GAAG,CAAC,IAAI,EAAE;YAC5C,QAAQ,EAAE,QAAQ;YAClB,QAAQ,EAAE,cAAc;YACxB,OAAO,EAAE,GAAG,GAAG,CAAC,IAAI,iEAAiE;YACrF,cAAc,EAAE,oGAAoG;SACrH,CAAC,CAAC;IACL,CAAC;IAED,IAAI,GAAG,CAAC,SAAS,KAAK,IAAI,IAAI,GAAG,CAAC,SAAS,GAAG,GAAG,EAAE,CAAC;QAClD,QAAQ,CAAC,IAAI,CAAC;YACZ,EAAE,EAAE,oBAAoB,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,YAAY,EAAE,GAAG,CAAC,EAAE;YAC9E,KAAK,EAAE,2BAA2B,GAAG,CAAC,IAAI,EAAE;YAC5C,QAAQ,EAAE,KAAK;YACf,QAAQ,EAAE,cAAc;YACxB,OAAO,EAAE,GAAG,GAAG,CAAC,IAAI,gEAAgE;YACpF,cAAc,EAAE,wFAAwF;YACxG,QAAQ,EAAE,GAAG,GAAG,CAAC,SAAS,OAAO;SAClC,CAAC,CAAC;IACL,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
package/dist/src/core/score.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { PackageHealth } from './dependency-types.js';
|
|
1
2
|
import type { ToolipFinding } from './report.js';
|
|
2
3
|
export type ScoreGrade = 'A' | 'B' | 'C' | 'D' | 'F';
|
|
3
4
|
export type ToolipScore = {
|
|
@@ -8,6 +9,27 @@ export type ToolipScore = {
|
|
|
8
9
|
overall: number;
|
|
9
10
|
grade: ScoreGrade;
|
|
10
11
|
};
|
|
12
|
+
export type DependencyHealthBreakdown = {
|
|
13
|
+
score: number;
|
|
14
|
+
vulnerabilityPenalty: number;
|
|
15
|
+
deprecationPenalty: number;
|
|
16
|
+
maintenancePenalty: number;
|
|
17
|
+
freshnessPenalty: number;
|
|
18
|
+
outdated: {
|
|
19
|
+
major: number;
|
|
20
|
+
minor: number;
|
|
21
|
+
patch: number;
|
|
22
|
+
unknown: number;
|
|
23
|
+
};
|
|
24
|
+
};
|
|
11
25
|
export declare function calculateScore(input?: Partial<Omit<ToolipScore, 'overall' | 'grade'>>): ToolipScore;
|
|
26
|
+
export declare function calculateDependencyHealthFromPackages(packages: PackageHealth[], vulnerabilityFindings?: ToolipFinding[]): DependencyHealthBreakdown;
|
|
27
|
+
/**
|
|
28
|
+
* Backward-compatible finding-based score.
|
|
29
|
+
*
|
|
30
|
+
* Outdated-package findings are treated as maintenance
|
|
31
|
+
* signals and capped so they cannot independently collapse
|
|
32
|
+
* dependency health to zero.
|
|
33
|
+
*/
|
|
12
34
|
export declare function calculateDependencyHealth(findings: ToolipFinding[]): number;
|
|
13
35
|
export declare function gradeScore(score: number): ScoreGrade;
|
package/dist/src/core/score.js
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
|
+
import semver from 'semver';
|
|
1
2
|
export function calculateScore(input) {
|
|
2
3
|
const dependencyHealth = clamp(input?.dependencyHealth ?? 100);
|
|
3
4
|
const secretHygiene = clamp(input?.secretHygiene ?? 100);
|
|
4
5
|
const configurationSecurity = clamp(input?.configurationSecurity ?? 100);
|
|
5
6
|
const gitSafety = clamp(input?.gitSafety ?? 100);
|
|
6
|
-
const overall = Math.round((dependencyHealth +
|
|
7
|
+
const overall = Math.round((dependencyHealth +
|
|
8
|
+
secretHygiene +
|
|
9
|
+
configurationSecurity +
|
|
10
|
+
gitSafety) / 4);
|
|
7
11
|
return {
|
|
8
12
|
dependencyHealth,
|
|
9
13
|
secretHygiene,
|
|
@@ -13,19 +17,140 @@ export function calculateScore(input) {
|
|
|
13
17
|
grade: gradeScore(overall)
|
|
14
18
|
};
|
|
15
19
|
}
|
|
20
|
+
export function calculateDependencyHealthFromPackages(packages, vulnerabilityFindings = []) {
|
|
21
|
+
let criticalVulnerabilities = 0;
|
|
22
|
+
let highVulnerabilities = 0;
|
|
23
|
+
let mediumVulnerabilities = 0;
|
|
24
|
+
let lowVulnerabilities = 0;
|
|
25
|
+
for (const finding of vulnerabilityFindings) {
|
|
26
|
+
if (finding.category !== 'vulnerability') {
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
if (finding.severity === 'critical') {
|
|
30
|
+
criticalVulnerabilities += 1;
|
|
31
|
+
}
|
|
32
|
+
else if (finding.severity === 'high') {
|
|
33
|
+
highVulnerabilities += 1;
|
|
34
|
+
}
|
|
35
|
+
else if (finding.severity === 'medium') {
|
|
36
|
+
mediumVulnerabilities += 1;
|
|
37
|
+
}
|
|
38
|
+
else if (finding.severity === 'low') {
|
|
39
|
+
lowVulnerabilities += 1;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
const vulnerabilityPenalty = Math.min(100, criticalVulnerabilities * 40 +
|
|
43
|
+
highVulnerabilities * 25 +
|
|
44
|
+
mediumVulnerabilities * 12 +
|
|
45
|
+
lowVulnerabilities * 4);
|
|
46
|
+
const deprecated = packages.filter((pkg) => pkg.deprecated).length;
|
|
47
|
+
const noMaintainers = packages.filter((pkg) => pkg.maintainers === 0).length;
|
|
48
|
+
const stale = packages.filter((pkg) => pkg.ageInDays !== null &&
|
|
49
|
+
pkg.ageInDays > 730).length;
|
|
50
|
+
const outdated = {
|
|
51
|
+
major: 0,
|
|
52
|
+
minor: 0,
|
|
53
|
+
patch: 0,
|
|
54
|
+
unknown: 0
|
|
55
|
+
};
|
|
56
|
+
for (const pkg of packages) {
|
|
57
|
+
if (!pkg.outdated ||
|
|
58
|
+
!pkg.latestVersion) {
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
const installed = semver.coerce(pkg.installedVersion);
|
|
62
|
+
const latest = semver.coerce(pkg.latestVersion);
|
|
63
|
+
if (!installed || !latest) {
|
|
64
|
+
outdated.unknown += 1;
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
if (latest.major > installed.major) {
|
|
68
|
+
outdated.major += 1;
|
|
69
|
+
}
|
|
70
|
+
else if (latest.minor > installed.minor) {
|
|
71
|
+
outdated.minor += 1;
|
|
72
|
+
}
|
|
73
|
+
else if (latest.patch > installed.patch) {
|
|
74
|
+
outdated.patch += 1;
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
outdated.unknown += 1;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const deprecationPenalty = Math.min(40, deprecated * 18);
|
|
81
|
+
const maintenancePenalty = Math.min(20, noMaintainers * 4);
|
|
82
|
+
const freshnessPenalty = Math.min(15, outdated.major * 3 +
|
|
83
|
+
outdated.minor * 1 +
|
|
84
|
+
outdated.patch * 0.25 +
|
|
85
|
+
outdated.unknown * 1 +
|
|
86
|
+
stale * 1);
|
|
87
|
+
const score = clamp(100 -
|
|
88
|
+
vulnerabilityPenalty -
|
|
89
|
+
deprecationPenalty -
|
|
90
|
+
maintenancePenalty -
|
|
91
|
+
freshnessPenalty);
|
|
92
|
+
return {
|
|
93
|
+
score,
|
|
94
|
+
vulnerabilityPenalty,
|
|
95
|
+
deprecationPenalty,
|
|
96
|
+
maintenancePenalty,
|
|
97
|
+
freshnessPenalty: Math.round(freshnessPenalty * 100) /
|
|
98
|
+
100,
|
|
99
|
+
outdated
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Backward-compatible finding-based score.
|
|
104
|
+
*
|
|
105
|
+
* Outdated-package findings are treated as maintenance
|
|
106
|
+
* signals and capped so they cannot independently collapse
|
|
107
|
+
* dependency health to zero.
|
|
108
|
+
*/
|
|
16
109
|
export function calculateDependencyHealth(findings) {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
if (finding.
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
110
|
+
let vulnerabilityPenalty = 0;
|
|
111
|
+
let deprecationPenalty = 0;
|
|
112
|
+
let maintenancePenalty = 0;
|
|
113
|
+
let freshnessPenalty = 0;
|
|
114
|
+
for (const finding of findings) {
|
|
115
|
+
if (finding.category === 'vulnerability') {
|
|
116
|
+
vulnerabilityPenalty +=
|
|
117
|
+
severityPenalty(finding.severity);
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
if (finding.id.startsWith('TOOLIP-DEP-DEPRECATED-')) {
|
|
121
|
+
deprecationPenalty += 18;
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
if (finding.id.startsWith('TOOLIP-DEP-OUTDATED-')) {
|
|
125
|
+
freshnessPenalty += 1;
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
if (finding.id.startsWith('TOOLIP-DEP-NO-MAINTAINERS-')) {
|
|
129
|
+
maintenancePenalty += 4;
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
if (finding.id.startsWith('TOOLIP-DEP-STALE-')) {
|
|
133
|
+
freshnessPenalty += 1;
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
maintenancePenalty += Math.min(10, severityPenalty(finding.severity));
|
|
137
|
+
}
|
|
138
|
+
return clamp(100 -
|
|
139
|
+
Math.min(100, vulnerabilityPenalty) -
|
|
140
|
+
Math.min(40, deprecationPenalty) -
|
|
141
|
+
Math.min(20, maintenancePenalty) -
|
|
142
|
+
Math.min(15, freshnessPenalty));
|
|
143
|
+
}
|
|
144
|
+
function severityPenalty(severity) {
|
|
145
|
+
if (severity === 'critical')
|
|
146
|
+
return 40;
|
|
147
|
+
if (severity === 'high')
|
|
148
|
+
return 25;
|
|
149
|
+
if (severity === 'medium')
|
|
150
|
+
return 12;
|
|
151
|
+
if (severity === 'low')
|
|
152
|
+
return 4;
|
|
153
|
+
return 0;
|
|
29
154
|
}
|
|
30
155
|
function clamp(value) {
|
|
31
156
|
return Math.max(0, Math.min(100, Math.round(value)));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"score.js","sourceRoot":"","sources":["../../../src/core/score.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"score.js","sourceRoot":"","sources":["../../../src/core/score.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "toolip",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.1",
|
|
4
4
|
"description": "A TypeScript-powered developer security companion CLI for supply chain security, dependency intelligence, secret detection, security auditing, encrypted local secrets management, Git security checks, and secure development education.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -21,10 +21,11 @@
|
|
|
21
21
|
"test:watch": "vitest",
|
|
22
22
|
"typecheck": "tsc --noEmit",
|
|
23
23
|
"verify:package": "node scripts/verify-package.mjs",
|
|
24
|
-
"verify": "npm run typecheck && npm test && npm run clean && npm run build && npm run verify:package",
|
|
24
|
+
"verify": "npm run verify:changelog && npm run typecheck && npm test && npm run clean && npm run build && npm run verify:package",
|
|
25
25
|
"prepack": "npm run verify",
|
|
26
26
|
"pack:check": "npm pack --dry-run",
|
|
27
|
-
"release:check": "bash scripts/release-check.sh"
|
|
27
|
+
"release:check": "bash scripts/release-check.sh",
|
|
28
|
+
"verify:changelog": "node scripts/verify-changelog.mjs"
|
|
28
29
|
},
|
|
29
30
|
"keywords": [
|
|
30
31
|
"typescript",
|