update CLAUDE.md, README.md and justfile
This commit is contained in:
@@ -1,191 +1,32 @@
|
||||
# CLAUDE.md
|
||||
# lanspread
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
Peer-to-peer game library sharing for LAN parties. Peers discover each other on the local network via mDNS, exchange library metadata over QUIC, and let users browse and download games from each other. Ships as a Tauri desktop app.
|
||||
|
||||
## Project Overview
|
||||
## Workspace layout
|
||||
|
||||
**LanSpread2** is a peer-to-peer (P2P) game distribution system with a Tauri desktop application frontend. It enables users to share games over local networks using mDNS discovery and QUIC protocol for peer communication.
|
||||
Cargo workspace under `crates/`:
|
||||
|
||||
## Common Development Commands
|
||||
- `lanspread-peer` — core peer: networking, library, downloads, services. Start here for behavior changes. See `crates/lanspread-peer/ARCHITECTURE.md`.
|
||||
- `lanspread-proto` — wire protocol types shared across peers.
|
||||
- `lanspread-mdns` — mDNS-SD discovery wrapper.
|
||||
- `lanspread-db` — database/schema types (sqlx + sqlite).
|
||||
- `lanspread-compat` — compatibility/migration glue between db and other crates.
|
||||
- `lanspread-utils` — small shared helpers.
|
||||
- `lanspread-tauri-deno-ts/` — frontend (Vite + Deno + TS in `src/`) and Tauri shell (`src-tauri/`). This is the GUI client.
|
||||
|
||||
### Build
|
||||
Top-level `Cargo.toml` pins workspace dependency versions; per-crate `Cargo.toml`s set lints (pedantic clippy, `unsafe_code = forbid` on most).
|
||||
|
||||
```bash
|
||||
# Development (opens UI, needs user interaction)
|
||||
cargo tauri dev
|
||||
## Commands (justfile)
|
||||
|
||||
# Debug build for very quick testing (without bundle)
|
||||
cargo tauri build --debug --no-bundle
|
||||
Never use normal cargo ... commands, use the just ... commands instead.
|
||||
|
||||
# Release build for testing (without bundling)
|
||||
cargo tauri build --no-bundle
|
||||
- `just run` — run the GUI in dev mode.
|
||||
- `just build` — build the GUI without bundling (also dev mode).
|
||||
- `just fmt` — format the workspace.
|
||||
- `just clippy` — lint the workspace.
|
||||
- `just fix` — auto-apply cargo/clippy fixes, then format.
|
||||
- `just clean` — wipe the build cache.
|
||||
|
||||
# Production (with bundling)
|
||||
cargo tauri build -- --profile release-lto
|
||||
```
|
||||
## General info
|
||||
|
||||
### Build Profiles
|
||||
|
||||
- `release`: Default release profile with debug info, assertions enabled, overflow checks on, for testing
|
||||
- `release-lto`: Optimized for distribution with LTO enabled, debug symbols stripped, smaller binary, only for production
|
||||
|
||||
### Code Quality
|
||||
|
||||
```bash
|
||||
# Lint all code
|
||||
cargo clippy
|
||||
|
||||
# Format code (nightly Rust)
|
||||
cargo +nightly fmt
|
||||
```
|
||||
|
||||
### Testing
|
||||
|
||||
```bash
|
||||
# Run all tests
|
||||
cargo test --workspace
|
||||
|
||||
# Run tests for a specific crate
|
||||
cargo test -p lanspread-peer
|
||||
|
||||
# Run a specific test
|
||||
cargo test -p lanspread-peer test_name
|
||||
|
||||
# Run tests with output
|
||||
cargo test -- --nocapture
|
||||
```
|
||||
|
||||
### Dependencies
|
||||
|
||||
```bash
|
||||
# Update frontend dependencies (Deno)
|
||||
deno outdated --update --latest
|
||||
```
|
||||
|
||||
### Wayland Users
|
||||
|
||||
```bash
|
||||
# Set this environment variable if running on Wayland
|
||||
WEBKIT_DISABLE_DMABUF_RENDERER=1
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
LanSpread follows a layered, modular architecture with clear separation of concerns:
|
||||
|
||||
### Crate Structure
|
||||
|
||||
The project is organized as a Cargo workspace with 7 crates:
|
||||
|
||||
**Foundation Layer:**
|
||||
|
||||
- **lanspread-utils**: Utility macros and helpers used across all crates
|
||||
- **lanspread-db**: Core data structures (`Game`, `GameFileDescription`, game metadata)
|
||||
|
||||
**Protocol & Communication:**
|
||||
|
||||
- **lanspread-proto**: P2P communication protocol definitions
|
||||
- Message types: `Request` (Ping, ListGames, GetGame, etc.), `Response`, `Message` trait
|
||||
- Serialization: JSON with `serde`
|
||||
|
||||
**Network Discovery & Compatibility:**
|
||||
|
||||
- **lanspread-mdns**: mDNS service discovery and advertisement
|
||||
- Advertises and discovers "_lanspread._udp.local." services on LAN
|
||||
- Uses `mdns-sd` crate
|
||||
|
||||
- **lanspread-compat**: Compatibility layer for legacy ETI game database format
|
||||
- Reads legacy `game.db` SQLite databases
|
||||
- Converts `EtiGame` structs to modern `Game` struct
|
||||
|
||||
**Core P2P Engine:**
|
||||
|
||||
- **lanspread-peer**: Central orchestration for all P2P functionality
|
||||
- Entry point: `start_peer()` in `lib.rs`
|
||||
- Communicates via unbounded channels (`PeerEvent`, `PeerCommand`)
|
||||
- Key modules:
|
||||
- `services.rs`: Background tasks (server, discovery, ping, local game monitor)
|
||||
- `handlers.rs`: Command handlers for UI requests
|
||||
- `network.rs`: QUIC connection management with length-delimited frames
|
||||
- `download.rs`: Chunked file transfer logic
|
||||
- `peer_db.rs`: Peer tracking and game availability
|
||||
- `path_validation.rs`: Security for file operations
|
||||
|
||||
**Application Layer:**
|
||||
|
||||
- **lanspread-tauri-deno-ts**: Tauri desktop application
|
||||
- Binary + Library crate for the UI layer
|
||||
- IPC commands: `request_games`, `install_game`, etc.
|
||||
- Manages `LanSpreadState` for peer controller, game DB, and downloads
|
||||
- Uses Tauri plugins: logging, shell, dialogs, persistent storage
|
||||
- Allocates MiMalloc for memory efficiency
|
||||
|
||||
### Data Flow
|
||||
|
||||
```
|
||||
User (Tauri UI)
|
||||
↓ IPC Commands (request_games, install_game)
|
||||
↓
|
||||
lanspread-tauri-deno-ts (app layer)
|
||||
↓
|
||||
lanspread-peer (P2P engine)
|
||||
├─ lanspread-mdns (discovers peers via mDNS)
|
||||
├─ lanspread-proto (constructs P2P messages)
|
||||
├─ lanspread-compat (reads legacy game databases)
|
||||
└─ QUIC Network ↔ Other Peers
|
||||
↓
|
||||
lanspread-db (game data structures)
|
||||
↓
|
||||
Result → Back to UI
|
||||
```
|
||||
|
||||
### Key Architectural Details
|
||||
|
||||
1. **Async/Await**: Tokio runtime throughout for non-blocking I/O
|
||||
2. **Message Passing**: Unbounded channels for inter-component communication (events and commands)
|
||||
3. **Protocol**: Length-delimited QUIC frames with JSON serialization
|
||||
4. **Service Discovery**: Automatic mDNS announcement and discovery of peers
|
||||
5. **File Streaming**: Chunked transfer with path validation for security
|
||||
6. **Legacy Support**: Backwards compatibility with ETI game database format
|
||||
7. **Error Handling**: Custom error types via `eyre` crate
|
||||
|
||||
## Development Practices
|
||||
|
||||
### From AGENTS.md
|
||||
|
||||
- Always check code with `cargo clippy` and fix any issues
|
||||
- Always format with `cargo +nightly fmt` after completing changes
|
||||
- Use appropriate Rust log levels when debugging:
|
||||
- `RUST_LOG=lanspread=debug` for module-specific debugging
|
||||
- `RUST_LOG=info,lanspread=debug` for general info + module debug
|
||||
|
||||
### Performance Considerations
|
||||
|
||||
- Use `release-lto` profile for final builds to enable Link-Time Optimization
|
||||
- MiMalloc is used for the Tauri app to reduce memory overhead
|
||||
- QUIC protocol chosen for efficient P2P communication
|
||||
- Length-delimited framing reduces message parsing overhead
|
||||
|
||||
## Important Implementation Notes
|
||||
|
||||
### Logging
|
||||
|
||||
The codebase uses `tracing` and `log` crates. Note: There's documented uncertainty about their exact relationship (see LESSONS_LEARNED.md). The client app uses `log` crate; be consistent with whichever is used in the component you're modifying.
|
||||
|
||||
### Legacy Database Support
|
||||
|
||||
Some users may have old ETI format game databases. The `lanspread-compat` crate handles reading these. When querying games, both modern and legacy formats are considered.
|
||||
|
||||
### Path Validation
|
||||
|
||||
File transfers validate paths to prevent directory traversal attacks. All file operations use validated paths from `lanspread-peer`.
|
||||
|
||||
### Retry Logic
|
||||
|
||||
`lanspread-peer` includes retry logic for requesting games from peers. This handles transient network failures in P2P discovery.
|
||||
|
||||
## Known Design Decisions
|
||||
|
||||
**Why not Tauri + Leptos?** Leptos adds unnecessary complexity. Tauri is designed to transfer backend Rust to frontend JavaScript world, but with Leptos the frontend becomes Rust, creating a double translation. The current Tauri + Deno/TypeScript approach is cleaner.
|
||||
|
||||
**Why Tauri?** Simple setup, easy development with `cargo tauri dev`, easy testing and bundling with installers, small final binary (~13MB).
|
||||
See `README.md`.
|
||||
|
||||
Reference in New Issue
Block a user