alterks 0.1.0__tar.gz
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.
- alterks-0.1.0/.github/workflows/publish.yml +30 -0
- alterks-0.1.0/.gitignore +39 -0
- alterks-0.1.0/LICENSE +21 -0
- alterks-0.1.0/PKG-INFO +335 -0
- alterks-0.1.0/README.md +294 -0
- alterks-0.1.0/pyproject.toml +104 -0
- alterks-0.1.0/src/alterks/__init__.py +20 -0
- alterks-0.1.0/src/alterks/actions.py +244 -0
- alterks-0.1.0/src/alterks/cli.py +505 -0
- alterks-0.1.0/src/alterks/config.py +180 -0
- alterks-0.1.0/src/alterks/data/top_packages.txt +5004 -0
- alterks-0.1.0/src/alterks/heuristics.py +298 -0
- alterks-0.1.0/src/alterks/models.py +142 -0
- alterks-0.1.0/src/alterks/monitor.py +276 -0
- alterks-0.1.0/src/alterks/pip_hook.py +112 -0
- alterks-0.1.0/src/alterks/quarantine.py +272 -0
- alterks-0.1.0/src/alterks/scanner.py +257 -0
- alterks-0.1.0/src/alterks/sources/__init__.py +1 -0
- alterks-0.1.0/src/alterks/sources/osv.py +383 -0
- alterks-0.1.0/src/alterks/sources/pypi.py +276 -0
- alterks-0.1.0/tests/__init__.py +0 -0
- alterks-0.1.0/tests/conftest.py +149 -0
- alterks-0.1.0/tests/helpers.py +33 -0
- alterks-0.1.0/tests/test_actions.py +267 -0
- alterks-0.1.0/tests/test_cli.py +430 -0
- alterks-0.1.0/tests/test_config.py +246 -0
- alterks-0.1.0/tests/test_heuristics.py +314 -0
- alterks-0.1.0/tests/test_monitor.py +448 -0
- alterks-0.1.0/tests/test_osv.py +250 -0
- alterks-0.1.0/tests/test_pip_hook.py +162 -0
- alterks-0.1.0/tests/test_pypi.py +278 -0
- alterks-0.1.0/tests/test_quarantine.py +274 -0
- alterks-0.1.0/tests/test_scanner.py +322 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
id-token: write # Required for trusted publishing
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
publish:
|
|
12
|
+
name: Build & Publish to PyPI
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
environment: pypi
|
|
15
|
+
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- uses: actions/setup-python@v5
|
|
20
|
+
with:
|
|
21
|
+
python-version: "3.12"
|
|
22
|
+
|
|
23
|
+
- name: Install build tools
|
|
24
|
+
run: pip install build
|
|
25
|
+
|
|
26
|
+
- name: Build package
|
|
27
|
+
run: python -m build
|
|
28
|
+
|
|
29
|
+
- name: Publish to PyPI
|
|
30
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
alterks-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
*.egg-info/
|
|
7
|
+
*.egg
|
|
8
|
+
dist/
|
|
9
|
+
build/
|
|
10
|
+
*.whl
|
|
11
|
+
|
|
12
|
+
# Virtual environments
|
|
13
|
+
.venv/
|
|
14
|
+
venv/
|
|
15
|
+
ENV/
|
|
16
|
+
|
|
17
|
+
# Testing
|
|
18
|
+
.pytest_cache/
|
|
19
|
+
.coverage
|
|
20
|
+
htmlcov/
|
|
21
|
+
.tox/
|
|
22
|
+
|
|
23
|
+
# IDE
|
|
24
|
+
.vscode/
|
|
25
|
+
.idea/
|
|
26
|
+
*.swp
|
|
27
|
+
*.swo
|
|
28
|
+
*~
|
|
29
|
+
|
|
30
|
+
# OS
|
|
31
|
+
.DS_Store
|
|
32
|
+
Thumbs.db
|
|
33
|
+
desktop.ini
|
|
34
|
+
|
|
35
|
+
# Project
|
|
36
|
+
AlterKS-plan.md
|
|
37
|
+
|
|
38
|
+
# Build artifacts
|
|
39
|
+
*.dist-info/
|
alterks-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 AlterKS Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
alterks-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: alterks
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: ALTER KILL SWITCH — Python package scanner, monitor, and supply chain attack mitigation tool.
|
|
5
|
+
Project-URL: Homepage, https://github.com/Wan-Saifudin-DS/AlterKS
|
|
6
|
+
Project-URL: Documentation, https://github.com/Wan-Saifudin-DS/AlterKS#readme
|
|
7
|
+
Project-URL: Repository, https://github.com/Wan-Saifudin-DS/AlterKS
|
|
8
|
+
Project-URL: Issues, https://github.com/Wan-Saifudin-DS/AlterKS/issues
|
|
9
|
+
Author: AlterKS Contributors
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: kill-switch,pip,pypi,scanner,security,supply-chain,vulnerability
|
|
13
|
+
Classifier: Development Status :: 3 - Alpha
|
|
14
|
+
Classifier: Environment :: Console
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
24
|
+
Classifier: Topic :: Security
|
|
25
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
26
|
+
Classifier: Topic :: System :: Systems Administration
|
|
27
|
+
Requires-Python: >=3.9
|
|
28
|
+
Requires-Dist: click>=8.0
|
|
29
|
+
Requires-Dist: httpx>=0.24
|
|
30
|
+
Requires-Dist: packaging>=21.0
|
|
31
|
+
Requires-Dist: rich>=12.0
|
|
32
|
+
Requires-Dist: tomli>=1.1; python_version < '3.11'
|
|
33
|
+
Provides-Extra: dev
|
|
34
|
+
Requires-Dist: build>=1.0; extra == 'dev'
|
|
35
|
+
Requires-Dist: pytest-asyncio>=0.21; extra == 'dev'
|
|
36
|
+
Requires-Dist: pytest>=7.0; extra == 'dev'
|
|
37
|
+
Requires-Dist: respx>=0.20; extra == 'dev'
|
|
38
|
+
Requires-Dist: ruff>=0.1; extra == 'dev'
|
|
39
|
+
Requires-Dist: twine>=4.0; extra == 'dev'
|
|
40
|
+
Description-Content-Type: text/markdown
|
|
41
|
+
|
|
42
|
+
# AlterKS — ALTER KILL SWITCH
|
|
43
|
+
|
|
44
|
+
[](https://pypi.org/project/alterks/)
|
|
45
|
+
[](https://pypi.org/project/alterks/)
|
|
46
|
+
[](https://opensource.org/licenses/MIT)
|
|
47
|
+
[](https://github.com/Wan-Saifudin-DS/AlterKS/actions)
|
|
48
|
+
|
|
49
|
+
**Python package scanner, monitor, and supply chain attack mitigation tool.**
|
|
50
|
+
|
|
51
|
+
AlterKS scans your Python dependencies for known vulnerabilities (via [OSV.dev](https://osv.dev)) and suspicious package metadata heuristics, then takes configurable action: **block** installation, **quarantine** to an isolated environment, or **alert** with a warning.
|
|
52
|
+
|
|
53
|
+
## Why AlterKS?
|
|
54
|
+
|
|
55
|
+
Supply chain attacks on PyPI are increasing — typosquatting, dependency confusion, and hijacked maintainer accounts are real threats. Existing tools like `pip-audit` and `safety` check for known CVEs, but don't:
|
|
56
|
+
|
|
57
|
+
- **Block installs before they happen** — AlterKS wraps `pip install` with a pre-scan gate
|
|
58
|
+
- **Score risk heuristically** — detect suspicious packages that have no CVEs yet (typosquats, brand-new single-maintainer packages)
|
|
59
|
+
- **Quarantine instead of just blocking** — isolate risky packages for inspection without polluting your environment
|
|
60
|
+
- **Monitor continuously** — detect newly disclosed vulnerabilities against already-installed packages
|
|
61
|
+
- **Generate constraints** — output pip constraint files to lock down your dependency tree
|
|
62
|
+
|
|
63
|
+
## Architecture
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
67
|
+
│ CLI Interface │
|
|
68
|
+
│ alterks scan | install | monitor | quarantine | report │
|
|
69
|
+
├─────────────┬───────────────────────────────────┬───────────────┤
|
|
70
|
+
│ Scanner │ Heuristic Risk Engine │ Monitor │
|
|
71
|
+
│ (scanner) │ (heuristics) │ (monitor) │
|
|
72
|
+
├─────────────┼───────────────────────────────────┼───────────────┤
|
|
73
|
+
│ │ Data Sources Layer │ │
|
|
74
|
+
│ │ ┌──────────┐ ┌───────────┐ │ │
|
|
75
|
+
│ │ │ OSV.dev │ │ PyPI JSON │ │ │
|
|
76
|
+
│ │ │ Client │ │ Client │ │ │
|
|
77
|
+
│ │ └──────────┘ └───────────┘ │ │
|
|
78
|
+
├─────────────┴───────────────────────────────────┴───────────────┤
|
|
79
|
+
│ Action Engine │
|
|
80
|
+
│ BLOCK | QUARANTINE | ALERT | ALLOW │
|
|
81
|
+
├─────────────────────────────────────────────────────────────────┤
|
|
82
|
+
│ Policy Config (pyproject.toml) │
|
|
83
|
+
│ [tool.alterks] severity, allowlist, actions │
|
|
84
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Features
|
|
88
|
+
|
|
89
|
+
- **Vulnerability scanning** — queries OSV.dev for known CVEs/PYSECs against installed or to-be-installed packages
|
|
90
|
+
- **Heuristic risk scoring** — detects typosquatting, suspiciously new packages, single-maintainer risks, poor metadata quality
|
|
91
|
+
- **Kill switch actions** — block, quarantine, or alert based on configurable severity thresholds
|
|
92
|
+
- **Pre-install protection** — `alterks install <pkg>` scans before pip installs
|
|
93
|
+
- **Continuous monitoring** — scheduled re-scans detect newly disclosed vulnerabilities with JSON and webhook notifications
|
|
94
|
+
- **Quarantine management** — isolate risky packages in separate virtual environments
|
|
95
|
+
- **Constraint generation** — output pip constraint files to block known-bad versions
|
|
96
|
+
- **Policy-driven** — configure everything via `[tool.alterks]` in `pyproject.toml`
|
|
97
|
+
|
|
98
|
+
## Installation
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
pip install alterks
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
For development:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
pip install alterks[dev]
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Quick Start
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
# Scan your current environment
|
|
114
|
+
alterks scan
|
|
115
|
+
|
|
116
|
+
# Scan a requirements file
|
|
117
|
+
alterks scan -r requirements.txt
|
|
118
|
+
|
|
119
|
+
# Install a package with pre-install scanning
|
|
120
|
+
alterks install flask
|
|
121
|
+
|
|
122
|
+
# Start continuous monitoring
|
|
123
|
+
alterks monitor --once
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## CLI Reference
|
|
127
|
+
|
|
128
|
+
### `alterks scan`
|
|
129
|
+
|
|
130
|
+
Scan installed packages or a requirements file for vulnerabilities and heuristic risks.
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
# Scan current environment (table output)
|
|
134
|
+
alterks scan
|
|
135
|
+
|
|
136
|
+
# Scan with JSON output
|
|
137
|
+
alterks scan --format json
|
|
138
|
+
|
|
139
|
+
# Scan with Markdown output
|
|
140
|
+
alterks scan --format markdown
|
|
141
|
+
|
|
142
|
+
# Scan a requirements file
|
|
143
|
+
alterks scan -r requirements.txt
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
**Options:**
|
|
147
|
+
- `-r, --requirements FILE` — scan a requirements file instead of the environment
|
|
148
|
+
- `--format [table|json|markdown]` — output format (default: `table`)
|
|
149
|
+
|
|
150
|
+
**Exit codes:** `0` = all clean, `1` = blocked packages found.
|
|
151
|
+
|
|
152
|
+
### `alterks install`
|
|
153
|
+
|
|
154
|
+
Pre-scan a package before installing it with pip. Blocks installation if the scan detects critical issues.
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
# Install with pre-scan
|
|
158
|
+
alterks install requests
|
|
159
|
+
|
|
160
|
+
# Dry-run (scan only, no install)
|
|
161
|
+
alterks install flask --dry-run
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
**Options:**
|
|
165
|
+
- `--dry-run` — scan only, do not run pip install
|
|
166
|
+
|
|
167
|
+
### `alterks quarantine`
|
|
168
|
+
|
|
169
|
+
Manage packages that have been quarantined to isolated virtual environments.
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
# List quarantined packages
|
|
173
|
+
alterks quarantine list
|
|
174
|
+
|
|
175
|
+
# Inspect a specific quarantined package
|
|
176
|
+
alterks quarantine inspect <name> <version>
|
|
177
|
+
|
|
178
|
+
# Release a package from quarantine
|
|
179
|
+
alterks quarantine release <name> <version>
|
|
180
|
+
|
|
181
|
+
# Remove a quarantined package entirely
|
|
182
|
+
alterks quarantine remove <name> <version>
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### `alterks report`
|
|
186
|
+
|
|
187
|
+
Generate a comprehensive scan report of your environment.
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
# Print JSON report
|
|
191
|
+
alterks report --format json
|
|
192
|
+
|
|
193
|
+
# Write Markdown report to a file
|
|
194
|
+
alterks report --format markdown -o report.md
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
**Options:**
|
|
198
|
+
- `--format [table|json|markdown]` — output format (default: `table`)
|
|
199
|
+
- `-o, --output FILE` — write report to a file instead of stdout
|
|
200
|
+
|
|
201
|
+
### `alterks monitor`
|
|
202
|
+
|
|
203
|
+
Continuously monitor installed packages for newly disclosed vulnerabilities.
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
# Run a single scan
|
|
207
|
+
alterks monitor --once
|
|
208
|
+
|
|
209
|
+
# Run every hour
|
|
210
|
+
alterks monitor --interval 3600
|
|
211
|
+
|
|
212
|
+
# Save reports to a JSON-lines file
|
|
213
|
+
alterks monitor --json-output reports.jsonl
|
|
214
|
+
|
|
215
|
+
# Send reports to a webhook
|
|
216
|
+
alterks monitor --webhook-url https://example.com/hook
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
**Options:**
|
|
220
|
+
- `--interval SECONDS` — scan interval (default: `86400` = 24 hours)
|
|
221
|
+
- `--once` — run a single scan and exit
|
|
222
|
+
- `--json-output FILE` — append JSON-lines reports to a file
|
|
223
|
+
- `--webhook-url URL` — POST scan reports to a webhook endpoint
|
|
224
|
+
|
|
225
|
+
### `alterks generate-constraints`
|
|
226
|
+
|
|
227
|
+
Generate a pip constraints file that blocks known-vulnerable versions.
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
# Print to stdout
|
|
231
|
+
alterks generate-constraints
|
|
232
|
+
|
|
233
|
+
# Write to file
|
|
234
|
+
alterks generate-constraints -o constraints.txt
|
|
235
|
+
|
|
236
|
+
# Then use with pip:
|
|
237
|
+
pip install -c constraints.txt -r requirements.txt
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
**Options:**
|
|
241
|
+
- `-o, --output FILE` — write constraints to a file instead of stdout
|
|
242
|
+
|
|
243
|
+
### Global Options
|
|
244
|
+
|
|
245
|
+
All commands support:
|
|
246
|
+
- `--verbose` — enable debug logging
|
|
247
|
+
- `--quiet` — suppress informational output
|
|
248
|
+
- `--no-color` — disable colored output
|
|
249
|
+
|
|
250
|
+
## Configuration
|
|
251
|
+
|
|
252
|
+
Add to your `pyproject.toml`:
|
|
253
|
+
|
|
254
|
+
```toml
|
|
255
|
+
[tool.alterks]
|
|
256
|
+
# Action per severity: "block", "quarantine", "alert", "allow"
|
|
257
|
+
severity_actions = { critical = "block", high = "block", medium = "alert", low = "allow" }
|
|
258
|
+
|
|
259
|
+
# Risk score threshold (0-100) — packages above this trigger the configured action
|
|
260
|
+
risk_threshold = 60
|
|
261
|
+
|
|
262
|
+
# Packages always allowed regardless of scan results
|
|
263
|
+
allowlist = ["my-internal-package"]
|
|
264
|
+
|
|
265
|
+
# Packages always blocked regardless of scan results
|
|
266
|
+
blocklist = ["known-malicious-pkg"]
|
|
267
|
+
|
|
268
|
+
[tool.alterks.heuristic_weights]
|
|
269
|
+
typosquatting = 0.30
|
|
270
|
+
package_age = 0.20
|
|
271
|
+
maintainer_count = 0.15
|
|
272
|
+
release_pattern = 0.15
|
|
273
|
+
metadata_quality = 0.20
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
## Heuristic Risk Factors
|
|
277
|
+
|
|
278
|
+
| Factor | Weight | What it detects |
|
|
279
|
+
|--------|--------|-----------------|
|
|
280
|
+
| **Typosquatting** | 30% | Name similarity to top 5,000 PyPI packages |
|
|
281
|
+
| **Package age** | 20% | Recently created packages (< 30 days) |
|
|
282
|
+
| **Maintainer count** | 15% | Single-maintainer packages |
|
|
283
|
+
| **Release pattern** | 15% | Unusual version release cadence |
|
|
284
|
+
| **Metadata quality** | 20% | Missing descriptions, URLs, classifiers |
|
|
285
|
+
|
|
286
|
+
## Development
|
|
287
|
+
|
|
288
|
+
```bash
|
|
289
|
+
# Clone and install in editable mode
|
|
290
|
+
git clone https://github.com/Wan-Saifudin-DS/AlterKS.git
|
|
291
|
+
cd AlterKS
|
|
292
|
+
pip install -e ".[dev]"
|
|
293
|
+
|
|
294
|
+
# Run tests
|
|
295
|
+
pytest tests/
|
|
296
|
+
|
|
297
|
+
# Lint
|
|
298
|
+
ruff check src/ tests/
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
## Project Structure
|
|
302
|
+
|
|
303
|
+
```
|
|
304
|
+
src/alterks/
|
|
305
|
+
├── __init__.py # Version, public API
|
|
306
|
+
├── models.py # Core dataclasses (ScanResult, Vulnerability, PolicyAction)
|
|
307
|
+
├── config.py # Policy config loader from pyproject.toml
|
|
308
|
+
├── scanner.py # Scan orchestrator: environment/requirements scanning
|
|
309
|
+
├── heuristics.py # Composite risk scorer (typosquatting, age, maintainer…)
|
|
310
|
+
├── actions.py # Kill switch logic: block, quarantine, alert
|
|
311
|
+
├── quarantine.py # Isolated venv quarantine manager
|
|
312
|
+
├── cli.py # CLI commands (scan, install, monitor, quarantine, report)
|
|
313
|
+
├── pip_hook.py # Pip install wrapper with pre-scan
|
|
314
|
+
├── monitor.py # Continuous monitoring daemon
|
|
315
|
+
├── sources/
|
|
316
|
+
│ ├── osv.py # OSV.dev API client (single + batch queries)
|
|
317
|
+
│ └── pypi.py # PyPI JSON API client for metadata heuristics
|
|
318
|
+
└── data/
|
|
319
|
+
└── top_packages.txt # Bundled top-5,000 PyPI package names (typosquatting)
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
## Contributing
|
|
323
|
+
|
|
324
|
+
Contributions are welcome! Please open an issue or submit a pull request.
|
|
325
|
+
|
|
326
|
+
1. Fork the repository
|
|
327
|
+
2. Create your feature branch (`git checkout -b feature/my-feature`)
|
|
328
|
+
3. Run the test suite (`pytest tests/`)
|
|
329
|
+
4. Commit your changes (`git commit -am 'Add my feature'`)
|
|
330
|
+
5. Push to the branch (`git push origin feature/my-feature`)
|
|
331
|
+
6. Open a Pull Request
|
|
332
|
+
|
|
333
|
+
## License
|
|
334
|
+
|
|
335
|
+
MIT — see [LICENSE](LICENSE) for details.
|