# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Commands **Run tests:** ```bash pytest tests/ pytest tests/unit/test_inf_parser.py # single test file pytest tests/ -k "test_name" # single test by name ``` **Run dev server:** ```bash export DATA_DIR=/tmp/imptune_data uvicorn imptune.main:app --reload --port 8000 ``` **Docker:** ```bash docker-compose up docker build -t imptune . ``` **Install deps:** ```bash pip install -r requirements.txt -r requirements-dev.txt ``` ## Architecture ImpTune generates printer deployment packages (`.intunewin` for Microsoft Intune, `.zip` for NinjaRMM) from Windows driver ZIPs and a web UI form. No external services — single FastAPI app + SQLite + Docker volume. **Request flow:** 1. Driver upload → `api/drivers.py` → `services/inf_parser.py` parses INF → `storage/driver_store.py` stores by SHA256 → Peewee `Driver` record 2. Printer config → `api/printers.py` → `db/models.py` `Printer` record (links Driver FK) 3. Icon upload → `api/icons.py` → Pillow validates PNG 256×256 → SHA256 storage → `Icon` record 4. Package export → `api/packages.py` → `generators/script_generator.py` renders Jinja2 PS1 templates → `generators/intunewin_builder.py` encrypts ZIP (AES-256-CBC + HMAC-SHA256) **Key modules:** - `imptune/config.py` — `DATA_DIR`, `DB_PATH`, `DRIVERS_DIR`, `ICONS_DIR` from env - `imptune/db/database.py` — SQLite WAL mode + `foreign_keys=1`; all models inherit `BaseModel` - `imptune/services/inf_parser.py` — auto-detects encoding (UTF-16/UTF-8/cp1252), resolves `%TOKEN%` from `[Strings]`, handles multi-model INFs - `imptune/generators/intunewin_builder.py` — Python-native `.intunewin` (ZIP-in-ZIP); IV is 16 bytes (not 32); matches reference tool `1.8.6.0` output - `imptune/templates/scripts/` — Jinja2 templates for `install.ps1`, `uninstall.ps1`, `detect.ps1` **UI stack:** Pico CSS + HTMX 2 + Alpine.js 3 + Jinja2 server-side templates. **HTMX pattern:** Forms `hx-post` and swap `#driver-list` / `#printer-list` / `#client-list` targets. Error responses return inline HTML fragments (HTTP 400/409) via `_error_response()`. Success returns rendered partials from `templates/partials/`. **PowerShell install script notes:** - WOW64 64-bit relaunch guard (Intune runs 32-bit, `pnputil` needs 64-bit) - UAC self-elevation for user context (SYSTEM context skips) - Two-step: `pnputil /add-driver` then `Add-PrinterDriver` + `Add-PrinterPort` + `Add-Printer` - All idempotent (`-ErrorAction SilentlyContinue`) ## Test Setup `conftest.py` monkeypatches `config.DATA_DIR` and `config.DB_PATH` to a temp dir per test. `client` fixture yields `TestClient(app)` with isolated SQLite. E2E tests in `tests/e2e/` use Playwright. ## Environment Variables | Var | Default | Purpose | |-----|---------|---------| | `DATA_DIR` | `/data` | Storage root (DB + drivers + icons) | | `PORT` | `8000` | Server port |