npmdiffwatch/ # Core package
__init__.py
__main__.py # CLI entry point
config.py # Config dataclasses + TOML loader
models.py # Data models (NewRelease, ArtifactSet, Diff, Verdict, etc.)
backends.py # LLM backends (OpenAI-compatible + Anthropic)
egress.py # Default-deny egress guard (socket.getaddrinfo wrapper)
notifier.py # Alert emitter (stdout + webhook)
store.py # SQLite store (cursor, releases, verdicts, alerts)
quarantine.py # Static denylist for confirmed malicious npm packages
deps.py # Dependency reputation gate (typosquat detection)
ingest.py # npm registry search API + packument poller
fetcher.py # npm .tgz download + in-memory extraction + baseline resolution
differ.py # Version-to-version diff (difflib + JSON-aware for package.json)
facts.py # JS/TS AST analysis via tree-sitter
rules.py # YAML rule loader (fail-closed validator + safe matcher)
engine.py # Rules engine triage (facts x rules)
reviewer.py # LLM reviewer prompt builder + verdict parser
orchestrator.py # Pipeline coordinator (run_once, seed, adjudicate, etc.)
dashboard.py # Static HTML verdict dashboard (npm links + report-malware actions)
data/
top_npm_names.txt # Vendored top npm names for typosquat corpus
rules/community/ # Shipped YAML detection rules
code.yaml # JS/TS code-level rules
package_json.yaml # package.json field change rules
deps.yaml # Dependency reputation rules
lockfile.yaml # Lockfile integrity rules
maintainer.yaml # Maintainer set change rules
binaries.yaml # Binary foreign-language rules
examples/ # Example config files
local-qwen.toml
ollama.toml
llamacpp.toml
openai.toml
anthropic.toml
npm registry search → ingest() → [NewRelease]
→ fetcher() → ArtifactSet (new + prior .tgz files in memory)
→ differ() → Diff (FileDiff[] + package.json changes + lockfile meta)
→ engine.triage() → TriageResult (score + FiredRule[])
→ [if escalate] reviewer.review() → Verdict (LLM classification)
→ notifier + store → alerts + SQLite