diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..cd703b3 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,113 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +EMLy is a Windows desktop email viewer for `.eml` and `.msg` files built with Wails v2 (Go backend + SvelteKit/Svelte 5 frontend). It supports viewing email content, attachments, and Italian PEC (Posta Elettronica Certificata) certified emails. + +## Build Commands + +```bash +# Development mode with hot-reload +wails dev + +# Production build (outputs to build/bin/EMLy.exe) +wails build + +# Build for specific platform +wails build -platform windows/amd64 + +# Frontend type checking +cd frontend && bun run check + +# Go tests +go test ./... + +# Install frontend dependencies (also runs automatically on build) +cd frontend && bun install +``` + +## Architecture + +### Wails Framework +- Go backend methods are automatically exposed to frontend via generated TypeScript bindings +- Bindings are generated in `frontend/src/lib/wailsjs/go/main/App.ts` +- All App methods with exported names become callable from TypeScript +- Wails runtime provides window control, dialogs, and event system + +### Backend Structure (Go) + +The `App` struct is the main controller, split across files by domain: + +| File | Responsibility | +|------|----------------| +| `app.go` | Core struct, lifecycle (startup/shutdown), configuration | +| `app_mail.go` | Email reading: ReadEML, ReadMSG, ReadPEC, ShowOpenFileDialog | +| `app_viewer.go` | Viewer windows: OpenImageWindow, OpenPDFWindow, OpenEMLWindow | +| `app_screenshot.go` | Window capture using Windows GDI APIs | +| `app_bugreport.go` | Bug report creation with screenshots and system info | +| `app_settings.go` | Settings import/export to JSON | +| `app_system.go` | Windows registry, encoding conversion, file explorer | + +Email parsing lives in `backend/utils/mail/`: +- `eml_reader.go` - Standard EML parsing +- `msg_reader.go` - Microsoft MSG (CFB format) parsing +- `mailparser.go` - MIME multipart handling + +### Frontend Structure (SvelteKit + Svelte 5) + +**Routes** (file-based routing): +- `(app)/` - Main app with sidebar layout, titlebar, footer +- `(app)/settings/` - Settings page +- `image/` - Standalone image viewer (launched with `--view-image=`) +- `pdf/` - Standalone PDF viewer (launched with `--view-pdf=`) + +**Key patterns**: +- Svelte 5 runes: `$state`, `$effect`, `$derived`, `$props` (NOT legacy stores in components) +- State classes in `stores/*.svelte.ts` using `$state` for reactive properties +- Traditional Svelte stores in `stores/app.ts` for simple global state +- shadcn-svelte components in `lib/components/ui/` + +**Mail utilities** (`lib/utils/mail/`): +- Modular utilities for email loading, attachment handling, data conversion +- Barrel exported from `index.ts` + +### Multi-Window Support + +The app spawns separate viewer processes: +- Main app uses single-instance lock with ID `emly-app-lock` +- Image/PDF viewers get unique IDs per file, allowing multiple concurrent viewers +- CLI args: `--view-image=` or `--view-pdf=` trigger viewer mode + +### Internationalization + +Uses ParaglideJS with compile-time type-safe translations: +- Translation files: `frontend/messages/en.json`, `it.json` +- Import: `import * as m from "$lib/paraglide/messages"` +- Usage: `{m.mail_open_btn_text()}` + +## Key Patterns + +### Calling Go from Frontend +```typescript +import { ReadEML, ShowOpenFileDialog } from "$lib/wailsjs/go/main/App"; +const filePath = await ShowOpenFileDialog(); +const email = await ReadEML(filePath); +``` + +### Event Communication +```typescript +import { EventsOn } from "$lib/wailsjs/runtime/runtime"; +EventsOn("launchArgs", (args: string[]) => { /* handle file from second instance */ }); +``` + +### Email Body Rendering +Email bodies render in sandboxed iframes with links disabled for security. + +## Important Conventions + +- Windows-only: Uses Windows APIs (registry, GDI, user32.dll) +- Bun package manager for frontend (not npm/yarn) +- Frontend assets embedded in binary via `//go:embed all:frontend/build` +- Custom frameless window with manual titlebar implementation