6.4 KiB
6.4 KiB
CLAUDE.md — Torrent Faker
Project Purpose
Torrent Faker is a fake BitTorrent seeder that announces upload stats to real trackers without transferring any actual data. It simulates realistic seeding behavior to satisfy tracker requirements.
Tech Stack
| Layer | Technology |
|---|---|
| Runtime | Bun |
| Language | TypeScript (strict, ESNext) |
| HTTP | Hono 4.x |
| Config | YAML (js-yaml) + Zod validation |
| Linting | Biome |
| Frontend | Svelte 5 + Vite (in ui/) |
Project Structure
src/
index.ts # Entry point: loads config, starts registry + HTTP server
cli/index.ts # CLI client (talks to running API)
config/Config.ts # Zod schema + config loader
config/config.default.yml # Default config values
api/
server.ts # Hono app, mounts routes, serves UI
SeederRegistry.ts # Central in-memory store for all FakeSeeder instances
response.ts # HTTP response helpers
routes/
torrents.ts # GET/POST/DELETE /api/torrents
status.ts # GET /api/status, GET /api/status/stream (SSE)
config.ts # GET/PATCH /api/config
core/
bencode/ # Bencode decoder + encoder
client/
ClientProfile.ts # Profile interface + peer ID generation
profiles/ # qbittorrent.ts, transmission.ts
seeder/
FakeSeeder.ts # Announce loop, lifecycle (started → running → stopped)
SpeedSimulator.ts # Gaussian noise + burst/stall events
torrent/TorrentFile.ts # Parses .torrent, extracts info hash + tracker list
tracker/
ITracker.ts # Tracker interface
HttpTracker.ts # HTTP/HTTPS tracker (BEP 3)
UdpTracker.ts # UDP tracker (BEP 15)
TrackerResponse.ts # Response types
config/config.yml # Runtime config (gitignored defaults)
torrents/ # Drop .torrent files here
ui/ # Svelte frontend (built to ui/dist/)
TypeScript Path Aliases
@core/* → src/core/*
@api/* → src/api/*
@config/* → src/config/*
Dev Commands
bun run dev # Start server (hot-reload)
bun run start # Start server (production)
bun run cli <cmd> # Run CLI against running server
bun test # Run tests
bun run lint # Biome check
bun run format # Biome format --write
bun run build:ui # Build Svelte UI to ui/dist/
bun run build # Full build (UI only for now)
Architecture
SeederRegistry
└── FakeSeeder (one per torrent)
├── SpeedSimulator — random base rate, ±15% jitter, burst/stall
└── Tracker[]
├── HttpTracker (BEP 3)
└── UdpTracker (BEP 15)
SeederRegistryis the single source of truth; routes call it, not FakeSeeder directly.FakeSeederextendsEventEmitter; emitsannounce,stopped,stateChange.SeederRegistrysubscribes to seeder events and pushes SSE updates to connected clients.- Announce lifecycle: first call sends
event=started, subsequent calls sendevent=(empty), final call on removal sendsevent=stopped.
Configuration
Runtime config file: config/config.yml (copied from src/config/config.default.yml).
| Field | Default | Description |
|---|---|---|
port |
3000 | HTTP server port (UI + API) |
announcePort |
6881 | Port reported to trackers |
minUploadRateBytesPerSec |
524288 | Min simulated speed (512 KB/s) |
maxUploadRateBytesPerSec |
2097152 | Max simulated speed (2 MB/s) |
clientProfile |
qbittorrent | Client to impersonate |
torrentsDir |
./torrents | Directory for .torrent files |
autoLoad |
true | Load all torrents in dir on startup |
Config is Zod-validated at startup. PATCH /api/config persists changes back to config.yml.
API Endpoints
| Method | Path | Description |
|---|---|---|
| GET | /api/torrents |
List all active torrents |
| POST | /api/torrents |
Upload .torrent file (multipart) |
| GET | /api/torrents/:hash |
Stats + announce history for one |
| DELETE | /api/torrents/:hash |
Stop seeding and remove |
| GET | /api/status |
Global stats snapshot |
| GET | /api/status/stream |
SSE stream (stats, torrent, ping) |
| GET | /api/config |
Current config |
| PATCH | /api/config |
Update mutable config fields |
| GET | /* |
Serve Svelte SPA from ui/dist/ |
SSE Event Types
stats— global stats on every changetorrent— per-torrent state update on announce/changetorrents— full list on initial connectionping— keep-alive every 30s
CLI
Requires a running server. Reads TORRENT_FAKER_API env var (default: http://localhost:3000).
bun run cli add <file.torrent> # Start fake-seeding
bun run cli list # List active torrents
bun run cli remove <hash> # Stop and remove (hash prefix OK)
bun run cli status # Global stats
Client Profiles
| Profile | Peer ID prefix | User-Agent |
|---|---|---|
qbittorrent |
-qB4520- |
qBittorrent/4.5.2 |
transmission |
-TR3000- |
Transmission/3.00 |
Each seeder generates a unique 20-byte peer ID per session.
Code Conventions
- Biome enforces formatting; run
bun run formatbefore committing. - Zod schemas for all external input (config file, API request bodies).
- No ORM — binary protocols implemented manually (bencode, UDP packets).
- EventEmitter pattern for seeder → registry communication.
- SSE for live UI updates (no WebSockets, no polling).