Metadata-Version: 2.4
Name: slopguard-cli
Version: 0.3.0
Summary: Defend developers and AI coding agents against slopsquatting (hallucinated package names).
Project-URL: Homepage, https://github.com/hariomunknownslab/slopguard
Project-URL: Repository, https://github.com/hariomunknownslab/slopguard
Project-URL: Issues, https://github.com/hariomunknownslab/slopguard/issues
Author-email: SlopGuard <contact@unknownslab.com>
License: MIT
Keywords: ai,llm,package-hallucination,security,slopsquatting,supply-chain
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Security
Classifier: Topic :: Software Development :: Quality Assurance
Requires-Python: >=3.11
Requires-Dist: httpx>=0.27.0
Requires-Dist: pydantic>=2.6.0
Requires-Dist: pyyaml>=6.0.1
Requires-Dist: rich>=13.7.0
Requires-Dist: tomli>=2.0.1; python_version < '3.11'
Requires-Dist: typer>=0.12.0
Provides-Extra: dev
Requires-Dist: build>=1.2.0; extra == 'dev'
Requires-Dist: jsonschema>=4.21.0; extra == 'dev'
Requires-Dist: mypy>=1.10.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
Requires-Dist: pytest-cov>=4.1.0; extra == 'dev'
Requires-Dist: pytest>=8.0.0; extra == 'dev'
Requires-Dist: respx>=0.21.0; extra == 'dev'
Requires-Dist: ruff>=0.4.0; extra == 'dev'
Requires-Dist: types-pyyaml>=6.0.12; extra == 'dev'
Description-Content-Type: text/markdown

# SlopGuard

[![CI](https://github.com/hariomunknownslab/slopguard/actions/workflows/ci.yml/badge.svg)](https://github.com/hariomunknownslab/slopguard/actions/workflows/ci.yml)
[![PyPI](https://img.shields.io/pypi/v/slopguard-cli.svg)](https://pypi.org/project/slopguard-cli/)
[![Python](https://img.shields.io/pypi/pyversions/slopguard-cli.svg)](https://pypi.org/project/slopguard-cli/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

**Slopsquatting** is what happens when an LLM hallucinates a plausible-sounding
package name that does not exist on the public registry — and then an attacker
registers that exact name with malware so the *next* developer (or AI agent)
who follows the suggestion installs it. SlopGuard scans your project's
dependencies, flags entries that are either known LLM hallucinations or that
show the behavioural fingerprint of a slopsquat, and exits non-zero so CI
fails the build before the malware reaches `node_modules` or `site-packages`.

> SlopGuard stops AI coding agents from installing packages that LLMs hallucinated.

## Install

```bash
pip install slopguard-cli
# Homebrew formula ships in a later release:
# brew install slopguard
```

> The PyPI **distribution** name is `slopguard-cli` (the name `slopguard`
> overlapped with an unrelated existing package on PyPI). The installed
> command, the Python import, and everything else stays `slopguard`.

Python 3.11+ is required.

## Usage

### 1. Scan the current directory

```bash
slopguard scan
```

SlopGuard auto-discovers `package.json`, `package-lock.json`,
`requirements.txt`, `pyproject.toml`, and `Pipfile` (up to two levels deep),
probes each name against the public registry, and prints a Rich table:

```text
SlopGuard v0.1.0 — scanning /home/dev/myproj

Detected manifests:
  • package.json (npm, 32 deps)
  • requirements.txt (pypi, 15 deps)

Scanned 47 dependencies in 3.1s.

┏━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Package            ┃ Risk       ┃ Reason                                       ┃
┡━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ react-codeshift    │ HALLUCIN.  │ Matched seed DB entry; recurrence 0.71.      │
│ langchain-helpers  │ SUSPICIOUS │ Created 14 days ago, 48 downloads, new auth. │
│ openai-utils       │ SUSPICIOUS │ Levenshtein 2 from popular package 'openai'. │
│ requests           │ CLEAN      │ Established package.                         │
└────────────────────┴────────────┴──────────────────────────────────────────────┘

Summary: 1 hallucinated, 2 suspicious, 44 clean, 0 error(s).
Exit code: 1
```

### 2. Scan a specific path

```bash
slopguard scan ./mono/services/api
```

### 3. CI mode — JSON output, strict failure threshold

```bash
slopguard scan --format json --output report.json --fail-on hallucinated
```

See [`.github/workflows/slopguard.yml.example`](.github/workflows/slopguard.yml.example)
for a drop-in GitHub Actions workflow and [`docs/ci-integration.md`](docs/ci-integration.md)
for details on other CI providers.

## How it works

For every dependency, SlopGuard computes a small set of independent signals
and combines them into a single risk score in `[0.0, 1.0]`:

- **Hallucination-DB hit** (weight 0.90) — exact match in an embedded seed
  database of names known to be hallucinated by major LLMs.
- **Registry not found** (0.85) — the registry returns 404 for the name. The
  most common slopsquat shape: a name that doesn't exist *yet*.
- **Very recently / recently published** (0.35 / 0.20) — first release < 7
  days / < 30 days old.
- **Low downloads** (0.15) — < 100 downloads in the last month (npm) or last
  week (PyPI).
- **New publisher** (0.20) and **single-release new account** (0.30) — a
  brand-new account whose only release is the package you're about to install.
- **Levenshtein typo** (0.25) — name is 1–2 edits away from a top-1000
  popular package (likely a typosquat).
- **Suspicious name pattern** (0.10) — matches a classic LLM-hallucination
  shape like `<stem>-helpers`, `<stem>-utils`, `<stem>-async`, `<stem>-pro`.

The default cutoffs map scores `≥ 0.85` → **hallucinated**, `≥ 0.40` →
**suspicious**, else **clean**. Both thresholds are tunable in
`.slopguard.yaml`. See [`docs/detection.md`](docs/detection.md) for the full
table, the order of operations, and edge cases.

## Configuration

`.slopguard.yaml`, picked up automatically from the scan target or any
ancestor (up to 3 levels):

```yaml
ignore:
  packages: ["internal-tool"]
  patterns: ["^@mycompany/"]

fail_on: suspicious        # any | hallucinated | suspicious | none

network:
  enabled: true
  timeout_seconds: 5
  concurrency: 16

scoring:
  suspicious_min_score: 0.4
  hallucinated_min_score: 0.85
```

CLI flags override the file. See [`docs/usage.md`](docs/usage.md) for the full
reference.

## What it does NOT do

- No dashboard, no auth, no accounts, no billing, no telemetry. The
  CLI is fully offline-capable; `slopguard update` is the only
  outbound call beyond the npm + PyPI registry probes, and it just
  fetches a static JSON file from GitHub Pages.
- No defensive package registration / tarpit.
- No Cursor / Claude Code / Copilot IDE plugins.
- No support for crates.io, pkg.go.dev, Maven Central, RubyGems, NuGet —
  Python and JavaScript only.
- No license scanning, no CVE matching, no SBOM generation.

Everything is MIT, free forever. Fork it.

## Privacy & trust

SlopGuard makes **only** the network calls you opt into (the public registry
probes against `registry.npmjs.org` and `pypi.org`). No analytics, no
ping-home, no telemetry. The trust model is the moat: run `--no-network` if
you want to be sure.

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md). PRs welcome — especially curated
additions to the hallucination database.

## License

MIT. Copyright © 2026 SlopGuard. See [LICENSE](LICENSE).
