# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

USB/IP Supervisor is a Linux-only system service for automatic USB device management over networks using USB/IP protocol. It consists of server and client components that manage device binding, attachment, hot-plugging, and network recovery.

## Runtime & Commands

This project uses **Bun** as the runtime (not Node.js).

### Development Commands
```bash
bun run dev              # Run the CLI locally
bun test                 # Run all tests
bun test --integration   # Run integration tests only
bun run lint             # Lint with Biome
bun run lint:fix         # Auto-fix linting issues
bun run format           # Format code with Biome
bun run typecheck        # Type check without emit
```

### Running the Application
```bash
# Server
bunx @siwats/usbip-supervisor server [--config path] [--configure] [--install-systemd]

# Client
bunx @siwats/usbip-supervisor client [--config path] [--configure] [--install-systemd]
```

## Architecture

### Core Components

**Server Side** (`src/server/`):
- `index.ts` - Entry point that orchestrates server startup, loads config, verifies system requirements
- `device-manager.ts` - Monitors USB devices via udev, handles bind/unbind operations
- `connection-manager.ts` - Manages TCP client connections, enforces access control, routes messages

**Client Side** (`src/client/`):
- `index.ts` - Entry point that loads config and initializes client components
- `connection-handler.ts` - Manages TCP connections to multiple servers with automatic reconnection
- `device-manager.ts` - Handles device attach/detach operations and periodic health checks

**Protocol** (`src/protocol/`):
- `types.ts` - Defines all message types for client-server communication (JSON over TCP with length prefix)
- `socket.ts` - TCP socket wrapper handling message framing and connection lifecycle

**Configuration** (`src/config/`):
- `schema.ts` - Zod schemas for server/client configuration validation
- `manager.ts` - Loads and validates YAML config files from `~/.config/usbip-supervisor/`
- `wizard-*.ts` - Interactive TUI configuration wizards using Ink (React for CLI)

**USB/IP Integration** (`src/usbip/`):
- `commands.ts` - Wraps `usbip` CLI commands (bind, attach, list, modprobe, usbipd daemon)
- `device.ts` - Discovers USB devices via sysfs and udev, resolves by-path identifiers

**System Integration**:
- `src/udev/` - udev rules and monitoring for hot-plug detection
- `src/systemd/` - systemd service templates and installation
- `src/system/permissions.ts` - Checks for root access and system requirements

### Device Identification

Devices are identified by **USB by-path** (e.g., `pci-0000:00:14.0-usb-0:1:1.0`) which uniquely identifies physical USB ports. This is more reliable than vendor/product IDs and allows distinguishing multiple identical devices. The system uses sysfs and udev to discover and monitor devices.

### Communication Flow

1. **Server**: Monitors configured USB devices → Binds when detected → Starts usbipd daemon → Accepts TCP connections → Sends DEVICE_BIND messages to authorized clients
2. **Client**: Connects to server(s) → Receives DEVICE_BIND messages → Attaches devices via usbip → Monitors health → Auto-reconnects on failures
3. **Protocol**: Length-prefixed JSON messages, heartbeat mechanism, exponential backoff reconnection

### State Management

- **Server device states**: DISCONNECTED → CONNECTED → BOUND
- **Client device states**: DISCONNECTED → ATTACHED
- **Connection states**: DISCONNECTED → CONNECTING → CONNECTED → ERROR (with retry)
- Periodic health checks verify state consistency and trigger recovery

## Key Patterns

### Error Handling
- All async operations use try-catch with detailed logging via `src/utils/logger.ts`
- System requirement failures (missing usbip, kernel modules) cause graceful exit with clear error messages
- Network/device failures trigger automatic retry with exponential backoff

### Process Execution
- Use `Bun.$` for shell commands (already imported in usbip/commands.ts)
- Commands like `usbip`, `modprobe`, `udevadm` require root privileges
- Always check exit codes and parse stdout/stderr

### Configuration
- YAML configs in `~/.config/usbip-supervisor/{server,client}.yaml`
- Validated with Zod schemas - always maintain schema-config sync
- Interactive wizards (Ink/React) for user-friendly setup

### Testing
- Use `bun test` framework (not Jest/Vitest)
- Integration tests require root and physical USB devices - tag with `--integration`
- Mock `usbip` commands for unit tests

## Important Constraints

1. **Linux-only**: Depends on Linux kernel modules (vhci-hcd, usbip-core), sysfs, udev
2. **Root required**: Most operations need root for usbip, modprobe, udev rules
3. **systemd integration**: Services run as root, use full paths (`/usr/bin/bunx`)
4. **USB by-path**: Never use vendor/product ID as primary identifier - always use by-path

## Code Style

- Use Biome (not ESLint/Prettier): `bun run lint:fix` and `bun run format`
- TypeScript strict mode enabled
- Import paths use `.js` extension (TypeScript convention)
- Prefer `Bun.$` over child_process/execa
- Use `logger` utility instead of console.log
